blob: 0509344298179da06612bb71e67de1cbcd1c2157 [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2010, 2013 E.D.Willink and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* E.D.Willink - Initial API and implementation
*
* </copyright>
*
* $Id: BasePreOrderVisitor.java,v 1.13 2011/05/22 21:06:21 ewillink Exp $
*/
package org.eclipse.ocl.examples.xtext.base.cs2as;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.ocl.examples.domain.elements.DomainTypedElement;
import org.eclipse.ocl.examples.domain.types.AbstractTuplePart;
import org.eclipse.ocl.examples.domain.utilities.DomainUtil;
import org.eclipse.ocl.examples.pivot.AnyType;
import org.eclipse.ocl.examples.pivot.DataType;
import org.eclipse.ocl.examples.pivot.Element;
import org.eclipse.ocl.examples.pivot.LambdaType;
import org.eclipse.ocl.examples.pivot.NamedElement;
import org.eclipse.ocl.examples.pivot.Parameter;
import org.eclipse.ocl.examples.pivot.PivotPackage;
import org.eclipse.ocl.examples.pivot.Property;
import org.eclipse.ocl.examples.pivot.TupleType;
import org.eclipse.ocl.examples.pivot.Type;
import org.eclipse.ocl.examples.pivot.utilities.PivotUtil;
import org.eclipse.ocl.examples.xtext.base.basecs.AnnotationCS;
import org.eclipse.ocl.examples.xtext.base.basecs.ClassCS;
import org.eclipse.ocl.examples.xtext.base.basecs.ClassifierCS;
import org.eclipse.ocl.examples.xtext.base.basecs.ConstraintCS;
import org.eclipse.ocl.examples.xtext.base.basecs.DataTypeCS;
import org.eclipse.ocl.examples.xtext.base.basecs.DocumentationCS;
import org.eclipse.ocl.examples.xtext.base.basecs.EnumerationCS;
import org.eclipse.ocl.examples.xtext.base.basecs.EnumerationLiteralCS;
import org.eclipse.ocl.examples.xtext.base.basecs.LambdaTypeCS;
import org.eclipse.ocl.examples.xtext.base.basecs.ModelElementCS;
import org.eclipse.ocl.examples.xtext.base.basecs.ModelElementRefCS;
import org.eclipse.ocl.examples.xtext.base.basecs.MultiplicityBoundsCS;
import org.eclipse.ocl.examples.xtext.base.basecs.MultiplicityStringCS;
import org.eclipse.ocl.examples.xtext.base.basecs.OperationCS;
import org.eclipse.ocl.examples.xtext.base.basecs.PackageCS;
import org.eclipse.ocl.examples.xtext.base.basecs.ParameterCS;
import org.eclipse.ocl.examples.xtext.base.basecs.PathElementCS;
import org.eclipse.ocl.examples.xtext.base.basecs.PathNameCS;
import org.eclipse.ocl.examples.xtext.base.basecs.PrimitiveTypeRefCS;
import org.eclipse.ocl.examples.xtext.base.basecs.StructuralFeatureCS;
import org.eclipse.ocl.examples.xtext.base.basecs.TemplateBindingCS;
import org.eclipse.ocl.examples.xtext.base.basecs.TemplateParameterSubstitutionCS;
import org.eclipse.ocl.examples.xtext.base.basecs.TemplateSignatureCS;
import org.eclipse.ocl.examples.xtext.base.basecs.TuplePartCS;
import org.eclipse.ocl.examples.xtext.base.basecs.TupleTypeCS;
import org.eclipse.ocl.examples.xtext.base.basecs.TypeRefCS;
import org.eclipse.ocl.examples.xtext.base.basecs.TypedRefCS;
import org.eclipse.ocl.examples.xtext.base.basecs.TypedTypeRefCS;
import org.eclipse.ocl.examples.xtext.base.basecs.WildcardTypeRefCS;
import org.eclipse.ocl.examples.xtext.base.basecs.util.AbstractExtendingBaseCSVisitor;
import org.eclipse.ocl.examples.xtext.base.basecs.util.VisitableCS;
import org.eclipse.ocl.examples.xtext.base.utilities.ElementUtil;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
public class BaseCSPreOrderVisitor extends AbstractExtendingBaseCSVisitor<Continuation<?>, CS2PivotConversion>
{
@Inject
private ICS2ASFactory cs2asFactory;
protected static class ClassSupersContinuation extends SingleContinuation<ClassCS>
{
private static Dependency[] computeDependencies(@NonNull CS2PivotConversion context, @NonNull ClassCS csElement) {
List<TypedRefCS> csSuperTypes = csElement.getOwnedSuperType();
if (csSuperTypes.isEmpty()) {
return null;
}
List<Dependency> dependencies = new ArrayList<Dependency>();
for (TypedRefCS csSuperType : csSuperTypes) {
dependencies.add(new PivotDependency(csSuperType));
}
return dependencies.toArray(new Dependency[dependencies.size()]);
}
public ClassSupersContinuation(@NonNull CS2PivotConversion context, org.eclipse.ocl.examples.pivot.Class pivotParent, @NonNull ClassCS csElement) {
super(context, pivotParent, null, csElement, computeDependencies(context, csElement));
}
@Override
public BasicContinuation<?> execute() {
org.eclipse.ocl.examples.pivot.Class pivotElement = PivotUtil.getPivot(org.eclipse.ocl.examples.pivot.Class.class, csElement);
if (pivotElement != null) {
List<Type> superClasses = pivotElement.getSuperClass();
context.refreshList(Type.class, superClasses, csElement.getOwnedSuperType());
if (superClasses.isEmpty()) {
org.eclipse.ocl.examples.pivot.Class oclElementType = context.getMetaModelManager().getOclElementType();
pivotElement.getSuperClass().add(oclElementType);
}
}
return null;
}
}
protected static class LambdaContinuation extends SingleContinuation<LambdaTypeCS>
{
private static Dependency[] computeDependencies(@NonNull CS2PivotConversion context, @NonNull LambdaTypeCS csElement) {
TypedRefCS ownedContextType = DomainUtil.nonNullState(csElement.getOwnedContextType());
TypedRefCS ownedResultType = DomainUtil.nonNullState(csElement.getOwnedResultType());
List<TypedRefCS> csParameterTypes = csElement.getOwnedParameterType();
int iMax = csParameterTypes.size();
Dependency[] dependencies = new Dependency[2 + iMax];
dependencies[0] = context.createTypeIsReferenceableDependency(ownedContextType);
dependencies[1] = context.createTypeIsReferenceableDependency(ownedResultType);
for (int i = 0; i < iMax; i++) {
TypedRefCS csParameterType = DomainUtil.nonNullState(csParameterTypes.get(i));
dependencies[i+2] = context.createTypeIsReferenceableDependency(csParameterType);
}
return dependencies;
}
public LambdaContinuation(@NonNull CS2PivotConversion context, @NonNull LambdaTypeCS csElement) {
super(context, null, null, csElement, computeDependencies(context, csElement));
}
@Override
public BasicContinuation<?> execute() {
Type contextType = PivotUtil.getPivot(Type.class, csElement.getOwnedContextType());
Type resultType = PivotUtil.getPivot(Type.class, csElement.getOwnedResultType());
String name = csElement.getName();
if ((contextType != null) && (resultType != null) && (name != null)) {
List<Type> parameterTypes = new ArrayList<Type>();
for (TypedRefCS csParameterType : csElement.getOwnedParameterType()) {
Type parameterType = PivotUtil.getPivot(Type.class, csParameterType);
parameterTypes.add(parameterType);
}
LambdaType lambdaType = context.getMetaModelManager().getLambdaType(name, contextType, parameterTypes, resultType, null);
context.installPivotTypeWithMultiplicity(lambdaType, csElement);
}
return null;
}
}
protected static class ParameterContinuation extends SingleContinuation<ParameterCS>
{
public ParameterContinuation(@NonNull CS2PivotConversion context, @NonNull ParameterCS csElement) {
super(context, null, null, csElement);
}
@Override
public boolean canExecute() {
if (!super.canExecute()) {
return false;
}
TypedRefCS ownedType = csElement.getOwnedType();
Element pivot = ownedType != null ? ownedType.getPivot() : null;
if (pivot == null) {
return false;
}
return true;
}
@Override
public BasicContinuation<?> execute() {
Parameter parameter = PivotUtil.getPivot(Parameter.class, csElement);
if (parameter != null) {
context.refreshRequiredType(parameter, csElement);
}
return null;
}
}
protected static class PrimitiveTypeRefContinuation extends TypedRefContinuation<PrimitiveTypeRefCS>
{
public PrimitiveTypeRefContinuation(@NonNull CS2PivotConversion context, @NonNull PrimitiveTypeRefCS csElement) {
super(context, csElement);
}
@Override
public BasicContinuation<?> execute() {
String name = csElement.getName();
if (name != null) {
Type pivotType = context.getMetaModelManager().getLibraryType(name);
if (pivotType != null) {
context.installPivotTypeWithMultiplicity(pivotType, csElement);
}
}
return null;
}
}
protected static class SpecializedTypeRefContinuation1 extends SingleContinuation<TypedTypeRefCS>
{
public SpecializedTypeRefContinuation1(@NonNull CS2PivotConversion context, @NonNull TypedTypeRefCS csElement) {
super(context, null, null, csElement, context.getTypesHaveSignaturesInterDependency());
assert csElement.getOwnedTemplateBinding() != null;
}
@Override
public BasicContinuation<?> execute() {
@SuppressWarnings("unused")
Element pivotType = csElement.getType();
return new SpecializedTypeRefContinuation2(context, csElement);
}
}
protected static class SpecializedTypeRefContinuation2 extends TypedRefContinuation<TypedTypeRefCS>
{
private static Dependency[] computeDependencies(@NonNull CS2PivotConversion context, @NonNull TypedTypeRefCS csElement) {
List<Dependency> dependencies = new ArrayList<Dependency>();
TemplateBindingCS csTemplateBinding = csElement.getOwnedTemplateBinding();
if (csTemplateBinding != null) {
for (TemplateParameterSubstitutionCS csTemplateParameterSubstitution : csTemplateBinding.getOwnedParameterSubstitution()) {
TypeRefCS csTemplateParameter = csTemplateParameterSubstitution.getOwnedActualParameter();
if (csTemplateParameter != null) {
Dependency dependency = context.createTypeIsReferenceableDependency(csTemplateParameter);
if (dependency != null) {
dependencies.add(dependency);
}
}
}
for (TemplateParameterSubstitutionCS csTemplateParameterSubstitution : csTemplateBinding.getOwnedParameterSubstitution()) {
TypeRefCS csActualParameter = csTemplateParameterSubstitution.getOwnedActualParameter();
dependencies.add(new PivotDependency(csActualParameter)); // FIXME may be a redundant duplicate
}
}
dependencies.add(new PivotHasSuperClassesDependency(csElement));
return dependencies.toArray(new Dependency[dependencies.size()]);
}
public SpecializedTypeRefContinuation2(@NonNull CS2PivotConversion context, @NonNull TypedTypeRefCS csElement) {
super(context, csElement, computeDependencies(context, csElement));
assert csElement.getOwnedTemplateBinding() != null;
}
@Override
public boolean canExecute() {
if (!super.canExecute()) {
return false;
}
if (context.isInReturnTypeWithUnresolvedParameters(csElement)) {
return false;
}
Type pivotType = csElement.getType();
if (pivotType != null) {
if (pivotType.getSuperClass().size() <= 0) {
return false;
}
TemplateBindingCS csTemplateBinding = csElement.getOwnedTemplateBinding();
if (csTemplateBinding != null) {
for (TemplateParameterSubstitutionCS csTemplateParameterSubstitution : csTemplateBinding.getOwnedParameterSubstitution()) {
TypeRefCS ownedActualParameter = csTemplateParameterSubstitution.getOwnedActualParameter();
if (ownedActualParameter instanceof WildcardTypeRefCS) {
return true;
}
Type actualParameterClass = (Type) ownedActualParameter.getPivot();
if (actualParameterClass == null) {
return false;
}
}
}
}
return true;
}
@Override
public BasicContinuation<?> execute() {
Type pivotType = csElement.getType();
if (pivotType != null) {
TemplateBindingCS csTemplateBinding = csElement.getOwnedTemplateBinding();
if ((csTemplateBinding != null) && ElementUtil.isSpecialization(csTemplateBinding)) {
pivotType = (Type) context.specializeTemplates(csElement);
// TemplateBinding pivotTemplateBinding = PivotUtil.getPivot(TemplateBinding.class, csTemplateBinding);
// pivotType = pivotTemplateBinding.getBoundElement();
}
if (pivotType != null) {
context.installPivotTypeWithMultiplicity(pivotType, csElement);
}
}
return null;
}
}
protected static class TemplateSignatureContinuation extends SingleContinuation<ClassifierCS>
{
public TemplateSignatureContinuation(@NonNull CS2PivotConversion context, NamedElement pivotParent, @NonNull ClassifierCS csElement) {
super(context, pivotParent, PivotPackage.Literals.TEMPLATEABLE_ELEMENT__OWNED_TEMPLATE_SIGNATURE, csElement);
context.getTypesHaveSignaturesInterDependency().addDependency(this);
}
@Override
public BasicContinuation<?> execute() {
Type pivotElement = PivotUtil.getPivot(Type.class, csElement);
if (pivotElement != null) {
context.refreshTemplateSignature(csElement, pivotElement);
context.getTypesHaveSignaturesInterDependency().setSatisfied(this);
}
return null;
}
}
protected static class TupleContinuation extends TypedRefContinuation<TupleTypeCS>
{
public TupleContinuation(@NonNull CS2PivotConversion context, @NonNull TupleTypeCS csElement) {
super(context, csElement);
}
@Override
public boolean canExecute() {
if (!super.canExecute()) {
return false;
}
for (TuplePartCS csTuplePart : csElement.getOwnedParts()) {
TypedRefCS ownedType = csTuplePart.getOwnedType();
Element pivot = ownedType.getPivot();
if (pivot == null) {
return false;
}
}
if (context.isInReturnTypeWithUnresolvedParameters(csElement)) {
return false;
}
return true;
}
@Override
public BasicContinuation<?> execute() {
String name = csElement.getName();
if (name != null) {
List<DomainTypedElement> parts = new ArrayList<DomainTypedElement>();
for (@SuppressWarnings("null")@NonNull TuplePartCS csTuplePart : csElement.getOwnedParts()) {
String partName = csTuplePart.getName();
if (partName != null) {
Type partType = PivotUtil.getPivot(Type.class, csTuplePart.getOwnedType());
if (partType != null) {
parts.add(new AbstractTuplePart(partType, partName));
}
}
}
TupleType tupleType = context.getMetaModelManager().getTupleType(name, parts, null);
context.installPivotTypeWithMultiplicity(tupleType, csElement);
List<Property> tupleParts = tupleType.getOwnedAttribute();
for (TuplePartCS csTuplePart : csElement.getOwnedParts()) {
String partName = csTuplePart.getName();
Property tuplePart = DomainUtil.getNamedElement(tupleParts, partName);
if (tuplePart != null) {
context.installPivotUsage(csTuplePart, tuplePart);
}
}
}
return null;
}
}
protected static abstract class TypedRefContinuation<T extends TypedRefCS> extends SingleContinuation<T>
{
public TypedRefContinuation(@NonNull CS2PivotConversion context, @NonNull T csElement, Dependency... dependencies) {
super(context, null, null, csElement);
}
}
protected static class UnspecializedTypeRefContinuation extends TypedRefContinuation<TypedTypeRefCS>
{
public UnspecializedTypeRefContinuation(@NonNull CS2PivotConversion context, @NonNull TypedTypeRefCS csElement) {
super(context, csElement, context.getTypesHaveSignaturesInterDependency());
assert csElement.getOwnedTemplateBinding() == null;
}
@Override
public BasicContinuation<?> execute() {
Type pivotType = csElement.getType();
if (pivotType != null) {
context.installPivotTypeWithMultiplicity(pivotType, csElement);
}
return null;
}
}
@AssistedInject
public BaseCSPreOrderVisitor(@Assisted @NonNull CS2PivotConversion context) {
super(context);
// getInjector().injectMembers(this); // FIXME workaround since this class is not injected by Guice yet.
}
// FIXME workaround since this class is not injected by guice yet
// protected Injector getInjector() {
// // overriden by derived classes
// return null;
// }
public Continuation<?> visiting(@NonNull VisitableCS visitable) {
throw new IllegalArgumentException("Unsupported " + visitable.eClass().getName() + " for CS2Pivot PreOrder pass");
}
@Override
public Continuation<?> visitAnnotationCS(@NonNull AnnotationCS object) {
return null;
}
@Override
public Continuation<?> visitClassCS(@NonNull ClassCS csClass) {
org.eclipse.ocl.examples.pivot.Class pivotElement = PivotUtil.getPivot(org.eclipse.ocl.examples.pivot.Class.class, csClass);
if (pivotElement == null) {
return null;
}
Continuations continuations = cs2asFactory.createContinuations();
if (csClass.getOwnedTemplateSignature() != null) {
continuations.add(new TemplateSignatureContinuation(context, pivotElement, csClass));
}
else {
pivotElement.setOwnedTemplateSignature(null);
}
if (!(pivotElement instanceof AnyType)) {
continuations.add(new ClassSupersContinuation(context, pivotElement, csClass));
}
return continuations.getContinuation();
}
@Override
public Continuation<?> visitConstraintCS(@NonNull ConstraintCS csConstraint) {
return null;
}
@Override
public Continuation<?> visitDataTypeCS(@NonNull DataTypeCS csDataType) {
DataType pivotElement = PivotUtil.getPivot(DataType.class, csDataType);
if (pivotElement != null) {
List<Type> pivotSuperClasses = pivotElement.getSuperClass();
pivotSuperClasses.clear();
org.eclipse.ocl.examples.pivot.Class oclElementType = context.getMetaModelManager().getOclElementType();
pivotSuperClasses.add(oclElementType);
}
return null;
}
@Override
public Continuation<?> visitDocumentationCS(@NonNull DocumentationCS object) {
return null;
}
@Override
public Continuation<?> visitEnumerationCS(@NonNull EnumerationCS csEnumeration) {
org.eclipse.ocl.examples.pivot.Enumeration pivotElement = PivotUtil.getPivot(org.eclipse.ocl.examples.pivot.Enumeration.class, csEnumeration);
if (pivotElement != null) {
List<Type> pivotSuperClasses = pivotElement.getSuperClass();
pivotSuperClasses.clear();
org.eclipse.ocl.examples.pivot.Class oclElementType = context.getMetaModelManager().getOclElementType();
pivotSuperClasses.add(oclElementType);
}
return null;
}
@Override
public Continuation<?> visitEnumerationLiteralCS(@NonNull EnumerationLiteralCS csEnumerationLiteral) {
return null;
}
@Override
public Continuation<?> visitLambdaTypeCS(@NonNull LambdaTypeCS csLambdaType) {
return new LambdaContinuation(context, csLambdaType);
}
@Override
public Continuation<?> visitModelElementCS(@NonNull ModelElementCS csModelElement) {
return null;
}
@Override
public Continuation<?> visitModelElementRefCS(@NonNull ModelElementRefCS csModelElementRef) {
return null;
}
@Override
public Continuation<?> visitMultiplicityBoundsCS(@NonNull MultiplicityBoundsCS object) {
return null;
}
@Override
public Continuation<?> visitMultiplicityStringCS(@NonNull MultiplicityStringCS object) {
return null;
}
@Override
public Continuation<?> visitOperationCS(@NonNull OperationCS csOperation) {
return null;
}
@Override
public Continuation<?> visitPackageCS(@NonNull PackageCS csPackage) {
return null;
}
@Override
public Continuation<?> visitParameterCS(@NonNull ParameterCS csParameter) {
return new ParameterContinuation(context, csParameter);
}
@Override
public Continuation<?> visitPathElementCS(@NonNull PathElementCS csElement) {
return null;
}
@Override
public Continuation<?> visitPathNameCS(@NonNull PathNameCS csElement) {
return null;
}
@Override
public Continuation<?> visitPrimitiveTypeRefCS(@NonNull PrimitiveTypeRefCS csPrimitiveTypeRef) {
return new PrimitiveTypeRefContinuation(context, csPrimitiveTypeRef);
}
@Override
public Continuation<?> visitStructuralFeatureCS(@NonNull StructuralFeatureCS csStructuralFeature) {
return null;
}
@Override
public Continuation<?> visitTemplateBindingCS(@NonNull TemplateBindingCS csTemplateBinding) {
return null;
}
@Override
public Continuation<?> visitTemplateSignatureCS(@NonNull TemplateSignatureCS csTemplateSignature) {
return null;
}
@Override
public Continuation<?> visitTupleTypeCS(@NonNull TupleTypeCS csTupleType) {
return new TupleContinuation(context, csTupleType);
}
@Override
public Continuation<?> visitTypedTypeRefCS(@NonNull TypedTypeRefCS csTypedTypeRef) {
if (csTypedTypeRef.getOwnedTemplateBinding() == null) {
return new UnspecializedTypeRefContinuation(context, csTypedTypeRef);
}
else {
return new SpecializedTypeRefContinuation1(context, csTypedTypeRef);
}
}
@Override
public Continuation<?> visitWildcardTypeRefCS(@NonNull WildcardTypeRefCS csWildcardTypeRef) {
return null;
}
}