Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorptessier2012-02-17 05:23:08 -0500
committerptessier2012-02-17 05:23:08 -0500
commita8906fa0ed85e79ccbb1959ce91ca1b0819144de (patch)
treed1a67ac88b1d7d4f37f0a82b9e04b0058ca753fb /extraplugins/alf
parentffe24c067e23c2394799151d31f3c9bbae04f6c5 (diff)
downloadorg.eclipse.papyrus-a8906fa0ed85e79ccbb1959ce91ca1b0819144de.tar.gz
org.eclipse.papyrus-a8906fa0ed85e79ccbb1959ce91ca1b0819144de.tar.xz
org.eclipse.papyrus-a8906fa0ed85e79ccbb1959ce91ca1b0819144de.zip
329865: [ALF editor] Papyrus shall provide a specific textual editor for ALF.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=329865
Diffstat (limited to 'extraplugins/alf')
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/Alf.xtext30
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/scoping/AbstractScopingTool.java39
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/scoping/AlfScopeProvider.java2
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/scoping/AlfScopingTool.java722
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/syntax/ASTFactory.java20
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/AlfJavaValidator.java39
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/PredefinedBehaviorsAndTypesUtils.java26
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/DefaultConstructorFacade.java2
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/MultiplicityFacade.java9
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacade.java150
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacadeFactory.java18
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TemplateBindingFacade.java98
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TemplateBindingFacadeFactory.java35
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeFacade.java37
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeFacadeFactory.java89
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeInferenceException.java41
-rw-r--r--extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeUtils.java408
17 files changed, 1528 insertions, 237 deletions
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/Alf.xtext b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/Alf.xtext
index 33f577e1203..17258d2ebf5 100644
--- a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/Alf.xtext
+++ b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/Alf.xtext
@@ -231,8 +231,12 @@ LinkOperationTuple :
'('linkOperationTupleElement += LinkOperationTupleElement (',' linkOperationTupleElement += LinkOperationTupleElement)*')'
;
+//LinkOperationTupleElement :
+// objectOrRole = ID (('['roleIndex = Expression ']')? '=>' object = ID)?
+//;
+
LinkOperationTupleElement :
- objectOrRole = ID (('['roleIndex = Expression ']')? '=>' object = ID)?
+ role = ID ('['roleIndex = Expression ']')? '=>' object = Expression
;
enum LinkOperationKind :
@@ -242,7 +246,8 @@ enum LinkOperationKind :
;
SequenceOperationExpression :
- '->' operationName = ID tuple = Tuple (suffix = SuffixExpression) ?
+ //'->' operationName = ID tuple = Tuple (suffix = SuffixExpression) ?
+ '->' operationName = QualifiedNameWithBinding tuple = Tuple (suffix = SuffixExpression) ?
;
SequenceReductionExpression :
@@ -332,11 +337,30 @@ SuperInvocationExpression :
('.' operationName = QualifiedNameWithBinding tuple = Tuple))
;
+//InstanceCreationExpression :
+ //'new' constructor=QualifiedNameWithBinding
+ // (tuple = Tuple | sequenceConstuctionCompletion = SequenceConstructionCompletion) (suffix = SuffixExpression) ?
+ //'new' constructor=QualifiedNameWithBinding
+ // tuple = Tuple (suffix = SuffixExpression) ?
+//;
+
InstanceCreationExpression :
//'new' constructor=QualifiedNameWithBinding
// (tuple = Tuple | sequenceConstuctionCompletion = SequenceConstructionCompletion) (suffix = SuffixExpression) ?
'new' constructor=QualifiedNameWithBinding
- tuple = Tuple (suffix = SuffixExpression) ?
+ tuple = InstanceCreationTuple (suffix = SuffixExpression) ?
+;
+
+InstanceCreationTuple :
+ {InstanceCreationTuple}'('(instanceCreationTupleElement += InstanceCreationTupleElement (',' instanceCreationTupleElement += InstanceCreationTupleElement)*)?')'
+;
+
+//LinkOperationTupleElement :
+// objectOrRole = ID (('['roleIndex = Expression ']')? '=>' object = ID)?
+//;
+
+InstanceCreationTupleElement :
+ role = ID '=>' object = Expression
;
SequenceConstructionOrAccessCompletion :
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/scoping/AbstractScopingTool.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/scoping/AbstractScopingTool.java
deleted file mode 100644
index b16092b6d6f..00000000000
--- a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/scoping/AbstractScopingTool.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*****************************************************************************
- * Copyright (c) 2011 CEA LIST.
- *
- *
- * 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:
- * CEA LIST - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.alf.scoping;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.papyrus.alf.validation.typing.TypeExpression;
-import org.eclipse.papyrus.alf.validation.typing.TypeFacade;
-
-public abstract class AbstractScopingTool {
-
- public abstract AlfPartialScope getVisibleVariablesOrParametersOrProperties(EObject context) ;
-
- public abstract AlfPartialScope getVisibleOperationsOrBehaviors(EObject context) ;
-
- public abstract AlfPartialScope getVisibleBehaviors(EObject context) ;
-
- public abstract AlfPartialScope getVisibleClassifiers(EObject context) ;
-
- public abstract AlfPartialScope getVisiblePackages(EObject context) ;
-
- public abstract boolean isAReturnStatementExpected(EObject context) ;
-
- public abstract TypeExpression getExpectedReturnType(EObject context) ;
-
- public abstract AlfPartialScope getVisibleSignalReceptions(EObject context) ;
-
- public abstract AlfPartialScope getVisibleFormalParameters(TypeFacade context) ;
-}
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/scoping/AlfScopeProvider.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/scoping/AlfScopeProvider.java
index 198f66db75e..cbbb2d9ace9 100644
--- a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/scoping/AlfScopeProvider.java
+++ b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/scoping/AlfScopeProvider.java
@@ -23,5 +23,5 @@ import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
*
*/
public class AlfScopeProvider extends AbstractDeclarativeScopeProvider {
- public static AbstractScopingTool scopingTool ;
+ public static AlfScopingTool scopingTool ;
}
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/scoping/AlfScopingTool.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/scoping/AlfScopingTool.java
new file mode 100644
index 00000000000..4f909b79725
--- /dev/null
+++ b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/scoping/AlfScopingTool.java
@@ -0,0 +1,722 @@
+/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.scoping;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.alf.alf.AcceptClause;
+import org.eclipse.papyrus.alf.alf.AcceptStatement;
+import org.eclipse.papyrus.alf.alf.DocumentedStatement;
+import org.eclipse.papyrus.alf.alf.InvocationOrAssignementOrDeclarationStatement;
+import org.eclipse.papyrus.alf.alf.LocalNameDeclarationStatement;
+import org.eclipse.papyrus.alf.alf.LoopVariableDefinition;
+import org.eclipse.papyrus.alf.alf.SequenceExpansionExpression;
+import org.eclipse.papyrus.alf.alf.Statement;
+import org.eclipse.papyrus.alf.validation.AlfJavaValidator;
+import org.eclipse.papyrus.alf.validation.typing.TypeExpression;
+import org.eclipse.papyrus.alf.validation.typing.TypeUtils;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.ElementImport;
+import org.eclipse.uml2.uml.Enumeration;
+import org.eclipse.uml2.uml.EnumerationLiteral;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Namespace;
+import org.eclipse.uml2.uml.Operation;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.PackageImport;
+import org.eclipse.uml2.uml.PackageableElement;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Reception;
+import org.eclipse.uml2.uml.Signal;
+import org.eclipse.uml2.uml.VisibilityKind;
+
+public abstract class AlfScopingTool {
+
+ protected static List<EObject> removeDuplicateClassifiers(List<EObject> list) {
+ List<EObject> intermediateFilteredList = new ArrayList<EObject>() ;
+
+ HashMap<String, Classifier> classifiers = new HashMap<String, Classifier>() ;
+ HashMap<String, Classifier> elementImports = new HashMap<String, Classifier>() ;
+ for (EObject o : list) {
+ if (o instanceof Classifier) {
+ Classifier c = (Classifier) o ;
+ if (classifiers.get(c.getQualifiedName()) == null) {
+ classifiers.put(c.getQualifiedName(), c) ;
+ intermediateFilteredList.add(c) ;
+ }
+ // else => nothing to be done, this is a duplicate
+ }
+ else if (o instanceof ElementImport) {
+ ElementImport e = (ElementImport)o ;
+ Classifier c = (Classifier)e.getImportedElement() ;
+ if (elementImports.get(e.getAlias()) == null) {
+ elementImports.put(e.getAlias(), c) ;
+ intermediateFilteredList.add(e) ;
+ }
+ else {// need to check if element import aliases the same thing.
+ Classifier alreadyInTheList = elementImports.get(e.getAlias()) ;
+ if (! alreadyInTheList.getQualifiedName().equals(c.getQualifiedName())) {
+ // The model is ill-formed, and there's no need to filter
+ intermediateFilteredList.add(e) ;
+ }
+ // else => nothing to be done, this is a duplicate
+ }
+ }
+ }
+
+ // needs to make a second pass on the filtered list, to remove cases where aliases and names are the same, and represent the same element
+ List<EObject> filteredList = new ArrayList<EObject>() ;
+ for (int i = 0 ; i < intermediateFilteredList.size() ; i++) {
+ String classifierName = (intermediateFilteredList.get(i) instanceof Classifier) ?
+ ((Classifier)intermediateFilteredList.get(i)).getName() :
+ ((ElementImport)intermediateFilteredList.get(i)).getAlias() ;
+ String classifierQualifiedName = (intermediateFilteredList.get(i) instanceof Classifier) ?
+ ((Classifier)intermediateFilteredList.get(i)).getQualifiedName() :
+ ((Classifier)((ElementImport)intermediateFilteredList.get(i)).getImportedElement()).getQualifiedName() ;
+ boolean duplicateFound = false ;
+ for (int j = i + 1 ; j < intermediateFilteredList.size() && !duplicateFound ; j++) {
+ String cddDuplicateClassifierName = (intermediateFilteredList.get(j) instanceof Classifier) ?
+ ((Classifier)intermediateFilteredList.get(j)).getName() :
+ ((ElementImport)intermediateFilteredList.get(j)).getAlias() ;
+ if (cddDuplicateClassifierName.equals(classifierName)) {
+ String cddDuplicateClassifierQualifiedName = (intermediateFilteredList.get(j) instanceof Classifier) ?
+ ((Classifier)intermediateFilteredList.get(j)).getQualifiedName() :
+ ((Classifier)((ElementImport)intermediateFilteredList.get(j)).getImportedElement()).getQualifiedName() ;
+ if (cddDuplicateClassifierQualifiedName.equals(classifierQualifiedName)) {
+ duplicateFound = true ;
+ }
+ }
+ }
+ if (!duplicateFound)
+ filteredList.add(intermediateFilteredList.get(i)) ;
+ }
+
+ return filteredList ;
+ }
+
+ public abstract AlfPartialScope getVisibleVariablesOrParametersOrProperties(EObject context) ;
+
+
+ public AlfPartialScope getVisibleOperationsOrBehaviors(EObject context) {
+ AlfPartialScope.IGetNameStrategy nameStrategy = new OperationAndBehaviorNameStrategy() ;
+ AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new OperationAndBehaviorBuildScopeStrategy() ;
+ return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ;
+ }
+
+ public AlfPartialScope getVisibleBehaviors(EObject context) {
+ AlfPartialScope.IGetNameStrategy nameStrategy = new BehaviorsNameStrategy() ;
+ AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new BehaviorsBuildScopeStrategy() ;
+ return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ;
+ }
+
+ public AlfPartialScope getVisibleClassifiers(EObject context) {
+ AlfPartialScope.IGetNameStrategy nameStrategy = new ClassifiersNameStrategy() ;
+ AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new ClassifiersBuildScopeStrategy() ;
+ return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ;
+ }
+
+ public AlfPartialScope getVisiblePackages(EObject context) {
+ if (context instanceof Package) {
+ AlfPartialScope.IGetNameStrategy nameStrategy = new PackageNameStrategy() ;
+ AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new PackagesBuildScopeStrategy() ;
+ return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ;
+ }
+ AlfPartialScope.IGetNameStrategy nameStrategy = new PackageNameStrategy() ;
+ AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new PackagesBuildScopeStrategy() ;
+ return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ;
+ }
+
+ public boolean isAReturnStatementExpected(EObject context) {
+ return false ;
+ }
+
+ public TypeExpression getExpectedReturnType(EObject context) {
+ return null;
+ }
+
+ public AlfPartialScope getVisibleSignalReceptions(EObject context) {
+ AlfPartialScope.IGetNameStrategy nameStrategy = new ReceptionsNameStrategy() ;
+ AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new ReceptionsBuildScopeStrategy() ;
+ return new AlfPartialScope(nameStrategy, buildScopeStrategy, context);
+ }
+
+ /*
+ * Strategies for operations
+ */
+ protected class OperationAndBehaviorNameStrategy implements AlfPartialScope.IGetNameStrategy {
+ public String getName(EObject element) {
+ if (element instanceof Operation)
+ return ((Operation)element).getName();
+ else if (element instanceof Behavior)
+ return ((Behavior)element).getName() ;
+ else if (element instanceof ElementImport) {
+ ElementImport eImport = (ElementImport)element ;
+ if (eImport.getAlias() != null)
+ return eImport.getAlias() ;
+ else
+ return ((Behavior)eImport.getImportedElement()).getName() ;
+ }
+ else if (element instanceof Reception) {
+ return ((Reception)element).getName() ;
+ }
+ else
+ return "Unexpected element kind..." ;
+ }
+ };
+
+ protected class OperationAndBehaviorBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy {
+ public List<List<EObject>> buildScope(EObject contextElement) {
+ List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ;
+ List<EObject> nestedList = new ArrayList<EObject>() ;
+
+ // in the case where the context element is a Package or an ElementImport for a package, the scope can only contain behaviors
+ Package potentialContextPackage = null ;
+ if (contextElement instanceof Package) {
+ potentialContextPackage = (Package)contextElement ;
+ }
+ else if (contextElement instanceof ElementImport) {
+ ElementImport eImport = (ElementImport)contextElement ;
+ if (eImport.getImportedElement() instanceof Package)
+ potentialContextPackage = (Package)eImport.getImportedElement() ;
+ }
+ if (potentialContextPackage != null) {
+ AlfPartialScope behaviorScope = AlfScopeProvider.scopingTool.getVisibleBehaviors(contextElement) ;
+ for (List<EObject> scope : behaviorScope.getScopeDetails()) {
+ nestedScopes.add(scope) ;
+ }
+ return nestedScopes ;
+ }
+
+ // At this point, we have identified that the context element is not a package.
+
+ // First scoping levels concern operations
+ // retrieves the contextClassier (i.e. the owner of the contextOperation, or contextElement)
+ Classifier contextClassifier ;
+ if (contextElement instanceof Classifier) {
+ contextClassifier = (Classifier)contextElement ;
+ }
+ else if (contextElement instanceof ElementImport && ((ElementImport)contextElement).getImportedElement() instanceof Classifier) {
+ contextClassifier = (Classifier) ((ElementImport)contextElement).getImportedElement() ;
+ }
+ else {
+ contextClassifier = AlfJavaValidator.getContextClassifier() ;
+ }
+
+ // add all the operations owned by the context classifier at the first scoping level
+ nestedList.addAll(contextClassifier.getOperations()) ;
+ // adds also receptions
+ if (contextClassifier instanceof org.eclipse.uml2.uml.Class) {
+ nestedList.addAll(((Class)contextClassifier).getOwnedReceptions()) ;
+ }
+
+ nestedScopes.add(nestedList) ;
+ // then builds other scoping levels based on context classifier inheritance hierarchy
+ List<Classifier> currentGenerals = new ArrayList<Classifier>() ;
+ currentGenerals.addAll(contextClassifier.getGenerals()) ;
+ List<Classifier> nextGenerals ;
+ while (!currentGenerals.isEmpty()) {
+ nextGenerals = new ArrayList<Classifier>() ;
+ nestedList = new ArrayList<EObject>() ;
+ for (Classifier general : currentGenerals) {
+ nextGenerals.addAll(general.getGenerals()) ;
+ for (Operation o : general.getOperations())
+ nestedList.add(o) ;
+ if (general instanceof Class) {
+ for (Reception r : ((Class)general).getOwnedReceptions()) {
+ nestedList.add(r) ;
+ }
+ }
+ }
+ nestedScopes.add(nestedList) ;
+ currentGenerals = nextGenerals ;
+ }
+
+ // finally feeds last scoping levels with behaviors (only if contextElement is not a Class)
+ if (! ((contextElement instanceof Classifier) ||
+ ((contextElement instanceof ElementImport &&
+ ((ElementImport)contextElement).getImportedElement() instanceof Classifier)))) {
+
+ AlfPartialScope behaviorScope = AlfScopeProvider.scopingTool.getVisibleBehaviors(contextElement) ;
+
+ for (List<EObject> scope : behaviorScope.getScopeDetails()) {
+ nestedScopes.add(scope) ;
+ }
+ }
+
+ return nestedScopes ;
+ }
+ }
+
+ /*
+ * Strategies for Receptions
+ */
+ protected class ReceptionsNameStrategy implements AlfPartialScope.IGetNameStrategy {
+ public String getName(EObject element) {
+ if (element instanceof Signal)
+ return ((Signal)element).getName();
+ else
+ return "Unexpected element kind..." ;
+ }
+ };
+
+ protected class ReceptionsBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy {
+ public List<List<EObject>> buildScope(EObject contextElement) {
+ List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ;
+ List<EObject> nestedList = new ArrayList<EObject>() ;
+
+ // retrieves the owner of the contextOperation
+ Classifier contextClassifier = AlfJavaValidator.getContextClassifier() ;
+ if (! (contextClassifier instanceof org.eclipse.uml2.uml.Class)) {
+ nestedScopes.add(nestedList) ;
+ return nestedScopes ;
+ }
+
+ // add all the signals for which a Reception is defined
+ for (org.eclipse.uml2.uml.Feature f : contextClassifier.allFeatures()) {
+ if (f instanceof Reception)
+ if (((Reception)f).getSignal() != null)
+ nestedList.add(((Reception)f).getSignal()) ;
+ }
+
+ nestedScopes.add(nestedList) ;
+
+ return nestedScopes ;
+ }
+ }
+
+ /*
+ * Strategies for Variables, Parameters and Properties
+ */
+ protected class VariableOrParameterOrPropertyNameStrategy implements AlfPartialScope.IGetNameStrategy {
+ public String getName(EObject element) {
+ if (element instanceof Property)
+ return ((Property)element).getName();
+ else if (element instanceof LocalNameDeclarationStatement){
+ return ((LocalNameDeclarationStatement)element).getVarName() ;
+ }
+ else if (element instanceof InvocationOrAssignementOrDeclarationStatement) {
+ InvocationOrAssignementOrDeclarationStatement statement = (InvocationOrAssignementOrDeclarationStatement)element ;
+ return statement.getVariableDeclarationCompletion() != null ?
+ statement.getVariableDeclarationCompletion().getVariableName() :
+ "" ;
+ }
+ else if (element instanceof LoopVariableDefinition) {
+ return ((LoopVariableDefinition)element).getName() ;
+ }
+ else if (element instanceof AcceptClause) {
+ return ((AcceptClause)element).getName() ;
+ }
+ else if (element instanceof AcceptStatement) {
+ return ((AcceptStatement)element).getClause().getName() ;
+ }
+ else if (element instanceof SequenceExpansionExpression) {
+ SequenceExpansionExpression expression = (SequenceExpansionExpression)element ;
+ return expression.getName() != null ?
+ expression.getName() :
+ "" ;
+ }
+ return "unexpected kind ..." ;
+ }
+ }
+
+ protected abstract class VariableOrPropertyOrParameterBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy {
+ public abstract List<List<EObject>> buildScope(EObject contextElement) ;
+
+ public boolean containsALocalNameDeclaration(DocumentedStatement previousDocumentStatement) {
+ Statement statement = previousDocumentStatement.getStatement() ;
+ if (statement instanceof LocalNameDeclarationStatement)
+ return true ;
+ if (statement instanceof InvocationOrAssignementOrDeclarationStatement) {
+ //TODO : handle cases with implicit declarations, e.g., v = 14 ; // v is a variable of type Integer
+ InvocationOrAssignementOrDeclarationStatement cddDclStatement = (InvocationOrAssignementOrDeclarationStatement)statement;
+ if (cddDclStatement.getVariableDeclarationCompletion() != null) {
+ return true ;
+ }
+ }
+ if (statement instanceof AcceptStatement) {
+ AcceptStatement cddDclStatement = (AcceptStatement)statement ;
+ if (cddDclStatement.getSimpleAccept() != null && cddDclStatement.getClause().getName() != null)
+ return true ;
+ }
+ return false;
+ }
+
+ }
+
+ /*
+ * Strategies for Classifiers
+ */
+ protected class ClassifiersNameStrategy implements AlfPartialScope.IGetNameStrategy {
+ public String getName(EObject element) {
+ if (element instanceof Classifier)
+ return ((Classifier)element).getName() ;
+ else if (element instanceof ElementImport) {
+ ElementImport imported = (ElementImport)element ;
+ return imported.getAlias() != null ? imported.getAlias() : ((Classifier)imported.getImportedElement()).getName() ;
+ }
+ else
+ return "Unexpected element kind..." ;
+ }
+ };
+
+ protected class ClassifiersBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy {
+ public List<List<EObject>> buildScope(EObject contextElement) {
+ List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ;
+ List<EObject> nestedList = new ArrayList<EObject>() ;
+
+ // first checks if contextElement represents a Package. In this case, builds a scope containing all classifiers visible from this package
+ Package potentialContextPackage = null ;
+ if (contextElement instanceof Package)
+ potentialContextPackage = (Package)contextElement ;
+ else if (contextElement instanceof ElementImport) {
+ ElementImport eImport = (ElementImport)contextElement ;
+ if (eImport.getImportedElement() instanceof Package)
+ potentialContextPackage = (Package)eImport.getImportedElement() ;
+ }
+ if (potentialContextPackage != null) {
+ List<EObject> importedClassifiers = processPublicallyImportedClassifiers(potentialContextPackage) ;
+ importedClassifiers = removeDuplicateClassifiers(importedClassifiers) ;
+ nestedScopes.add(importedClassifiers) ;
+ return nestedScopes ;
+ }
+
+ // retrieves the owner of the contextOperation
+ Classifier contextClassifier = AlfJavaValidator.getContextClassifier() ;
+
+ // add the context classifier at the first scoping level
+ nestedList.add(contextClassifier) ;
+ // retrieves all package imports, and add all classifiers available at the root of this package
+ for (PackageImport i : contextClassifier.getPackageImports()) {
+ Package importedPackage = i.getImportedPackage() ;
+ nestedList.addAll(processPublicallyImportedClassifiers(importedPackage)) ;
+ }
+ // retrieves all element imports. For those which concern a Classifier, either add the classifier if no alias is defined, or the element import if an alias is defined
+ for (ElementImport i : contextClassifier.getElementImports()) {
+ PackageableElement e = i.getImportedElement() ;
+ if (e instanceof Classifier) {
+ if (i.getAlias() != null)
+ nestedList.add(i) ;
+ else
+ nestedList.add(e) ;
+ }
+ }
+ nestedList = removeDuplicateClassifiers(nestedList) ;
+ nestedScopes.add(nestedList) ;
+
+ // Then process the implicit import of alf library
+ nestedList = new ArrayList<EObject>() ;
+ if (AlfJavaValidator.getAlfStandardLibrary() != null) {
+ List<EObject> importedClassifiers = processPublicallyImportedClassifiers(AlfJavaValidator.getAlfStandardLibrary()) ;
+
+ importedClassifiers.add(TypeUtils._Collection.extractActualType()) ;
+ importedClassifiers.add(TypeUtils._Set.extractActualType()) ;
+ importedClassifiers.add(TypeUtils._Bag.extractActualType()) ;
+ importedClassifiers.add(TypeUtils._Queue.extractActualType()) ;
+ importedClassifiers.add(TypeUtils._OrderedSet.extractActualType()) ;
+ importedClassifiers.add(TypeUtils._List.extractActualType()) ;
+ importedClassifiers.add(TypeUtils._Deque.extractActualType()) ;
+ importedClassifiers.add(TypeUtils._Map.extractActualType()) ;
+ //importedClassifiers.add(TypeUtils._Entry.extractActualType()) ;
+
+ nestedList.addAll(removeDuplicateClassifiers(importedClassifiers)) ;
+ nestedScopes.add(nestedList) ;
+ }
+
+ // Then process all classifiers at the same namespace level than the context classifier
+ nestedList = new ArrayList<EObject>() ;
+ Namespace namespaceOfContextClassifier = contextClassifier.getNamespace() ;
+ for (Element e : namespaceOfContextClassifier.getOwnedElements()) {
+ if (e instanceof Classifier && e != contextClassifier)
+ nestedList.add(e) ;
+ }
+ nestedScopes.add(nestedList) ;
+
+ return nestedScopes ;
+ }
+
+ private List<EObject> processPublicallyImportedClassifiers (Package p){
+ List<EObject> importedClassifiers = new ArrayList<EObject>() ;
+ for (NamedElement n : p.getOwnedMembers()) {
+ if (n instanceof Classifier)
+ if (((Classifier)n).getVisibility() != VisibilityKind.PRIVATE_LITERAL) {
+
+ importedClassifiers.add(n) ;
+ }
+ }
+ for (ElementImport eImport : p.getElementImports()) {
+ if (eImport.getVisibility()!= VisibilityKind.PRIVATE_LITERAL) {
+ PackageableElement element = eImport.getImportedElement() ;
+ if (element instanceof Classifier) {
+
+ if (eImport.getAlias() != null) {
+ importedClassifiers.add(eImport) ;
+ }
+ else {
+ importedClassifiers.add(element) ;
+ }
+
+ }
+ }
+ }
+ for (PackageImport pImport : p.getPackageImports()) {
+ if (pImport.getVisibility() != VisibilityKind.PRIVATE_LITERAL) {
+ importedClassifiers.addAll(processPublicallyImportedClassifiers(pImport.getImportedPackage())) ;
+ }
+ }
+ return importedClassifiers ;
+ }
+ }
+
+ /*
+ * Strategies for Packages
+ */
+ protected class PackageNameStrategy implements AlfPartialScope.IGetNameStrategy {
+ public String getName(EObject element) {
+ if (element instanceof Namespace)
+ return ((Namespace)element).getName() ;
+ else if (element instanceof ElementImport) {
+ ElementImport eImport = (ElementImport)element ;
+ return eImport.getAlias() != null ? eImport.getAlias() : eImport.getImportedElement().getName() ;
+ }
+ else
+ return "Unexpected element kind..." ;
+ }
+ }
+
+ protected class PackagesBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy {
+ public List<List<EObject>> buildScope(EObject contextElement) {
+
+ List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ;
+ List<EObject> nestedList = new ArrayList<EObject>() ;
+
+ if (contextElement instanceof Package) { // if the context element is a package, returns the scope related to this package.
+ nestedScopes.add(processPublicallyImportedPackages((Package)contextElement)) ;
+ return nestedScopes ;
+ }
+
+ Package root = (Package)AlfJavaValidator.getModel() ;
+
+ // first process packages directly imported by the context classifier (either package import or element import)
+ Classifier contextClassifier = AlfJavaValidator.getContextClassifier() ;
+
+ nestedList.addAll(processPublicallyImportedPackages(contextClassifier)) ;
+ nestedScopes.add(nestedList) ;
+
+ // Then process the implicit import of alf library
+ nestedList = new ArrayList<EObject>() ;
+ if (AlfJavaValidator.getAlfStandardLibrary() != null) {
+ nestedList.add(AlfJavaValidator.getAlfStandardLibrary()) ;
+ nestedList.addAll(processPublicallyImportedPackages(AlfJavaValidator.getAlfStandardLibrary())) ;
+ nestedScopes.add(nestedList) ;
+ }
+
+ // finally processes the root package
+ nestedList = new ArrayList<EObject>() ;
+ nestedList.add(root) ;
+ nestedScopes.add(nestedList) ;
+
+ return nestedScopes;
+ }
+
+ protected List<EObject> processPublicallyImportedPackages (Namespace namespace) {
+ List<EObject> importedPackages = new ArrayList<EObject>() ;
+
+ for (NamedElement ownedMember : namespace.getOwnedMembers()) {
+ if (ownedMember.getVisibility() != VisibilityKind.PRIVATE_LITERAL && ownedMember instanceof Package)
+ importedPackages.add(ownedMember) ;
+ }
+ for (ElementImport eImport : namespace.getElementImports()) {
+ if (eImport.getVisibility() != VisibilityKind.PRIVATE_LITERAL ) {
+ PackageableElement importedElement = eImport.getImportedElement() ;
+ if (importedElement instanceof Package) {
+ if (eImport.getAlias() != null)
+ importedPackages.add(eImport) ;
+ else
+ importedPackages.add(importedElement) ;
+ }
+ }
+ }
+ for (PackageImport pImport : namespace.getPackageImports()) {
+ if (pImport.getVisibility() != VisibilityKind.PRIVATE_LITERAL) {
+ importedPackages.addAll(processPublicallyImportedPackages(pImport.getImportedPackage())) ;
+ }
+ }
+
+ return importedPackages ;
+ }
+ }
+
+
+ /*
+ * Strategies for Behaviors
+ */
+
+ protected class BehaviorsNameStrategy implements AlfPartialScope.IGetNameStrategy {
+ public String getName(EObject element) {
+ if (element instanceof Behavior)
+ return ((Behavior)element).getName() ;
+ else if (element instanceof ElementImport) {
+ ElementImport imported = (ElementImport)element ;
+ return imported.getAlias() != null ? imported.getAlias() : ((Behavior)imported.getImportedElement()).getName() ;
+ }
+ else
+ return "Unexpected element kind..." ;
+ }
+ };
+
+ protected class BehaviorsBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy {
+ public List<List<EObject>> buildScope(EObject contextElement) {
+ List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ;
+ List<EObject> nestedList = new ArrayList<EObject>() ;
+
+ // first checks if contextElement represents a Package. In this case, builds a scope containing all behaviors visible from this package
+ Package potentialContextPackage = null ;
+ if (contextElement instanceof Package)
+ potentialContextPackage = (Package)contextElement ;
+ else if (contextElement instanceof ElementImport) {
+ ElementImport eImport = (ElementImport)contextElement ;
+ if (eImport.getImportedElement() instanceof Package)
+ potentialContextPackage = (Package)eImport.getImportedElement() ;
+ }
+ if (potentialContextPackage != null) {
+ nestedScopes.add(processPublicallyImportedBehaviors(potentialContextPackage)) ;
+ return nestedScopes ;
+ }
+
+ // retrieves the contextOperation (i.e., the operation edited by the current editor)
+ // retrieves the owner of the contextOperation
+ Classifier contextClassifier = AlfJavaValidator.getContextClassifier() ;
+
+ // retrieves all package imports, and add all behaviors available at the root of this package
+ for (PackageImport i : contextClassifier.getPackageImports()) {
+ Package importedPackage = i.getImportedPackage() ;
+ nestedList.addAll(processPublicallyImportedBehaviors(importedPackage)) ;
+ }
+ // retrieves all element imports. For those which concern a Behavior, either add the behavior if no alias is defined, or the element import if an alias is defined
+ for (ElementImport i : contextClassifier.getElementImports()) {
+ PackageableElement e = i.getImportedElement() ;
+ if (e instanceof Classifier) {
+ if (i.getAlias() != null)
+ nestedList.add(i) ;
+ else
+ nestedList.add(e) ;
+ }
+ }
+ nestedList = removeDuplicateClassifiers(nestedList) ;
+ nestedScopes.add(nestedList) ;
+
+ // Then process the implicit import of alf library
+ nestedList = new ArrayList<EObject>() ;
+ if (AlfJavaValidator.getAlfStandardLibrary() != null) {
+ List<EObject> importedClassifiers = processPublicallyImportedBehaviors(AlfJavaValidator.getAlfStandardLibrary()) ;
+ importedClassifiers = removeDuplicateClassifiers(importedClassifiers) ;
+ nestedList.addAll(importedClassifiers) ;
+ nestedScopes.add(nestedList) ;
+ }
+
+ return nestedScopes ;
+ }
+
+ private List<EObject> processPublicallyImportedBehaviors (Package p){
+ List<EObject> importedBehaviors = new ArrayList<EObject>() ;
+ for (NamedElement n : p.getOwnedMembers()) {
+ if (n instanceof Behavior) {
+ if (((Behavior)n).getVisibility() != VisibilityKind.PRIVATE_LITERAL)
+ importedBehaviors.add(n) ;
+ }
+ else if (n instanceof Package) {
+ importedBehaviors.addAll(processPublicallyImportedBehaviors((Package)n)) ;
+ }
+ }
+ for (ElementImport eImport : p.getElementImports()) {
+ if (eImport.getVisibility()!= VisibilityKind.PRIVATE_LITERAL) {
+ PackageableElement element = eImport.getImportedElement() ;
+ if (element instanceof Behavior) {
+ if (eImport.getAlias() != null)
+ importedBehaviors.add(eImport) ;
+ else
+ importedBehaviors.add(element) ;
+ }
+ }
+ }
+ for (PackageImport pImport : p.getPackageImports()) {
+ if (pImport.getVisibility() != VisibilityKind.PRIVATE_LITERAL) {
+ importedBehaviors.addAll(processPublicallyImportedBehaviors(pImport.getImportedPackage())) ;
+ }
+ }
+ return importedBehaviors ;
+ }
+ }
+
+
+
+ protected class EnumerationLiteralNameStrategy implements AlfPartialScope.IGetNameStrategy {
+ public String getName(EObject element) {
+ if (element instanceof EnumerationLiteral) {
+ return ((EnumerationLiteral)element).getName() ;
+ }
+ return "Unexpected element kind..." ;
+ }
+ }
+
+ protected class EnumerationLiteralBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy {
+ public List<List<EObject>> buildScope(EObject contextElement) {
+ List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ;
+ List<EObject> nestedList = new ArrayList<EObject>() ;
+
+ if (!(contextElement instanceof Enumeration)) {
+ nestedScopes.add(nestedList) ;
+ return nestedScopes ;
+ }
+ Enumeration contextEnumeration = (Enumeration)contextElement ;
+
+ // add all the literals owned by the context enumeration at the first scoping level
+ nestedList.addAll(contextEnumeration.getOwnedLiterals()) ;
+ nestedScopes.add(nestedList) ;
+ // then builds other scoping levels based on context classifier inheritance hierarchy
+
+ List<Classifier> currentGenerals = new ArrayList<Classifier>() ;
+ currentGenerals.addAll(contextEnumeration.getGenerals()) ;
+ List<Classifier> nextGenerals ;
+ while (!currentGenerals.isEmpty()) {
+ nextGenerals = new ArrayList<Classifier>() ;
+ nestedList = new ArrayList<EObject>() ;
+ for (Classifier general : currentGenerals) {
+ nextGenerals.addAll(general.getGenerals()) ;
+ if (general instanceof Enumeration) {
+ for (EnumerationLiteral enumLiteral : ((Enumeration)general).getOwnedLiterals())
+ nestedList.add(enumLiteral) ;
+ }
+ }
+ nestedScopes.add(nestedList) ;
+ currentGenerals = nextGenerals ;
+ }
+ return nestedScopes ;
+ }
+ }
+
+
+ public AlfPartialScope getVisibleEnumerationLiterals(EObject context) {
+ AlfPartialScope.IGetNameStrategy nameStrategy = new EnumerationLiteralNameStrategy() ;
+ AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new EnumerationLiteralBuildScopeStrategy() ;
+ return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ;
+ }
+
+}
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/syntax/ASTFactory.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/syntax/ASTFactory.java
index 92c7abbe8b2..52d8a64459d 100644
--- a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/syntax/ASTFactory.java
+++ b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/syntax/ASTFactory.java
@@ -1043,14 +1043,14 @@ public class ASTFactory {
synthesized.namedExpression = new ArrayList<NamedExpression>() ;
NamedExpression n ;
// Hypothesis: All LinkOperationTupleElement have both a "objectOrRole" and an "object"
- for (LinkOperationTupleElement t : tuple.getLinkOperationTupleElement()) {
- n = new NamedExpression() ;
- n.name = t.getObjectOrRole() ;
- if (t.getRoleIndex() != null)
- n.index = this.synthesizeExpression(t.getRoleIndex()) ;
- n.expression = this.synthesizeNameExpression(t.getObject()) ;
- synthesized.namedExpression.add(n) ;
- }
+// for (LinkOperationTupleElement t : tuple.getLinkOperationTupleElement()) {
+// n = new NamedExpression() ;
+// n.name = t.getObjectOrRole() ;
+// if (t.getRoleIndex() != null)
+// n.index = this.synthesizeExpression(t.getRoleIndex()) ;
+// n.expression = this.synthesizeNameExpression(t.getObject()) ;
+// synthesized.namedExpression.add(n) ;
+// }
return synthesized ;
}
@@ -1070,8 +1070,8 @@ public class ASTFactory {
/* 1. Synthesizes property target:QualifiedName */
synthesized.constructor = this.synthesizeQualifiedName(parsed.getConstructor()) ;
- /* 2. Synthesizes property tuple:Tuple */
- synthesized.tuple = this.synthesizeTuple(parsed.getTuple(), synthesized) ;
+// /* 2. Synthesizes property tuple:Tuple */
+// synthesized.tuple = this.synthesizeTuple(parsed.getTuple(), synthesized) ;
if (parsed.getSuffix() != null)
return this.synthesizeExpression(synthesized, parsed.getSuffix()) ;
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/AlfJavaValidator.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/AlfJavaValidator.java
index 91524fb1b91..d87f9692a93 100644
--- a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/AlfJavaValidator.java
+++ b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/AlfJavaValidator.java
@@ -85,7 +85,9 @@ import org.eclipse.swt.widgets.Shell;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Comment;
+import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.Namespace;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.PackageImport;
@@ -101,7 +103,10 @@ import org.eclipse.xtext.validation.EValidatorRegistrar;
public class AlfJavaValidator extends AbstractAlfJavaValidator {
+ private static Element contextElement ;
private static Classifier contextClassifier ;
+ private static Namespace model ;
+
private static Package alfStandardLibrary ; // TODO: include the library as part of the plug-in
public static PredefinedBehaviorsAndTypesUtils predefinedBehaviorsAndTypes ;
@@ -113,6 +118,22 @@ public class AlfJavaValidator extends AbstractAlfJavaValidator {
return true ;
}
+ public static Namespace getModel() {
+ return model;
+ }
+
+ public static void setModel(Namespace model) {
+ AlfJavaValidator.model = model;
+ }
+
+ public static void setContextElement(Element _contextElement) {
+ contextElement = _contextElement ;
+ }
+
+ public static Element getContextElement() {
+ return contextElement ;
+ }
+
public static Classifier getContextClassifier() {
return contextClassifier ;
}
@@ -248,7 +269,7 @@ public class AlfJavaValidator extends AbstractAlfJavaValidator {
}
}
- // 2. checks that type can be resolved
+ // 2. checks that type can be resolved, and that potentially required template bindings are specified
TypeFacade variableType = null ;
if (statement.getType() != null) {
variableType = TypeFacadeFactory.eInstance.createVoidFacade(statement.getType()) ;
@@ -257,6 +278,12 @@ public class AlfJavaValidator extends AbstractAlfJavaValidator {
error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ;
variableType = null ;
}
+ else if (variableType.isATemplate()){
+ if (statement.getType().getBinding() == null) {
+ String errorMessage = variableType.getLabel() + " is a template. All its parameters shall be bound." ;
+ error(errorMessage, statement, AlfPackage.eINSTANCE.getLocalNameDeclarationStatement_Type(), INSIGNIFICANT_INDEX) ;
+ }
+ }
}
// 3. checks the init expression
@@ -1399,16 +1426,16 @@ public class AlfJavaValidator extends AbstractAlfJavaValidator {
@Check
public void checkTemplateBindingInNameExpression(UnqualifiedName expression) {
if (expression.getTemplateBinding() != null) {
- String errorMessage = "Template bindings are not supported in this version of the Alf editor." ; // TODO
+ String errorMessage = "Template bindings are not supported in name expressions." ; // TODO
warning(errorMessage, AlfPackage.eINSTANCE.getUnqualifiedName_TemplateBinding()) ;
}
}
@Check
public void checkTemplateBindingInQualifiedNameWithBinding(QualifiedNameWithBinding expression) {
- if (expression.getBinding() != null) {
- String errorMessage = "Template bindings are not supported in this version of the Alf editor." ; // TODO
- warning(errorMessage, AlfPackage.eINSTANCE.getQualifiedNameWithBinding_Binding()) ;
- }
+ //if (expression.getBinding() != null) {
+ // String errorMessage = "Template bindings are not supported in this version of the Alf editor." ; // TODO
+ // warning(errorMessage, AlfPackage.eINSTANCE.getQualifiedNameWithBinding_Binding()) ;
+ //}
}
} \ No newline at end of file
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/PredefinedBehaviorsAndTypesUtils.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/PredefinedBehaviorsAndTypesUtils.java
index 0af6eddf173..33482dd32d9 100644
--- a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/PredefinedBehaviorsAndTypesUtils.java
+++ b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/PredefinedBehaviorsAndTypesUtils.java
@@ -19,6 +19,7 @@ import java.util.List;
import java.util.Map;
import org.eclipse.papyrus.alf.validation.typing.SignatureFacade;
+import org.eclipse.papyrus.alf.validation.typing.SignatureFacadeFactory;
import org.eclipse.papyrus.alf.validation.typing.TypeExpressionFactory;
import org.eclipse.papyrus.alf.validation.typing.TypeFacade;
import org.eclipse.papyrus.alf.validation.typing.TypeFacadeFactory;
@@ -27,6 +28,7 @@ import org.eclipse.uml2.uml.Behavior;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.ElementImport;
import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.PackageImport;
public class PredefinedBehaviorsAndTypesUtils {
@@ -35,12 +37,15 @@ public class PredefinedBehaviorsAndTypesUtils {
private Map<String, TypeFacade> typeMap = new HashMap<String, TypeFacade>() ;
private List<Behavior> behaviorInsertedAsElementImport = new ArrayList<Behavior>() ;
private List<Classifier> classifierInsertedAsElementImport = new ArrayList<Classifier>();
+ //private List<Behavior> predefinedCollectionFunctions = new ArrayList<Behavior>() ;
+ //private Map<String, SignatureFacade> predefinedCollectionFunctionsMap = new HashMap<String, SignatureFacade>() ;
public void init(org.eclipse.uml2.uml.Package library) {
behaviorMap = new HashMap<String, List<SignatureFacade>>();
typeMap = new HashMap<String, TypeFacade>() ;
behaviorInsertedAsElementImport = new ArrayList<Behavior>() ;
classifierInsertedAsElementImport = new ArrayList<Classifier>() ;
+ TypeUtils.predefinedCollectionFunctions = new HashMap<String, SignatureFacade>() ;
localInit(library) ;
// initializes predefined type facades from TypeUtils
TypeUtils._bitString = typeMap.get("BitString") ;
@@ -63,9 +68,12 @@ public class PredefinedBehaviorsAndTypesUtils {
}
private void localInit(org.eclipse.uml2.uml.Package library) {
+ if (library.getQualifiedName().equals("Alf::Library::CollectionFunctions")) {
+ this.initCollectionFunctions(library) ;
+ }
for (NamedElement n : library.getOwnedMembers()) {
if (n instanceof Behavior) {
- insertSignatureFacade(new SignatureFacade((Behavior)n)) ;
+ insertSignatureFacade(SignatureFacadeFactory.eInstance.createSignatureFacade(n)) ;
}
else if (n instanceof Classifier) {
insertTypeFacade(TypeFacadeFactory.eInstance.createTypeFacade(n)) ;
@@ -99,8 +107,24 @@ public class PredefinedBehaviorsAndTypesUtils {
TypeUtils._Deque = typeMap.get("Deque") ;
TypeUtils._Map = typeMap.get("Map") ;
TypeUtils._Entry = typeMap.get("Entry") ;
+
}
+ private void initCollectionFunctions(Package library) {
+ for (NamedElement element : library.getOwnedMembers()) {
+ if (element instanceof Behavior) {
+ SignatureFacade s = SignatureFacadeFactory.eInstance.createSignatureFacade(element) ;
+ TypeUtils.predefinedCollectionFunctions.put(s.getName(), s) ;
+ }
+ }
+ for (ElementImport eImport : library.getElementImports()) {
+ if (eImport.getImportedElement() instanceof Behavior) {
+ SignatureFacade s = SignatureFacadeFactory.eInstance.createSignatureFacade(eImport) ;
+ TypeUtils.predefinedCollectionFunctions.put(eImport.getAlias() == null || eImport.getAlias().isEmpty() ? s.getName() : eImport.getAlias(), s) ;
+ }
+ }
+ }
+
public List<SignatureFacade> getSignatures(String name) {
return behaviorMap.get(name) ;
}
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/DefaultConstructorFacade.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/DefaultConstructorFacade.java
index ee922d80f70..965ce551f6d 100644
--- a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/DefaultConstructorFacade.java
+++ b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/DefaultConstructorFacade.java
@@ -32,7 +32,9 @@ public class DefaultConstructorFacade extends SignatureFacade {
super(d) ;
this.datatypeToBeConstructed = d ;
for (Property p : d.getAllAttributes()) {
+ TypeExpression typeOfArgument = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
parameters.add(TypeExpressionFactory.eInstance.createTypeExpression(p)) ;
+ parametersMap.put(p.getName(), typeOfArgument) ;
}
this.setReturnType(TypeExpressionFactory.eInstance.createTypeExpression(d)) ;
}
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/MultiplicityFacade.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/MultiplicityFacade.java
index 7e64f1f1d6c..4ab7b6363c4 100644
--- a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/MultiplicityFacade.java
+++ b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/MultiplicityFacade.java
@@ -43,7 +43,7 @@ public class MultiplicityFacade {
}
public boolean isCompatibleWithMe(MultiplicityFacade multiplicity) {
- boolean lowerBoundCompatible = multiplicity.lowerBound >= this.lowerBound ;
+ //boolean lowerBoundCompatible = multiplicity.lowerBound >= this.lowerBound ;
boolean upperBoundCompatible = true ;
switch (this.upperBound) {
@@ -53,12 +53,13 @@ public class MultiplicityFacade {
default:
if (multiplicity.upperBound == -1)
upperBoundCompatible = false ;
- else
- upperBoundCompatible = multiplicity.upperBound <= this.upperBound ;
+// else
+// upperBoundCompatible = multiplicity.upperBound <= this.upperBound ;
break;
}
- return lowerBoundCompatible && upperBoundCompatible;
+ //return lowerBoundCompatible && upperBoundCompatible;
+ return upperBoundCompatible ;
}
public void setLowerBound(int lowerBound) {
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacade.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacade.java
index b358010078b..de53a815b07 100644
--- a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacade.java
+++ b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacade.java
@@ -14,23 +14,50 @@
package org.eclipse.papyrus.alf.validation.typing;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.alf.alf.InstanceCreationTupleElement;
+import org.eclipse.papyrus.alf.alf.QualifiedNameWithBinding;
+import org.eclipse.papyrus.uml.templates.utils.TemplateBindingUtils;
+import org.eclipse.uml2.uml.Activity;
import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.ElementImport;
+import org.eclipse.uml2.uml.FunctionBehavior;
+import org.eclipse.uml2.uml.Interaction;
+import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Parameter;
import org.eclipse.uml2.uml.ParameterDirectionKind;
+import org.eclipse.uml2.uml.ParameterableElement;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Reception;
+import org.eclipse.uml2.uml.StateMachine;
+import org.eclipse.uml2.uml.TemplateParameter;
+import org.eclipse.uml2.uml.TemplateParameterSubstitution;
+import org.eclipse.uml2.uml.TemplateableElement;
+import org.eclipse.uml2.uml.UMLFactory;
+import org.eclipse.uml2.uml.UMLPackage;
public class SignatureFacade {
private String name = "";
protected List<TypeExpression> parameters = new ArrayList<TypeExpression>();
- private TypeExpression returnType = TypeExpressionFactory.eInstance.createTypeExpression(TypeUtils._undefined, 0, 0, false, false) ;
+ //
+ protected Map<String, TypeExpression> parametersMap = new HashMap<String, TypeExpression>() ;
+ //
+ //private TypeExpression returnType = TypeExpressionFactory.eInstance.createTypeExpression(TypeUtils._undefined, 0, 0, false, false) ;
+ private TypeExpression returnType = null ;
private EObject actualSignatureObject = null ;
+ public EObject getActualSignatureObject() {
+ return actualSignatureObject;
+ }
+
public SignatureFacade() {
}
@@ -43,8 +70,11 @@ public class SignatureFacade {
for (Parameter p : operation.getOwnedParameters()) {
if (p.getDirection() == ParameterDirectionKind.RETURN_LITERAL)
returnType = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
- else
- parameters.add(TypeExpressionFactory.eInstance.createTypeExpression(p)) ;
+ else {
+ TypeExpression typeOfP = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
+ parameters.add(typeOfP) ;
+ parametersMap.put(p.getName(), typeOfP) ;
+ }
}
}
else if (o instanceof Behavior) {
@@ -54,8 +84,11 @@ public class SignatureFacade {
for (Parameter p : behavior.getOwnedParameters()) {
if (p.getDirection() == ParameterDirectionKind.RETURN_LITERAL)
returnType = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
- else
- parameters.add(TypeExpressionFactory.eInstance.createTypeExpression(p)) ;
+ else {
+ TypeExpression typeOfP = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
+ parameters.add(typeOfP) ;
+ parametersMap.put(p.getName(), typeOfP) ;
+ }
}
}
else if (o instanceof ElementImport) {
@@ -70,8 +103,23 @@ public class SignatureFacade {
for (Parameter p : b.getOwnedParameters()) {
if (p.getDirection() == ParameterDirectionKind.RETURN_LITERAL)
returnType = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
- else
- parameters.add(TypeExpressionFactory.eInstance.createTypeExpression(p)) ;
+ else {
+ TypeExpression typeOfP = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
+ parameters.add(typeOfP) ;
+ parametersMap.put(p.getName(), typeOfP) ;
+ }
+ }
+ }
+ }
+ else if (o instanceof Reception) {
+ Reception r = (Reception)o ;
+ this.actualSignatureObject = r ;
+ this.name = r.getName() ;
+ if (r.getSignal() != null) {
+ for (Property p : r.getSignal().getAllAttributes()) {
+ TypeExpression typeOfP = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
+ parameters.add(typeOfP) ;
+ parametersMap.put(p.getName(), typeOfP) ;
}
}
}
@@ -150,16 +198,28 @@ public class SignatureFacade {
return compatibilityLevel ;
}
+ public String isCompatibleWithMe(Map<String,TypeExpression> arguments) {
+ if (arguments.keySet().size() == 0 )
+ return "" ;
+ String compatibility = "" ;
+ for (String parameterName : arguments.keySet()) {
+ if (parametersMap.get(parameterName) == null) {
+ compatibility += "Parameter " + parameterName + " is undefined\n";
+ }
+ else {
+ int compatibilityLevel = parametersMap.get(parameterName).isCompatibleWithMe(arguments.get(parameterName)) ;
+ if (compatibilityLevel == 0) {
+ compatibility += "Parameter " + parameterName + " requires an argument of type " + parametersMap.get(parameterName).getLabel() + "\n" ;
+ }
+ }
+ }
+ return compatibility ;
+ }
+
public static List<SignatureFacade> findNearestSignature(List<TypeExpression> arguments, List<SignatureFacade> candidates) {
List<SignatureFacade> matchingSignatures = new ArrayList<SignatureFacade>() ;
int bestScore = 0 ;
for (SignatureFacade cddMatchingSignature : candidates) {
- //String signatureLabel = cddMatchingSignature.getName() + "(";
- //for (TypeExpression t : cddMatchingSignature.getParameters()) {
- // signatureLabel += " " + t.getLabel() + " ";
- //}
- //signatureLabel += ")" + (cddMatchingSignature.hasReturnType() ? " : " + cddMatchingSignature.getReturnType().getLabel() : "");
- //System.out.println(signatureLabel) ;
int currentScore = cddMatchingSignature.isCompatibleWithMe(arguments) ;
if (currentScore != 0) {
if (currentScore >= bestScore) {
@@ -173,11 +233,20 @@ public class SignatureFacade {
return matchingSignatures ;
}
+ public static List<SignatureFacade> findNearestConstructorSignature(Map<String, TypeExpression> arguments, List<SignatureFacade> candidates) {
+ List<SignatureFacade> matchingSignatures = new ArrayList<SignatureFacade>() ;
+ for (SignatureFacade cddMatchingSignature : candidates) {
+ String compatibility = cddMatchingSignature.isCompatibleWithMe(arguments) ;
+ if (compatibility.isEmpty()) {
+ matchingSignatures.add(cddMatchingSignature) ;
+ }
+ }
+ return matchingSignatures ;
+ }
+
public List<SignatureFacade> isNotDistinguishableFrom(List<SignatureFacade> candidates) {
List<SignatureFacade> matchingSignatures = new ArrayList<SignatureFacade>() ;
for (SignatureFacade cddMatchingSignature : candidates) {
- //System.out.println("self : " + this.getLabel()) ;
- //System.out.println("compared to : " + cddMatchingSignature.getLabel()) ;
if (this.name.equals(cddMatchingSignature.getName())) {
if (this.parameters.size() == cddMatchingSignature.parameters.size()) {
boolean parameterThatDoesNotMatchFound = false ;
@@ -225,4 +294,55 @@ public class SignatureFacade {
return false ;
return signature.getAppliedStereotype("Standard::Destroy") != null ;
}
+
+ public Map<String, TypeExpression> getParametersMap() {
+ return this.parametersMap ;
+ }
+
+ public boolean isATemplate() {
+ if (this.actualSignatureObject instanceof TemplateableElement) {
+ return ((TemplateableElement)this.actualSignatureObject).isTemplate() ;
+ }
+ return false ;
+ }
+
+ public SignatureFacade bindTemplate(Map<TemplateParameter, ParameterableElement> substitutions) {
+ if (this.isATemplate()) {
+ TemplateableElement t = (TemplateableElement)this.actualSignatureObject ;
+ if (t.getOwnedTemplateSignature().getParameters().size() != substitutions.size()) {
+ // Invalid number of template parameter subsitutions
+ return null ;
+ }
+ //Map<Object, EObject> substitutionsMap = new HashMap<Object, EObject>() ;
+
+ if (this.isATemplate()) {
+ TemplateableElement equivalentBoundElement = null ;
+ if (this.actualSignatureObject instanceof Activity) {
+ equivalentBoundElement = UMLFactory.eINSTANCE.createActivity() ;
+ }
+ else if (this.actualSignatureObject instanceof FunctionBehavior) {
+ equivalentBoundElement = UMLFactory.eINSTANCE.createFunctionBehavior() ;
+ }
+ else if (this.actualSignatureObject instanceof StateMachine) {
+ equivalentBoundElement = UMLFactory.eINSTANCE.createStateMachine() ;
+ }
+ else if (this.actualSignatureObject instanceof Interaction) {
+ equivalentBoundElement = UMLFactory.eINSTANCE.createInteraction() ;
+ }
+ else if (this.actualSignatureObject instanceof Operation) {
+ equivalentBoundElement = UMLFactory.eINSTANCE.createOperation() ;
+ }
+ ((NamedElement)equivalentBoundElement).setName(((NamedElement)this.actualSignatureObject).getName()) ;
+ org.eclipse.uml2.uml.TemplateBinding generatedTemplateBinding = equivalentBoundElement.createTemplateBinding(((TemplateableElement)this.actualSignatureObject).getOwnedTemplateSignature()) ;
+ for (TemplateParameter formal : substitutions.keySet()) {
+ TemplateParameterSubstitution tps = generatedTemplateBinding.createParameterSubstitution() ;
+ tps.setFormal(formal) ;
+ tps.setActual(substitutions.get(formal)) ;
+ }
+ equivalentBoundElement = (TemplateableElement)new TemplateBindingUtils().getEquivalentBoundElement(equivalentBoundElement) ;
+ return SignatureFacadeFactory.eInstance.createSignatureFacade(equivalentBoundElement) ;
+ }
+ }
+ return this ;
+ }
}
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacadeFactory.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacadeFactory.java
index 5aa86f9e548..1065abea3d9 100644
--- a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacadeFactory.java
+++ b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacadeFactory.java
@@ -14,10 +14,13 @@
package org.eclipse.papyrus.alf.validation.typing;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.papyrus.alf.alf.InstanceCreationExpression;
+import org.eclipse.papyrus.alf.alf.InstanceCreationTupleElement;
import org.eclipse.papyrus.alf.alf.QualifiedNameWithBinding;
import org.eclipse.papyrus.alf.alf.TupleElement;
import org.eclipse.papyrus.alf.scoping.AlfScopeProvider;
@@ -37,12 +40,15 @@ public class SignatureFacadeFactory {
public SignatureFacade createConstructorFacade(InstanceCreationExpression exp) throws Exception {
List<TypeExpression> arguments = new ArrayList<TypeExpression>() ;
- if (exp.getTuple().getTupleElements() != null) {
- for (TupleElement tupleElement : exp.getTuple().getTupleElements()) {
- TypeExpression typeOfArgument = new TypeUtils().getTypeOfExpression(tupleElement.getArgument()) ;
+ Map<String, TypeExpression> argumentsMap = new HashMap<String, TypeExpression>() ;
+
+ if (exp.getTuple().getInstanceCreationTupleElement() != null) {
+ for (InstanceCreationTupleElement tupleElement : exp.getTuple().getInstanceCreationTupleElement()) {
+ TypeExpression typeOfArgument = new TypeUtils().getTypeOfExpression(tupleElement.getObject()) ;
if (typeOfArgument.getTypeFacade() instanceof ErrorTypeFacade)
- throw new Exception(typeOfArgument.getTypeFacade().getLabel()) ;
+ throw new TypeInferenceException(typeOfArgument) ;
arguments.add(typeOfArgument) ;
+ argumentsMap.put(tupleElement.getRole(), typeOfArgument) ;
}
}
@@ -129,7 +135,7 @@ public class SignatureFacadeFactory {
errorMessage += ") is undefined" ;
throw new Exception(errorMessage) ;
}
- String potentialErrorMessage = constructor.isCompatibleWithMe(arguments, true) ;
+ String potentialErrorMessage = constructor.isCompatibleWithMe(argumentsMap) ;
if (potentialErrorMessage.length() == 0)
return constructor ;
else
@@ -139,7 +145,7 @@ public class SignatureFacadeFactory {
else if (referencedType instanceof DataType){ // This is a data type.
//must match arguments with visible properties of the data type
SignatureFacade defaultDataTypeConstructor = new DefaultConstructorFacade((DataType)referencedType) ;
- String errorMessage = defaultDataTypeConstructor.isCompatibleWithMe(arguments, true) ;
+ String errorMessage = defaultDataTypeConstructor.isCompatibleWithMe(argumentsMap) ;
if (!(errorMessage.length() == 0))
throw new Exception(errorMessage) ;
else
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TemplateBindingFacade.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TemplateBindingFacade.java
deleted file mode 100644
index 08c756ad413..00000000000
--- a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TemplateBindingFacade.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*****************************************************************************
- * Copyright (c) 2011 CEA LIST.
- *
- *
- * 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:
- * CEA LIST - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.alf.validation.typing;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.papyrus.alf.alf.LocalNameDeclarationStatement;
-import org.eclipse.papyrus.alf.alf.LoopVariableDefinition;
-import org.eclipse.papyrus.alf.alf.SequenceExpansionExpression;
-import org.eclipse.uml2.uml.Classifier;
-import org.eclipse.uml2.uml.ClassifierTemplateParameter;
-import org.eclipse.uml2.uml.ElementImport;
-import org.eclipse.uml2.uml.Parameter;
-import org.eclipse.uml2.uml.Property;
-import org.eclipse.uml2.uml.TemplateBinding;
-import org.eclipse.uml2.uml.TemplateParameterSubstitution;
-
-public class TemplateBindingFacade {
-
- public class ParameterSubstitutionFacade {
- private ClassifierTemplateParameter formal ;
- private TypeFacade actual ;
-
- public ParameterSubstitutionFacade(TemplateParameterSubstitution t) {
- this.formal = (ClassifierTemplateParameter)t.getFormal() ;
- this.actual = TypeFacadeFactory.eInstance.createTypeFacade((Classifier)t.getActual()) ;
- }
-
- public ParameterSubstitutionFacade(ClassifierTemplateParameter formal, TypeFacade actual) {
- this.formal = formal ;
- this.actual = actual ;
- }
-
- public ClassifierTemplateParameter getFormal() {
- return formal;
- }
-
- public void setFormal(ClassifierTemplateParameter formal) {
- this.formal = formal;
- }
-
- public TypeFacade getActual() {
- return actual;
- }
-
- public void setActual(TypeFacade actual) {
- this.actual = actual;
- }
-
- public String getLabel(boolean withExplicitFormalParameter) {
- String label = actual.getLabelWithoutBinding() ;
- if (withExplicitFormalParameter) {
- label = ((Classifier)formal.getParameteredElement()).getName() + " => " + label ;
- }
- return label ;
- }
-
- public String getLabel() {
- return getLabel(false) ;
- }
- }
-
- private List<ParameterSubstitutionFacade> substitutions ;
-
- public TemplateBindingFacade() {
- this.substitutions = new ArrayList<TemplateBindingFacade.ParameterSubstitutionFacade>() ;
- }
-
- public String getLabel(boolean withExplicitFormalParameters) {
- if (substitutions.isEmpty())
- return "" ;
- String label = "<" ;
- boolean first = true ;
- for (ParameterSubstitutionFacade s : substitutions) {
- if (!first) label += ", " ; else first = false ;
- label += withExplicitFormalParameters ? s.getLabel(true) : s.getLabel(false) ;
- }
- label += ">" ;
- return label ;
- }
-
- public String getLabel() {
- return this.getLabel(false) ;
- }
-}
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TemplateBindingFacadeFactory.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TemplateBindingFacadeFactory.java
deleted file mode 100644
index 006b8e2b219..00000000000
--- a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TemplateBindingFacadeFactory.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*****************************************************************************
- * Copyright (c) 2011 CEA LIST.
- *
- *
- * 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:
- * CEA LIST - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.alf.validation.typing;
-
-import org.eclipse.papyrus.alf.alf.TemplateBinding;
-import org.eclipse.uml2.uml.Classifier;
-
-public class TemplateBindingFacadeFactory {
-
- // TODO: store bound classifiers to avoid useless recomputing
-
- public static TemplateBindingFacadeFactory eInstance = new TemplateBindingFacadeFactory() ;
-
- public TemplateBindingFacade createTemplateBindingFacade() {
- return new TemplateBindingFacade() ;
- }
-
- public TemplateBindingFacade createTemplateBindingFacade(TemplateBinding templateBinding, Classifier boundTemplate) throws Exception {
- TemplateBindingFacade bindingFacade = new TemplateBindingFacade() ;
- templateBinding.getBindings().get(0).getActual() ;
- return bindingFacade ;
- }
-
-}
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeFacade.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeFacade.java
index c21fe56259d..d6eb0258a54 100644
--- a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeFacade.java
+++ b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeFacade.java
@@ -14,20 +14,31 @@
package org.eclipse.papyrus.alf.validation.typing;
import java.util.List;
+import java.util.Map;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.alf.alf.AcceptClause;
+import org.eclipse.papyrus.alf.alf.AcceptStatement;
import org.eclipse.papyrus.alf.alf.Expression;
import org.eclipse.papyrus.alf.alf.SequenceExpansionExpression;
import org.eclipse.papyrus.alf.alf.SuffixExpression;
+import org.eclipse.papyrus.alf.alf.TemplateBinding;
import org.eclipse.papyrus.alf.validation.AlfJavaValidator;
+import org.eclipse.papyrus.uml.templates.utils.TemplateBindingUtils;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.ElementImport;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Operation;
+import org.eclipse.uml2.uml.ParameterableElement;
+import org.eclipse.uml2.uml.TemplateParameter;
+import org.eclipse.uml2.uml.TemplateParameterSubstitution;
+import org.eclipse.uml2.uml.TemplateableElement;
import org.eclipse.uml2.uml.TypedElement;
+import org.eclipse.uml2.uml.UMLFactory;
public class TypeFacade {
protected EObject typeObject ;
- protected TemplateBindingFacade templateBindingFacade ;
public void setTypeObject(EObject typeObject) {
this.typeObject = typeObject ;
@@ -45,6 +56,8 @@ public class TypeFacade {
if (myType == null) // i.e. any
return 3 ;
Classifier hisType = extractActualType(type) ;
+ if (hisType == null)
+ return 0 ;
if (perfectMatch(myType, hisType))
return 3 ;
//else if (autoConversionMatch(myType, hisType)) TODO: temporarily commented. Rules need to be clarified
@@ -118,6 +131,11 @@ public class TypeFacade {
// infers the type of the nesting expression, ignoring the t.typeObject suffix
TypeExpression typeOfPrefix = new TypeUtils((SuffixExpression)t.typeObject).getTypeOfExpression((Expression)cddExpression) ;
actualType = extractActualType(typeOfPrefix.getTypeFacade()) ;
+ for (Operation o : actualType.getAllOperations()) {
+ if (o.getName().equals("toSequence")) {
+ actualType = (Classifier) (o.getReturnResult() != null ? o.getReturnResult().getType() : actualType) ;
+ }
+ }
}
return actualType ;
}
@@ -161,4 +179,21 @@ public class TypeFacade {
return "" ; // TODO: uncomment when template bindings are supported + this.templateBindingFacade.getLabel() ;
}
+ public void bindTemplate(Map<TemplateParameter, ParameterableElement> substitutions) {
+ if (this.isATemplate()) {
+ Classifier equivalentBoundElement = null ;
+ if (this.typeObject instanceof org.eclipse.uml2.uml.Class) {
+ equivalentBoundElement = UMLFactory.eINSTANCE.createClass() ;
+ equivalentBoundElement.setName(((NamedElement)this.typeObject).getName()) ;
+ }
+ org.eclipse.uml2.uml.TemplateBinding generatedTemplateBinding = equivalentBoundElement.createTemplateBinding(((TemplateableElement)this.typeObject).getOwnedTemplateSignature()) ;
+ for (TemplateParameter formal : substitutions.keySet()) {
+ TemplateParameterSubstitution tps = generatedTemplateBinding.createParameterSubstitution() ;
+ tps.setFormal(formal) ;
+ tps.setActual(substitutions.get(formal)) ;
+ }
+ this.typeObject = new TemplateBindingUtils().getEquivalentBoundElement(equivalentBoundElement) ;
+ }
+ }
+
}
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeFacadeFactory.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeFacadeFactory.java
index b363ede70f0..16639c7535d 100644
--- a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeFacadeFactory.java
+++ b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeFacadeFactory.java
@@ -13,11 +13,16 @@
*****************************************************************************/
package org.eclipse.papyrus.alf.validation.typing;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.papyrus.alf.alf.AcceptClause;
+import org.eclipse.papyrus.alf.alf.AcceptStatement;
import org.eclipse.papyrus.alf.alf.AlfPackage;
import org.eclipse.papyrus.alf.alf.ClassificationExpression;
import org.eclipse.papyrus.alf.alf.Expression;
@@ -25,15 +30,20 @@ import org.eclipse.papyrus.alf.alf.InvocationOrAssignementOrDeclarationStatement
import org.eclipse.papyrus.alf.alf.LocalNameDeclarationStatement;
import org.eclipse.papyrus.alf.alf.LoopVariableDefinition;
import org.eclipse.papyrus.alf.alf.NameExpression;
+import org.eclipse.papyrus.alf.alf.NamedTemplateBinding;
import org.eclipse.papyrus.alf.alf.QualifiedNameWithBinding;
import org.eclipse.papyrus.alf.alf.SequenceExpansionExpression;
import org.eclipse.papyrus.alf.alf.SuperInvocationExpression;
import org.eclipse.papyrus.alf.alf.UnqualifiedName;
import org.eclipse.papyrus.alf.scoping.AlfScopeProvider;
+import org.eclipse.papyrus.uml.templates.utils.TemplateBindingUtils;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.ElementImport;
+import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Parameter;
+import org.eclipse.uml2.uml.ParameterableElement;
import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.TemplateParameter;
import org.eclipse.uml2.uml.TypedElement;
public class TypeFacadeFactory {
@@ -93,6 +103,8 @@ public class TypeFacadeFactory {
TypeFacade t = TypeFacadeFactory.eInstance.createTypeFacade(typeObject) ;
return t.extractActualType().getName() + super.getLabel() ;
}
+ if (typeObject == null)
+ return "any" ;
}
catch (NullPointerException e) { // occurs when no type can be derived from typeObject (i.e., typeObject.getType() == null)
return "any" ;
@@ -146,6 +158,18 @@ public class TypeFacadeFactory {
else if (typeObject instanceof SequenceExpansionExpression) {
result.setTypeObject(typeObject) ;
}
+ else if (typeObject instanceof AcceptStatement) {
+ // first extract the accept clause
+ AcceptClause acceptClause = (AcceptClause)((AcceptStatement)typeObject).getClause() ;
+ if (acceptClause.getQualifiedNameList() != null && !(acceptClause.getQualifiedNameList().getQualifiedName().isEmpty())) {
+ // TODO : getQualifiedName is a collection. Should compute the least common ancestor.
+ TypeFacade f = TypeFacadeFactory.eInstance.createVoidFacade(acceptClause.getQualifiedNameList().getQualifiedName().get(0)) ;
+ result.setTypeObject(f.extractActualType()) ;
+ }
+ else {
+ result.setTypeObject(typeObject) ;
+ }
+ }
return result ;
}
@@ -301,7 +325,70 @@ public class TypeFacadeFactory {
return createErrorTypeFacade(remaining.getId() + " resolves to multiple classifiers.", remaining,
AlfPackage.eINSTANCE.getQualifiedNameWithBinding_Id()) ;
}
- return new VoidFacade(createTypeFacade(visibleClassifiers.get(0))) ;
+
+ // Need to check that potential binding is valid
+ Classifier resolvedClassifier = (Classifier)visibleClassifiers.get(0) ;
+ if (!resolvedClassifier.isTemplate()) {
+ if (remaining.getBinding()!= null) {
+ return createErrorTypeFacade(remaining.getId() + " is not a template", remaining,
+ AlfPackage.eINSTANCE.getQualifiedNameWithBinding_Binding()) ;
+ }
+ else {
+ return new VoidFacade(createTypeFacade(visibleClassifiers.get(0))) ;
+ }
+ }
+ else {
+ if (remaining.getBinding()!= null) {
+ // Needs to check that the binding is correct:
+ List<ParameterableElement> orderedListOfParameteredElements = new ArrayList<ParameterableElement>() ;
+ Map<String, ParameterableElement> mapOfParameteredElements = new HashMap<String, ParameterableElement>() ;
+ for (TemplateParameter tp : resolvedClassifier.getOwnedTemplateSignature().getOwnedParameters()) {
+ ParameterableElement p = tp.getParameteredElement() ;
+ if (p != null) {
+ orderedListOfParameteredElements.add(p) ;
+ mapOfParameteredElements.put(((NamedElement)p).getName(), p) ;
+ }
+ }
+ // Builds the substitutions map
+ Map<TemplateParameter, ParameterableElement> substitutionsMap = new HashMap<TemplateParameter, ParameterableElement>() ;
+ for (NamedTemplateBinding ntp : remaining.getBinding().getBindings()) {
+ ParameterableElement formal = mapOfParameteredElements.get(ntp.getFormal()) ;
+ if (formal == null) {
+ return createErrorTypeFacade("Template parameter " + ntp.getFormal() + " is undefined for classifier " + remaining.getId() , ntp,
+ AlfPackage.eINSTANCE.getNamedTemplateBinding_Formal()) ;
+ }
+ TypeFacade actual = createVoidFacade(ntp.getActual()) ;
+ if (actual instanceof ErrorTypeFacade)
+ return actual ;
+ substitutionsMap.put(formal.getTemplateParameter(), actual.extractActualType()) ;
+ }
+ // Checks the number of specified substitution
+ if (remaining.getBinding().getBindings().size() != orderedListOfParameteredElements.size()) {
+ String errorMessage = "" ;
+ if (remaining.getBinding().getBindings().size() > orderedListOfParameteredElements.size())
+ errorMessage = "Too many template bindings specified for " + remaining.getId() ;
+ else {
+ errorMessage = "Template bindings are missing for " + remaining.getId() ;
+ }
+ return createErrorTypeFacade(errorMessage, remaining,
+ AlfPackage.eINSTANCE.getQualifiedNameWithBinding_Binding()) ;
+ }
+ // Now, can create the void facade, and bind it with appropriate substitutions
+ VoidFacade boundResolvedClassifier = new VoidFacade(createTypeFacade(visibleClassifiers.get(0))) ;
+// HashMap<Object, EObject> actualSubsitutionsMap = new HashMap<Object, EObject>() ;
+// for (ParameterableElement p : orderedListOfParameteredElements) {
+// actualSubsitutionsMap.put(TemplateBindingUtils.getParameteredElementName(p),
+// subsitutionsMap.get(p) ) ;
+// }
+ boundResolvedClassifier.bindTemplate(substitutionsMap) ;
+
+ return boundResolvedClassifier;
+ }
+ else {
+ // Binding is not specified. It is up to the caller to perform implicit bindings.
+ return new VoidFacade(createTypeFacade(visibleClassifiers.get(0))) ;
+ }
+ }
}
}
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeInferenceException.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeInferenceException.java
new file mode 100644
index 00000000000..ead36e1263d
--- /dev/null
+++ b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeInferenceException.java
@@ -0,0 +1,41 @@
+package org.eclipse.papyrus.alf.validation.typing;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+public class TypeInferenceException extends Exception {
+
+ protected String errorMessage = "" ;
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ protected EObject errorSource = null ;
+ public EObject getErrorSource() {
+ return errorSource;
+ }
+
+ protected EStructuralFeature errorFeature = null ;
+ public EStructuralFeature getErrorFeature() {
+ return errorFeature;
+ }
+
+ public TypeInferenceException(TypeExpression typeOfArgument) {
+ // TODO Auto-generated constructor stub
+ if (typeOfArgument != null && typeOfArgument.getTypeFacade() != null) {
+ if (typeOfArgument.getTypeFacade() instanceof ErrorTypeFacade) {
+ ErrorTypeFacade e = (ErrorTypeFacade)typeOfArgument.getTypeFacade() ;
+ this.errorMessage += e.getLabel() ;
+ this.errorSource = e.getErrorSource() ;
+ this.errorFeature = e.getStructuralFeature() ;
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -152485940032266338L;
+
+
+}
diff --git a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeUtils.java b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeUtils.java
index 2b9da22074f..dbe88404c25 100644
--- a/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeUtils.java
+++ b/extraplugins/alf/org.eclipse.papyrus.alf/src/org/eclipse/papyrus/alf/validation/typing/TypeUtils.java
@@ -14,8 +14,10 @@
package org.eclipse.papyrus.alf.validation.typing;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
@@ -44,7 +46,8 @@ import org.eclipse.papyrus.alf.alf.NameExpression;
import org.eclipse.papyrus.alf.alf.NonLiteralValueSpecification;
import org.eclipse.papyrus.alf.alf.NullExpression;
import org.eclipse.papyrus.alf.alf.OperationCallExpression;
-import org.eclipse.papyrus.alf.alf.OperationCallExpressionWithoutDot;
+import org.eclipse.papyrus.alf.alf.Tuple;
+//import org.eclipse.papyrus.alf.alf.OperationCallExpressionWithoutDot;
import org.eclipse.papyrus.alf.alf.ParenthesizedExpression;
import org.eclipse.papyrus.alf.alf.PrimaryExpression;
import org.eclipse.papyrus.alf.alf.PropertyCallExpression;
@@ -68,11 +71,19 @@ import org.eclipse.papyrus.alf.alf.UnqualifiedName;
import org.eclipse.papyrus.alf.alf.ValueSpecification;
import org.eclipse.papyrus.alf.scoping.AlfScopeProvider;
import org.eclipse.papyrus.alf.validation.AlfJavaValidator;
+import org.eclipse.papyrus.alf.validation.PredefinedBehaviorsAndTypesUtils;
import org.eclipse.uml2.common.util.UML2Util;
import org.eclipse.uml2.uml.Behavior;
import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Enumeration;
+import org.eclipse.uml2.uml.EnumerationLiteral;
+import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Parameter;
+import org.eclipse.uml2.uml.ParameterDirectionKind;
+import org.eclipse.uml2.uml.ParameterableElement;
import org.eclipse.uml2.uml.PrimitiveType;
+import org.eclipse.uml2.uml.TemplateParameter;
+import org.eclipse.uml2.uml.TemplateableElement;
public class TypeUtils {
@@ -93,6 +104,7 @@ public class TypeUtils {
public static TypeFacade _Deque ;
public static TypeFacade _Map ;
public static TypeFacade _Entry ;
+ public static Map<String, SignatureFacade> predefinedCollectionFunctions ;
private SuffixExpression suffixToBeIgnored = null ;
@@ -542,10 +554,20 @@ public class TypeUtils {
}
}
catch (Exception e) {
- ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ ErrorTypeFacade error = null ;
+ if (e instanceof TypeInferenceException) {
+ TypeInferenceException tie = (TypeInferenceException)e ;
+ error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ tie.getErrorMessage(),
+ tie.getErrorSource(),
+ tie.getErrorFeature()) ;
+ }
+ else {
+ error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
e.getMessage(),
exp,
AlfPackage.eINSTANCE.getInstanceCreationExpression_Constructor()) ;
+ }
return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
}
}
@@ -651,8 +673,53 @@ public class TypeUtils {
// first resolves the first element of the path
List<EObject> visiblePackages = AlfScopeProvider.scopingTool.getVisiblePackages(exp).resolveByName(path.get(0).getName()) ;
if (visiblePackages.isEmpty()) {
- ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Could not resolve package " + path.get(0).getName(), path.get(0), AlfPackage.eINSTANCE.getUnqualifiedName_Name()) ;
- return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ // Try to find a classifier
+ List<EObject> visibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(exp).resolveByName(path.get(0).getName()) ;
+ if (visibleClassifiers.isEmpty()) {
+ // No classifier found
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Could not resolve package " + path.get(0).getName(), path.get(0), AlfPackage.eINSTANCE.getUnqualifiedName_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else if (visibleClassifiers.size() > 1) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(0).getName() + " resolves to multiple classifiers", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else {
+ // Then walks through the path, which shall contain only references to (nested) classifiers
+ List<EObject> nestedVisibleClassifiers ;
+ EObject previousClassifier = visibleClassifiers.get(0) ;
+ for (int i = 1 ; i<path.size() ; i++) {
+ nestedVisibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(previousClassifier).resolveByName(path.get(i).getName()) ;
+ if (nestedVisibleClassifiers.isEmpty()) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Could not resolve classifier " + path.get(i).getName(), path.get(i), AlfPackage.eINSTANCE.getUnqualifiedName_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else if (nestedVisibleClassifiers.size() > 1) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(i).getName() + " resolves to multiple classifiers", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ previousClassifier = nestedVisibleClassifiers.get(0) ;
+ }
+ // TODO : Check if this is reasonable => We make the assumption than the final id can only be a reference to an enumeration
+ if (previousClassifier instanceof Enumeration) {
+ List<EObject> visibleEnumerationLiterals = AlfScopeProvider.scopingTool.getVisibleEnumerationLiterals(previousClassifier).resolveByName(exp.getId()) ;
+ if (visibleEnumerationLiterals.isEmpty()) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Could not resolve enumeration literal " + exp.getId(), exp, AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else if (visibleEnumerationLiterals.size() > 1) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(exp.getId() + " resolves to multiple enumeration literals", exp, AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else {
+ return TypeExpressionFactory.eInstance.createTypeExpression(previousClassifier) ;
+ }
+ }
+ else {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(path.size()-1).getName() + " does not resolve to an enumeration", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ }
}
else if (visiblePackages.size() > 1) {
ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(0).getName() + " resolves to multiple packages", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
@@ -663,9 +730,54 @@ public class TypeUtils {
previousPackage = visiblePackages.get(0) ;
for (int i = 1 ; i<path.size() ; i++) {
nestedVisiblePackages = AlfScopeProvider.scopingTool.getVisiblePackages(previousPackage).resolveByName(path.get(i).getName()) ;
- if (nestedVisiblePackages.isEmpty()) {
- ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Could not resolve package " + path.get(i).getName(), path.get(i), AlfPackage.eINSTANCE.getUnqualifiedName_Name()) ;
- return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ if (nestedVisiblePackages.isEmpty()) {
+ // Try to find a classifier
+ List<EObject> visibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(exp).resolveByName(path.get(i).getName()) ;
+ if (visibleClassifiers.isEmpty()) {
+ // No classifier found
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Could not resolve package " + path.get(i).getName(), path.get(i), AlfPackage.eINSTANCE.getUnqualifiedName_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else if (visibleClassifiers.size() > 1) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(0).getName() + " resolves to multiple classifiers", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else {
+ // Then walks through the path, which shall contain only references to (nested) classifiers
+ List<EObject> nestedVisibleClassifiers ;
+ EObject previousClassifier = visibleClassifiers.get(0) ;
+ for (int j = i ; j<path.size() ; j++) {
+ nestedVisibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(previousClassifier).resolveByName(path.get(j).getName()) ;
+ if (nestedVisibleClassifiers.isEmpty()) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Could not resolve classifier " + path.get(j).getName(), path.get(j), AlfPackage.eINSTANCE.getUnqualifiedName_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else if (nestedVisibleClassifiers.size() > 1) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(j).getName() + " resolves to multiple classifiers", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ previousClassifier = nestedVisibleClassifiers.get(0) ;
+ }
+ // TODO : Check if this is reasonable => We make the assumption than the final id can only be a reference to an enumeration
+ if (previousClassifier instanceof Enumeration) {
+ List<EObject> visibleEnumerationLiterals = AlfScopeProvider.scopingTool.getVisibleEnumerationLiterals(previousClassifier).resolveByName(exp.getId()) ;
+ if (visibleEnumerationLiterals.isEmpty()) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Could not resolve enumeration literal " + exp.getId(), exp, AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else if (visibleEnumerationLiterals.size() > 1) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(exp.getId() + " resolves to multiple enumeration literals", exp, AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else {
+ return TypeExpressionFactory.eInstance.createTypeExpression(previousClassifier) ;
+ }
+ }
+ else {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(path.size()-1).getName() + " does not resolve to an enumeration", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ }
}
else if (nestedVisiblePackages.size() > 1) {
ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(i).getName() + " resolves to multiple packages", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
@@ -727,7 +839,7 @@ public class TypeUtils {
else if (visibleOperationOrBehaviors.size()>1) {
List<SignatureFacade> availableSignatures = new ArrayList<SignatureFacade>() ;
for (EObject operation : visibleOperationOrBehaviors) {
- availableSignatures.add(new SignatureFacade(operation)) ;
+ availableSignatures.add(SignatureFacadeFactory.eInstance.createSignatureFacade(operation)) ;
}
List<SignatureFacade> selectedSignatures = SignatureFacade.findNearestSignature(arguments, availableSignatures) ;
if (selectedSignatures.size() > 1) { // could not infer the actual operations even with type of arguments
@@ -759,7 +871,7 @@ public class TypeUtils {
}
}
else {
- SignatureFacade operationOrBehaviorSignature = new SignatureFacade(visibleOperationOrBehaviors.get(0)) ;
+ SignatureFacade operationOrBehaviorSignature = SignatureFacadeFactory.eInstance.createSignatureFacade(visibleOperationOrBehaviors.get(0)) ;
String argumentsAreCompatible = operationOrBehaviorSignature.isCompatibleWithMe(arguments, true) ;
if (! (argumentsAreCompatible.length() == 0)) {
ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
@@ -829,12 +941,14 @@ public class TypeUtils {
return typeOfPrefix ;
}
- public TypeExpression getTypeOfSuffixExpression(SuffixExpression exp, TypeExpression typeOfPrefix) {
+ public TypeExpression getTypeOfSuffixExpression(SuffixExpression exp, TypeExpression propagatedTypeOfPrefix) {
// TODO: Support all cases
EObject source = exp.eContainer() ;
EStructuralFeature containtFeature = exp.eContainingFeature() ;
///////////////////////////
+ TypeExpression typeOfPrefix = propagatedTypeOfPrefix ;
+
if (typeOfPrefix == null) {
String errorMessage = "Type of prefix is undefined. Could not validate suffix." ;
ErrorTypeFacade error =
@@ -848,7 +962,27 @@ public class TypeUtils {
return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
}
-
+ // If the of prefix is of multiplicity 1 and if it has an operation toSequence (i.e., it is a collection class)
+ // Then, depending on the kind of suffix, it may be necessary to propagate a sequence has the prefix type
+ if (typeOfPrefix.getMultiplicity().getUpperBound() == 1 &&
+ (exp instanceof SequenceOperationExpression ||
+ exp instanceof SelectOrRejectOperation
+ // || exp.getSuffix() instanceof ... TODO
+ )) {
+ Classifier actualPrefixType = typeOfPrefix.getTypeFacade().extractActualType() ;
+ if( actualPrefixType != null) {
+ Operation toSequenceOperation = null ;
+ for (int i = 0 ; i<actualPrefixType.getAllOperations().size() && toSequenceOperation == null ; i++) {
+ Operation o = actualPrefixType.getAllOperations().get(i) ;
+ if (o.getName().equals("toSequence"))
+ toSequenceOperation = o ;
+ }
+ if (toSequenceOperation != null) {
+ typeOfPrefix = TypeExpressionFactory.eInstance.createTypeExpression(toSequenceOperation.getReturnResult()) ;
+ }
+ }
+ }
+
if (exp instanceof ClassExtentExpression) {
// TODO
String errorMessage = "Class extent expressions are not supported in this version of the Alf editor" ;
@@ -873,10 +1007,7 @@ public class TypeUtils {
return getTypeOfSequenceExpansionExpression((SequenceExpansionExpression) exp, typeOfPrefix) ;
}
else if (exp instanceof SequenceOperationExpression) {
- String errorMessage = "Sequence operation expressions are not supported in this version of the Alf editor" ;
- ErrorTypeFacade unsupportedCase =
- TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
- return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ return getTypeOfSequenceOperationExpression((SequenceOperationExpression)exp, typeOfPrefix) ;
}
else {// exp instanceof SequenceReductionExpression
return getTypeOfSequenceReductionExpression((SequenceReductionExpression) exp, typeOfPrefix) ;
@@ -884,7 +1015,107 @@ public class TypeUtils {
}
public TypeExpression getTypeOfSequenceOperationExpression(SequenceOperationExpression exp, TypeExpression typeOfPrefix) {
- return typeOfPrefix ; // TODO
+
+ if (exp.getOperationName() == null) {
+ String errorMessage = "Sequence function is missing" ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, exp, AlfPackage.eINSTANCE.getSequenceOperationExpression_OperationName()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+
+ // first tries to resolve the behavior name
+ SignatureFacade s = null ;
+ TypeFacade cddBehaviorFacade = TypeFacadeFactory.eInstance.createVoidFacade(exp.getOperationName()) ;
+ if (cddBehaviorFacade instanceof ErrorTypeFacade) {
+ // the behavior has not been found using default strategies.
+ // Tries to find it in predefined collection functions
+ s = TypeUtils.predefinedCollectionFunctions.get(exp.getOperationName().getId()) ;
+ if (s == null) {
+ return TypeExpressionFactory.eInstance.createTypeExpression(cddBehaviorFacade) ;
+// EObject source = exp.eContainer() ;
+// EStructuralFeature containingFeature = exp.eContainingFeature() ;
+// String errorMessage = "Could not resolve collection function " + exp.getOperationName().getId() ;
+// ErrorTypeFacade unsupportedCase =
+// TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containingFeature) ;
+// return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+ }
+ else {
+ Classifier cddBehavior = cddBehaviorFacade.extractActualType() ;
+ if (! (cddBehavior instanceof Behavior)) {
+ String errorMessage = cddBehavior.getName() + " does not resolve to a Behavior" ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, exp, AlfPackage.eINSTANCE.getSequenceOperationExpression_OperationName()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+ else {
+ s = SignatureFacadeFactory.eInstance.createSignatureFacade(cddBehavior) ;
+ }
+ }
+
+ if (s.isATemplate()) {
+ // A binding needs to be done, with the type of the prefix as an actual.
+ Map<TemplateParameter, ParameterableElement> substitutions = new HashMap<TemplateParameter, ParameterableElement>() ;
+ for (TemplateParameter tp : ((TemplateableElement)s.getActualSignatureObject()).getOwnedTemplateSignature().getOwnedParameters()) {
+ substitutions.put(tp,typeOfPrefix.getTypeFacade().extractActualType()) ;
+ }
+ String sLabelInCaseOfErrorInBinding = "" + s.getLabel() ;
+ s = s.bindTemplate(substitutions) ;
+ if (s == null) { // a problem occurred with binding
+ EObject source = exp.eContainer() ;
+ EStructuralFeature containtFeature = exp.eContainingFeature() ;
+ String errorMessage = "Could not implicitly bind behavior " + sLabelInCaseOfErrorInBinding + " with actual parameter " + typeOfPrefix.getTypeFacade().getLabel() ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+ }
+
+ // The signature has been resolved.
+ // Needs to determine if this is a valid signature. i.e. must have its first parameter with direction in or inout, and multiplicity *
+ if (s.getParameters().isEmpty()) {
+ EObject source = exp.eContainer() ;
+ EStructuralFeature containtFeature = exp.eContainingFeature() ;
+ String errorMessage = "Invalid sequence function. Should at least one in or inout parameter with multiplicity *" ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+ Behavior sequenceFunction = (Behavior)s.getActualSignatureObject() ;
+ Parameter firstParameter = sequenceFunction.getOwnedParameters().get(0) ;
+ if (((firstParameter.getDirection()!= ParameterDirectionKind.IN_LITERAL) && (firstParameter.getDirection() != ParameterDirectionKind.INOUT_LITERAL)) ||
+ firstParameter.getUpper() != -1) {
+ EObject source = exp.eContainer() ;
+ EStructuralFeature containtFeature = exp.eContainingFeature() ;
+ String errorMessage = "Invalid sequence function. The first parameter should have direction in or inout, with multiplicity *" ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+ // Then determines if arguments match parameters of the signature
+ List<TypeExpression> arguments = new ArrayList<TypeExpression>() ;
+ arguments.add(typeOfPrefix) ;
+ for (TupleElement e : exp.getTuple().getTupleElements()) {
+ TypeExpression argType = getTypeOfExpression(e.getArgument()) ;
+ if (argType.getTypeFacade() != null && argType.getTypeFacade() instanceof ErrorTypeFacade)
+ return argType ;
+ arguments.add(argType) ;
+ }
+ String argumentsAreCompatible = s.isCompatibleWithMe(arguments, true) ;
+ if (! (argumentsAreCompatible.length() == 0)) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ argumentsAreCompatible,
+ exp,
+ AlfPackage.eINSTANCE.getSequenceOperationExpression_OperationName()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ TypeExpression typeOfSuffix = s.getReturnType() ;
+
+ if (exp.getSuffix() != null) {
+ return this.getTypeOfSuffixExpression(exp.getSuffix(), typeOfSuffix) ;
+ }
+
+ return typeOfSuffix ;
}
public TypeExpression getTypeOfSequenceReductionExpression(SequenceReductionExpression exp, TypeExpression typeOfPrefix) {
@@ -1293,7 +1524,7 @@ public class TypeUtils {
else if (matchingOperations.size() > 1) {
List<SignatureFacade> availableSignatures = new ArrayList<SignatureFacade>() ;
for (EObject operation : matchingOperations) {
- availableSignatures.add(new SignatureFacade(operation)) ;
+ availableSignatures.add(SignatureFacadeFactory.eInstance.createSignatureFacade(operation)) ;
}
List<SignatureFacade> selectedSignatures = SignatureFacade.findNearestSignature(arguments, availableSignatures) ;
if (selectedSignatures.size() > 1) { // could not infer the actual operations even with type of arguments
@@ -1425,5 +1656,148 @@ public class TypeUtils {
}
return mostGeneral ;
}
+
+ public TypeExpression getTypeOfCandidateExpression(EObject exp) {
+ // EObject cddExpression = o ;
+ if (exp instanceof Tuple)
+ return getTypeOfCandidateExpression(exp.eContainer()) ;
+ else if (exp instanceof Expression)
+ return getTypeOfExpression((Expression) exp) ;
+ else if (exp instanceof ConditionalTestExpression)
+ return getTypeOfConditionalTestExpression((ConditionalTestExpression)exp) ;
+ else if (exp instanceof ConditionalOrExpression)
+ return getTypeOfConditionalOrExpression((ConditionalOrExpression) exp) ;
+ else if (exp instanceof ConditionalAndExpression)
+ return getTypeOfConditionalAndExpression((ConditionalAndExpression) exp) ;
+ else if (exp instanceof InclusiveOrExpression)
+ return getTypeOfInclusiveOrExpression((InclusiveOrExpression) exp) ;
+ else if (exp instanceof ExclusiveOrExpression)
+ return getTypeOfExclusiveOrExpression((ExclusiveOrExpression) exp) ;
+ else if (exp instanceof AndExpression)
+ return getTypeOfAndExpression((AndExpression) exp) ;
+ else if (exp instanceof EqualityExpression)
+ return getTypeOfEqualityExpression((EqualityExpression) exp) ;
+ else if (exp instanceof ClassificationExpression)
+ return getTypeOfClassificationExpression((ClassificationExpression) exp) ;
+ else if (exp instanceof RelationalExpression)
+ return getTypeOfRelationalExpression((RelationalExpression) exp) ;
+ else if (exp instanceof ShiftExpression)
+ return getTypeOfShiftExpression((ShiftExpression) exp) ;
+ else if (exp instanceof AdditiveExpression)
+ return getTypeOfAdditiveExpression((AdditiveExpression) exp) ;
+ else if (exp instanceof MultiplicativeExpression)
+ return getTypeOfMultiplicativeExpression((MultiplicativeExpression) exp) ;
+ else if (exp instanceof UnaryExpression)
+ return getTypeOfUnaryExpression((UnaryExpression) exp) ;
+ else if (exp instanceof PrimaryExpression)
+ return getTypeOfPrimaryExpression((PrimaryExpression) exp) ;
+ else if (exp instanceof ValueSpecification)
+ return getTypeOfValueSpecification((ValueSpecification)exp) ;
+ else if (exp instanceof NullExpression)
+ return getTypeOfNullExpression((NullExpression) exp) ;
+ else if (exp instanceof InstanceCreationExpression)
+ return getTypeOfInstanceCreationExpression((InstanceCreationExpression) exp) ;
+ else if (exp instanceof SuperInvocationExpression)
+ return getTypeOfSuperInvocationExpression((SuperInvocationExpression) exp) ;
+ else if (exp instanceof NonLiteralValueSpecification)
+ return getTypeOfNonLiteralValueSpecification((NonLiteralValueSpecification) exp) ;
+ else if (exp instanceof LITERAL)
+ return getTypeOfLITERAL((LITERAL) exp) ;
+ else if (exp instanceof ParenthesizedExpression)
+ return getTypeOfParenthesizedExpression((ParenthesizedExpression) exp) ;
+ else if (exp instanceof NameExpression)
+ return getTypeOfNameExpression((NameExpression) exp) ;
+ else if (exp instanceof ThisExpression)
+ return getTypeOfThisExpression((ThisExpression) exp) ;
+ else if (exp instanceof SequenceOperationExpression) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfSequenceOperationExpression((SequenceOperationExpression) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof SequenceReductionExpression) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfSequenceReductionExpression((SequenceReductionExpression) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof SequenceExpansionExpression) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfSequenceExpansionExpression((SequenceExpansionExpression) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof IsUniqueOperation) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfIsUniqueOperation((IsUniqueOperation) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof ForAllOrExistsOrOneOperation) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfForAllOrExistsOrOneOperation((ForAllOrExistsOrOneOperation) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof CollectOrIterateOperation) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfCollectOrIterateOperation((CollectOrIterateOperation) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof SelectOrRejectOperation) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfSelectOrRejectOperation((SelectOrRejectOperation) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof PropertyCallExpression) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfPropertyCallExpression((PropertyCallExpression) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof OperationCallExpression) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfOperationCallExpression((OperationCallExpression) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof SequenceElement)
+ return getTypeOfSequenceElement ((SequenceElement) exp) ;
+ else if (exp instanceof SequenceConstructionExpression)
+ return getTypeOfSequenceConstructionExpression ((SequenceConstructionExpression) exp) ;
+
+ String errorMessage = "Not an expression." ;
+ TypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, exp, null) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
}

Back to the top