Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcbrun2015-03-13 10:23:44 +0000
committerMaxime Porhel2015-04-01 07:44:36 +0000
commit42e2eeba1f01807245db88e33cab22eeb9f812e1 (patch)
tree8e6c321c73848ba6befb14e686d281059ca9c81c
parentd39750524bf8affd349564ab18c0a4fa237f8aff (diff)
downloadorg.eclipse.sirius-42e2eeba1f01807245db88e33cab22eeb9f812e1.tar.gz
org.eclipse.sirius-42e2eeba1f01807245db88e33cab22eeb9f812e1.tar.xz
org.eclipse.sirius-42e2eeba1f01807245db88e33cab22eeb9f812e1.zip
[462481] Introduce VariableType and use it in APIs and VSM Validation
This commit adds the concept of a VariableType which can be defined by a list of type names (which are essentially Strings which can be matched back to EClassifier instances). This does not add more semantic than what was already existing and -- at least partially -- supported, but the notion of TypeName is introduced too in the Java code to avoid manipulating plain Strings. A return type can then be provided by an IInterpreter which implements the TypedValidation interface, this interface has been added instead of adapting the current IInterpreter interface to avoid breaking the compatibility with older IInterpreter implementations. The type of *self* is refined when the ModelOperations of a tool are being analyzed. Bug: 462481 Change-Id: Ifb0acadaca399b47712b9924a88044767f72f4bd Signed-off-by: Cedric Brun <cedric.brun@obeo.fr>
-rw-r--r--plugins/org.eclipse.sirius.common.acceleo.aql/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.sirius.common.acceleo.aql/src/org/eclipse/sirius/common/acceleo/aql/business/api/TypesUtil.java36
-rw-r--r--plugins/org.eclipse.sirius.common.acceleo.aql/src/org/eclipse/sirius/common/acceleo/aql/business/internal/AQLSiriusInterpreter.java56
-rw-r--r--plugins/org.eclipse.sirius.common.acceleo.mtl.ide/src/org/eclipse/sirius/common/acceleo/mtl/ide/AcceleoProposalProvider.java49
-rw-r--r--plugins/org.eclipse.sirius.common.acceleo.mtl/src/org/eclipse/sirius/common/acceleo/mtl/business/internal/interpreter/AcceleoMTLInterpreter.java124
-rw-r--r--plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/FeatureProposalProvider.java26
-rw-r--r--plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/VariableProposalProvider.java85
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/CompoundInterpreter.java21
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/DefaultInterpreterContextFactory.java5
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/IInterpreterContext.java20
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/IInterpreterStatus.java4
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/InterpreterStatusFactory.java61
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/TypeName.java202
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/TypedValidation.java40
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/ValidationResult.java78
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/VariableType.java154
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/AbstractInterpreter.java5
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/FeatureInterpreter.java76
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/InterpretedContextImpl.java29
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/InterpreterStatusImpl.java10
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/ServiceInterpreter.java8
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/VariableInterpreter.java26
-rw-r--r--plugins/org.eclipse.sirius.diagram/src-core/org/eclipse/sirius/diagram/business/internal/dialect/description/DiagramInterpretedExpressionQuery.java153
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/Release Notes.html30
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/Release Notes.textile7
-rw-r--r--plugins/org.eclipse.sirius.table/src/org/eclipse/sirius/table/business/internal/dialect/description/TableInterpretedExpressionQuery.java3
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/api/interpreter/CompletionTests.java6
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/AbstractCompletionTestCase.java18
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/mtl/AcceleoMTLCompletionTests.java16
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/service/ServiceProposalProviderTests.java3
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/variable/VariableInterpreterTests.java3
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/variable/VariableProposalProviderTests.java19
-rw-r--r--plugins/org.eclipse.sirius.tree/src/org/eclipse/sirius/tree/business/internal/dialect/description/TreeInterpretedExpressionQuery.java3
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java187
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/IInterpretedExpressionQuery.java3
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/api/interpreter/context/SiriusInterpreterContextFactory.java10
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/interpreter/ODesignGenericInterpreter.java4
37 files changed, 1236 insertions, 347 deletions
diff --git a/plugins/org.eclipse.sirius.common.acceleo.aql/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.common.acceleo.aql/META-INF/MANIFEST.MF
index 1be8ff9001..8fd7f4d857 100644
--- a/plugins/org.eclipse.sirius.common.acceleo.aql/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.common.acceleo.aql/META-INF/MANIFEST.MF
@@ -11,7 +11,8 @@ Require-Bundle: org.eclipse.acceleo.query;bundle-version="3.5.0",
org.eclipse.core.runtime;bundle-version="3.4.0",
com.google.guava;bundle-version="[11.0.2,16.0)",
org.eclipse.sirius.ecore.extender;bundle-version="2.0.0",
- org.eclipse.emf.ecore;bundle-version="2.8.0"
+ org.eclipse.emf.ecore;bundle-version="2.8.0",
+ org.eclipse.sirius.ext.base;bundle-version="3.0.0"
Export-Package: org.eclipse.sirius.common.acceleo.aql.business.api,
org.eclipse.sirius.common.acceleo.aql.business.internal
Bundle-Localization: plugin
diff --git a/plugins/org.eclipse.sirius.common.acceleo.aql/src/org/eclipse/sirius/common/acceleo/aql/business/api/TypesUtil.java b/plugins/org.eclipse.sirius.common.acceleo.aql/src/org/eclipse/sirius/common/acceleo/aql/business/api/TypesUtil.java
index 5b8d632d95..2479fd31ca 100644
--- a/plugins/org.eclipse.sirius.common.acceleo.aql/src/org/eclipse/sirius/common/acceleo/aql/business/api/TypesUtil.java
+++ b/plugins/org.eclipse.sirius.common.acceleo.aql/src/org/eclipse/sirius/common/acceleo/aql/business/api/TypesUtil.java
@@ -23,6 +23,8 @@ import org.eclipse.acceleo.query.validation.type.IType;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
+import org.eclipse.sirius.common.tools.api.interpreter.TypeName;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
/**
* An utility class to convert types denotations.
@@ -49,40 +51,44 @@ public final class TypesUtil {
public static Map<String, Set<IType>> createAQLVariableTypesFromInterpreterContext(IInterpreterContext context, IQueryEnvironment queryEnvironment) {
Map<String, Set<IType>> variableTypes = new LinkedHashMap<String, Set<IType>>();
final Set<IType> selfTyping = new LinkedHashSet<IType>(2);
- for (String targetTypeName : context.getTargetTypes()) {
- EClassifierType found = searchEClassifierType(queryEnvironment, targetTypeName);
+ VariableType targetTypeName = context.getTargetType();
+ for (TypeName possibleType : targetTypeName.getPossibleTypes()) {
+ EClassifierType found = searchEClassifierType(queryEnvironment, possibleType);
if (found != null) {
selfTyping.add(found);
}
-
}
+
if (selfTyping.size() == 0) {
selfTyping.add(new ClassType(queryEnvironment, EObject.class));
}
variableTypes.put("self", selfTyping);
- for (Entry<String, String> varDef : context.getVariables().entrySet()) {
- String typeName = varDef.getValue();
- if (typeName != null) {
- EClassifierType found = searchEClassifierType(queryEnvironment, typeName);
+
+ for (Entry<String, VariableType> varDef : context.getVariables().entrySet()) {
+ VariableType typeName = varDef.getValue();
+ final Set<IType> potentialTypes = new LinkedHashSet<IType>(2);
+ for (TypeName possibleVariableTypes : typeName.getPossibleTypes()) {
+ EClassifierType found = searchEClassifierType(queryEnvironment, possibleVariableTypes);
if (found != null) {
- final Set<IType> potentialTypes = new LinkedHashSet<IType>(2);
potentialTypes.add(found);
- variableTypes.put(varDef.getKey(), potentialTypes);
}
}
+ if (potentialTypes.size() == 0) {
+ potentialTypes.add(new ClassType(queryEnvironment, EObject.class));
+ }
+ variableTypes.put(varDef.getKey(), potentialTypes);
}
return variableTypes;
}
- private static EClassifierType searchEClassifierType(IQueryEnvironment queryEnvironment, String targetTypeName) {
+ private static EClassifierType searchEClassifierType(IQueryEnvironment queryEnvironment, TypeName targetTypeName) {
EClassifier found = null;
- int separatorPosition = targetTypeName.indexOf('.');
- if (separatorPosition > -1) {
- String typeName = targetTypeName.substring(separatorPosition + 1);
- String nsPrefix = targetTypeName.substring(0, separatorPosition);
+ if (targetTypeName.getPackagePrefix().some()) {
+ String typeName = targetTypeName.getClassifierName();
+ String nsPrefix = targetTypeName.getPackagePrefix().get();
found = queryEnvironment.getEPackageProvider().getType(nsPrefix, typeName);
} else {
- found = queryEnvironment.getEPackageProvider().getType(targetTypeName);
+ found = queryEnvironment.getEPackageProvider().getType(targetTypeName.getClassifierName());
}
if (found != null) {
return new EClassifierType(queryEnvironment, found);
diff --git a/plugins/org.eclipse.sirius.common.acceleo.aql/src/org/eclipse/sirius/common/acceleo/aql/business/internal/AQLSiriusInterpreter.java b/plugins/org.eclipse.sirius.common.acceleo.aql/src/org/eclipse/sirius/common/acceleo/aql/business/internal/AQLSiriusInterpreter.java
index 0d7dbaafd1..78baef0c6d 100644
--- a/plugins/org.eclipse.sirius.common.acceleo.aql/src/org/eclipse/sirius/common/acceleo/aql/business/internal/AQLSiriusInterpreter.java
+++ b/plugins/org.eclipse.sirius.common.acceleo.aql/src/org/eclipse/sirius/common/acceleo/aql/business/internal/AQLSiriusInterpreter.java
@@ -40,9 +40,11 @@ import org.eclipse.acceleo.query.runtime.impl.Nothing;
import org.eclipse.acceleo.query.runtime.impl.QueryBuilderEngine;
import org.eclipse.acceleo.query.runtime.impl.QueryEnvironment;
import org.eclipse.acceleo.query.runtime.impl.QueryValidationEngine;
+import org.eclipse.acceleo.query.validation.type.EClassifierType;
import org.eclipse.acceleo.query.validation.type.IType;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EPackage.Registry;
@@ -58,6 +60,8 @@ import org.eclipse.sirius.common.tools.api.interpreter.EvaluationException;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterStatus;
import org.eclipse.sirius.common.tools.api.interpreter.InterpreterStatusFactory;
+import org.eclipse.sirius.common.tools.api.interpreter.ValidationResult;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.ecore.extender.business.api.accessor.EcoreMetamodelDescriptor;
import org.eclipse.sirius.ecore.extender.business.api.accessor.MetamodelDescriptor;
import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
@@ -216,9 +220,25 @@ public class AQLSiriusInterpreter extends AcceleoAbstractInterpreter {
}
@Override
- public Collection<IInterpreterStatus> validateExpression(IInterpreterContext context, String fullExpression) {
+ public ValidationResult analyzeExpression(IInterpreterContext context, String fullExpression) {
+
+ /*
+ * use the VSM resource to declare dependent project/bundles.
+ */
+ EObject vsmElement = context.getElement();
+ if (vsmElement.eResource() != null && vsmElement.eResource().getURI() != null && vsmElement.eResource().getURI().segmentCount() >= 2) {
+ URI vsmURI = vsmElement.eResource().getURI();
+ String bundleOrProjectName = vsmURI.segment(1);
+ if (vsmURI.isPlatformResource()) {
+ javaExtensions.updateScope(Sets.<String> newHashSet(), Sets.newHashSet(bundleOrProjectName));
+ } else if (vsmURI.isPlatformPlugin()) {
+ javaExtensions.updateScope(Sets.newHashSet(bundleOrProjectName), Sets.<String> newHashSet());
+ }
+ }
+
String trimmedExpression = new ExpressionTrimmer(fullExpression).getExpression();
+ ValidationResult result = new ValidationResult();
for (EPackage pak : context.getAvailableEPackages()) {
if (pak != null) {
queryEnvironment.registerEPackage(pak);
@@ -226,25 +246,37 @@ public class AQLSiriusInterpreter extends AcceleoAbstractInterpreter {
}
Map<String, Set<IType>> variableTypes = TypesUtil.createAQLVariableTypesFromInterpreterContext(context, queryEnvironment);
- List<IInterpreterStatus> statuses = Lists.newArrayList();
+ for (String dependency : context.getDependencies()) {
+ addImport(dependency);
+ }
QueryValidationEngine validator = new QueryValidationEngine(this.queryEnvironment);
try {
IValidationResult validationResult = validator.validate(trimmedExpression, variableTypes);
for (IValidationMessage message : validationResult.getMessages()) {
- IInterpreterStatus status = InterpreterStatusFactory.createInterpreterStatus(context, IInterpreterStatus.WARNING, message.getMessage());
- statuses.add(status);
+ result.addStatus(InterpreterStatusFactory.createInterpreterStatus(context, IInterpreterStatus.WARNING, message.getMessage()));
+ }
+ List<String> classifierNames = Lists.newArrayList();
+ for (IType type : validationResult.getPossibleTypes(validationResult.getAstResult().getAst())) {
+ if (type instanceof EClassifierType) {
+ EClassifierType eClassifierType = (EClassifierType) type;
+ if (eClassifierType.getType() != null && eClassifierType.getType().getName() != null) {
+ String typeName = eClassifierType.getType().getName();
+ if (eClassifierType.getType().getEPackage() != null && eClassifierType.getType().getEPackage().getName() != null) {
+ typeName = eClassifierType.getType().getEPackage().getName() + "." + typeName;
+ }
+ classifierNames.add(typeName);
+ }
+ }
+ result.setReturnType(VariableType.fromStrings(classifierNames));
}
} catch (AcceleoQueryValidationException e) {
- statuses.add(InterpreterStatusFactory.createInterpreterStatus(context, IInterpreterStatus.ERROR, e.getMessage()));
- AQLSiriusPlugin.getPlugin().log(new Status(IStatus.ERROR, AQLSiriusPlugin.getPlugin().getSymbolicName(), e.getMessage(), e));
+ result.addStatus(InterpreterStatusFactory.createInterpreterStatus(context, IInterpreterStatus.ERROR, e.getMessage()));
+ AQLSiriusPlugin.INSTANCE.log(new Status(IStatus.ERROR, AQLSiriusPlugin.INSTANCE.getSymbolicName(), e.getMessage(), e));
} catch (AcceleoQueryEvaluationException e) {
- statuses.add(InterpreterStatusFactory.createInterpreterStatus(context, IInterpreterStatus.ERROR, e.getMessage()));
+ result.addStatus(InterpreterStatusFactory.createInterpreterStatus(context, IInterpreterStatus.ERROR, e.getMessage()));
}
- if (statuses.size() == 0) {
- // TODO check the return type of the expression matches or will be
- // adapted to the expected type
- }
- return statuses;
+
+ return result;
}
/**
diff --git a/plugins/org.eclipse.sirius.common.acceleo.mtl.ide/src/org/eclipse/sirius/common/acceleo/mtl/ide/AcceleoProposalProvider.java b/plugins/org.eclipse.sirius.common.acceleo.mtl.ide/src/org/eclipse/sirius/common/acceleo/mtl/ide/AcceleoProposalProvider.java
index 9a931fa40c..23e1f25da7 100644
--- a/plugins/org.eclipse.sirius.common.acceleo.mtl.ide/src/org/eclipse/sirius/common/acceleo/mtl/ide/AcceleoProposalProvider.java
+++ b/plugins/org.eclipse.sirius.common.acceleo.mtl.ide/src/org/eclipse/sirius/common/acceleo/mtl/ide/AcceleoProposalProvider.java
@@ -10,6 +10,14 @@
*******************************************************************************/
package org.eclipse.sirius.common.acceleo.mtl.ide;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.acceleo.common.IAcceleoConstants;
+import org.eclipse.acceleo.parser.interpreter.CompilationContext;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
import org.eclipse.sirius.common.acceleo.mtl.business.internal.interpreter.AcceleoMTLInterpreter;
import org.eclipse.sirius.common.acceleo.mtl.business.internal.interpreter.DynamicAcceleoModule;
import org.eclipse.sirius.common.acceleo.mtl.business.internal.interpreter.DynamicAcceleoModule.QueryIdentifier;
@@ -19,20 +27,12 @@ import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
import org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.common.tools.api.util.StringUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.acceleo.common.IAcceleoConstants;
-import org.eclipse.acceleo.parser.interpreter.CompilationContext;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EObject;
-
/**
* This implementation of the {@link IProposalProvider} interface will be used
* in order to provide completion for Acceleo 3 expressions.
@@ -54,24 +54,6 @@ public class AcceleoProposalProvider implements IProposalProvider {
*/
private static final String ACCELEO_EXPRESSION_SUFFIX = IAcceleoConstants.DEFAULT_END_BODY_CHAR + IAcceleoConstants.DEFAULT_END;
- /**
- * This will be used to convert a Java-style qualified name
- * (my.package.Type) to an OCL-style qualified name (my::package::Type).
- * <p>
- * Note that this will make no effort to try and check whether the given
- * type is indeed a Java qualified name.
- * </p>
- *
- * @param type
- * The type we are to convert.
- * @return The OCL qualified name corresponding to the given type.
- */
- private static String convertToOCLQualifiedName(String type) {
- if (type != null && type.length() > 0) {
- return type.replace(".", IAcceleoConstants.NAMESPACE_SEPARATOR); //$NON-NLS-1$
- }
- return type;
- }
/**
* {@inheritDoc}
@@ -100,24 +82,25 @@ public class AcceleoProposalProvider implements IProposalProvider {
final IInterpreterContext interpreterContext = context.getInterpreterContext();
final Map<String, String> validationVariables = Maps.newLinkedHashMap();
- for (Map.Entry<String, String> contextVariable : interpreterContext.getVariables().entrySet()) {
+ for (Map.Entry<String, VariableType> contextVariable : interpreterContext.getVariables().entrySet()) {
final String varName = contextVariable.getKey();
- final String varType = contextVariable.getValue();
- if (varName != null && varName.length() > 0 && varType != null && varType.length() > 0) {
+ final VariableType varType = contextVariable.getValue();
+ if (varName != null && varName.length() > 0 && varType.hasDefinition()) {
if (varName.matches("[0-9]+")) { //$NON-NLS-1$
// Ignore old Acceleo 2 style numeric variables used for
// direct edit tools.
continue;
}
- validationVariables.put(varName, convertToOCLQualifiedName(varType));
+ validationVariables.put(varName, varType.getCommonType(context.getInterpreterContext().getAvailableEPackages()).getCompleteName(IAcceleoConstants.NAMESPACE_SEPARATOR));
}
}
final String targetType;
+ VariableType selfType = interpreterContext.getTargetType();
if (!interpreterContext.requiresTargetType()) {
targetType = "ecore::EObject"; //$NON-NLS-1$
- } else if (!interpreterContext.getTargetTypes().isEmpty()) {
- targetType = convertToOCLQualifiedName(interpreterContext.getTargetTypes().iterator().next());
+ } else if (selfType.hasDefinition()) {
+ targetType = interpreterContext.getTargetType().getCommonType(context.getInterpreterContext().getAvailableEPackages()).getCompleteName(IAcceleoConstants.NAMESPACE_SEPARATOR);
} else {
targetType = null;
}
diff --git a/plugins/org.eclipse.sirius.common.acceleo.mtl/src/org/eclipse/sirius/common/acceleo/mtl/business/internal/interpreter/AcceleoMTLInterpreter.java b/plugins/org.eclipse.sirius.common.acceleo.mtl/src/org/eclipse/sirius/common/acceleo/mtl/business/internal/interpreter/AcceleoMTLInterpreter.java
index 0ffe9179f7..b4c3d73836 100644
--- a/plugins/org.eclipse.sirius.common.acceleo.mtl/src/org/eclipse/sirius/common/acceleo/mtl/business/internal/interpreter/AcceleoMTLInterpreter.java
+++ b/plugins/org.eclipse.sirius.common.acceleo.mtl/src/org/eclipse/sirius/common/acceleo/mtl/business/internal/interpreter/AcceleoMTLInterpreter.java
@@ -71,13 +71,16 @@ import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterStatus;
import org.eclipse.sirius.common.tools.api.interpreter.IVariableStatusListener;
import org.eclipse.sirius.common.tools.api.interpreter.InterpreterStatusFactory;
+import org.eclipse.sirius.common.tools.api.interpreter.TypeName;
+import org.eclipse.sirius.common.tools.api.interpreter.TypedValidation;
+import org.eclipse.sirius.common.tools.api.interpreter.ValidationResult;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.ecore.extender.business.api.accessor.EcoreMetamodelDescriptor;
import org.eclipse.sirius.ecore.extender.business.api.accessor.MetamodelDescriptor;
import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
import org.osgi.framework.Bundle;
import com.google.common.base.Joiner;
-import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.ListMultimap;
@@ -91,7 +94,7 @@ import com.google.common.collect.Sets;
*
* @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
*/
-public class AcceleoMTLInterpreter implements IInterpreter {
+public class AcceleoMTLInterpreter implements IInterpreter, TypedValidation {
/**
* This represents the prefix of an Acceleo 3 expression.
*
@@ -208,25 +211,6 @@ public class AcceleoMTLInterpreter implements IInterpreter {
}
/**
- * This will be used to convert a Java-style qualified name
- * (my.package.Type) to an OCL-style qualified name (my::package::Type).
- * <p>
- * Note that this will make no effort to try and check whether the given
- * type is indeed a Java qualified name.
- * </p>
- *
- * @param type
- * The type we are to convert.
- * @return The OCL qualified name corresponding to the given type.
- */
- private static String convertToOCLQualifiedName(String type) {
- if (type != null && type.length() > 0) {
- return type.replace(".", IAcceleoConstants.NAMESPACE_SEPARATOR); //$NON-NLS-1$
- }
- return type;
- }
-
- /**
* Checks whether the given path exists in the plugins.
*
* @param path
@@ -906,53 +890,7 @@ public class AcceleoMTLInterpreter implements IInterpreter {
* java.lang.String)
*/
public Collection<IInterpreterStatus> validateExpression(IInterpreterContext context, String expression) {
- /*
- * The interpreter is created as a global singleton : one single
- * interpreter for all operations, whatever the number of VSM or
- * representation files. Validation is called on expression granularity,
- * and we are never warned of the validation "start" or "end" events. We
- * thus cannot keep any state for the in-memory module as it could be
- * reflecting operations located on other VSM files.
- */
- invalidateModule();
-
- final Set<IInterpreterStatus> validationStatus = Sets.newLinkedHashSet();
-
- final Map<String, String> validationVariables = Maps.newLinkedHashMap();
- for (Map.Entry<String, String> contextVariable : context.getVariables().entrySet()) {
- final String varName = contextVariable.getKey();
- final String varType = contextVariable.getValue();
- boolean isVarNameValid = varName != null && varName.length() > 0 && !varName.matches("[0-9]+"); //$NON-NLS-1$
- boolean isVarTypeValid = varType != null && varType.length() > 0;
- if (isVarNameValid && isVarTypeValid) {
- validationVariables.put(varName, convertToOCLQualifiedName(varType));
- }
- }
-
- if (!context.requiresTargetType()) {
- final CompilationContext compilationContext = createCompilationContext(context, expression, "ecore::EObject", validationVariables); //$NON-NLS-1$
- validationStatus.addAll(doValidateExpression(context, compilationContext));
- } else {
- final Collection<String> actualTargetTypes = Lists.newArrayListWithCapacity(context.getTargetTypes().size());
- for (String candidateType : context.getTargetTypes()) {
- if (!Strings.isNullOrEmpty(candidateType)) {
- actualTargetTypes.add(candidateType);
- }
- }
- if (actualTargetTypes.isEmpty()) {
- validationStatus.add(InterpreterStatusFactory.createInterpreterStatus(context.getTargetTypes(), context.getField(), IInterpreterStatus.WARNING, "Cannot find Domain Class for " //$NON-NLS-1$
- + context.getField().getName() + " - Expression cannot be validated.")); //$NON-NLS-1$
- } else {
- for (String candidateTargetType : actualTargetTypes) {
- final String expressionType = convertToOCLQualifiedName(candidateTargetType);
-
- final CompilationContext compilationContext = createCompilationContext(context, expression, expressionType, validationVariables);
- validationStatus.addAll(doValidateExpression(context, compilationContext));
- }
- }
- }
-
- return validationStatus;
+ return analyzeExpression(context, expression).getStatuses();
}
/**
@@ -1076,7 +1014,7 @@ public class AcceleoMTLInterpreter implements IInterpreter {
if (compilationResult.getStatus() != null && compilationResult.getStatus().getSeverity() != IStatus.OK) {
if (compilationResult.getStatus() instanceof MultiStatus) {
for (IStatus child : ((MultiStatus) compilationResult.getStatus()).getChildren()) {
- final String type = compilationContext.getTargetType();
+ final VariableType type = VariableType.fromString(compilationContext.getTargetType());
final String severity;
if (child.getSeverity() == IStatus.ERROR) {
severity = IInterpreterStatus.ERROR;
@@ -1088,7 +1026,7 @@ public class AcceleoMTLInterpreter implements IInterpreter {
severity = IInterpreterStatus.WARNING;
}
- validationStatus.add(InterpreterStatusFactory.createInterpreterStatus(Collections.singleton(type), context.getField(), severity, child.getMessage(), 0, 0, 0));
+ validationStatus.add(InterpreterStatusFactory.createInterpreterStatus(type, context.getField(), severity, child.getMessage(), 0, 0, 0));
}
}
}
@@ -1258,4 +1196,50 @@ public class AcceleoMTLInterpreter implements IInterpreter {
}
}
+ @Override
+ public ValidationResult analyzeExpression(IInterpreterContext context, String expression) {
+ /*
+ * The interpreter is created as a global singleton : one single
+ * interpreter for all operations, whatever the number of VSM or
+ * representation files. Validation is called on expression granularity,
+ * and we are never warned of the validation "start" or "end" events. We
+ * thus cannot keep any state for the in-memory module as it could be
+ * reflecting operations located on other VSM files.
+ */
+ invalidateModule();
+
+ ValidationResult result = new ValidationResult();
+
+ final Map<String, String> validationVariables = Maps.newLinkedHashMap();
+ for (Map.Entry<String, VariableType> contextVariable : context.getVariables().entrySet()) {
+ final String varName = contextVariable.getKey();
+ final VariableType varType = contextVariable.getValue();
+ boolean isVarNameValid = varName != null && varName.length() > 0 && !varName.matches("[0-9]+"); //$NON-NLS-1$
+ boolean isVarTypeValid = varType.hasDefinition();
+ if (isVarNameValid && isVarTypeValid) {
+ validationVariables.put(varName, varType.getCommonType(context.getAvailableEPackages()).getCompleteName(IAcceleoConstants.NAMESPACE_SEPARATOR));
+ }
+ }
+
+ if (!context.requiresTargetType()) {
+ final CompilationContext compilationContext = createCompilationContext(context, expression, "ecore::EObject", validationVariables); //$NON-NLS-1$
+ result.addAllStatus(doValidateExpression(context, compilationContext));
+ } else {
+
+ VariableType candidateType = context.getTargetType();
+ if (!candidateType.hasDefinition()) {
+ result.addStatus(InterpreterStatusFactory.createInterpreterStatus(context.getTargetType(), context.getField(), IInterpreterStatus.WARNING, "Cannot find Domain Class for " //$NON-NLS-1$
+ + context.getField().getName() + " - Expression cannot be validated.")); //$NON-NLS-1$
+ } else {
+ for (TypeName candidateTargetType : candidateType.getPossibleTypes()) {
+ final String expressionType = candidateTargetType.getCompleteName(IAcceleoConstants.NAMESPACE_SEPARATOR);
+
+ final CompilationContext compilationContext = createCompilationContext(context, expression, expressionType, validationVariables);
+ result.addAllStatus(doValidateExpression(context, compilationContext));
+ }
+ }
+ }
+ return result;
+ }
+
}
diff --git a/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/FeatureProposalProvider.java b/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/FeatureProposalProvider.java
index 0c283ece0d..65f9996d4d 100644
--- a/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/FeatureProposalProvider.java
+++ b/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/FeatureProposalProvider.java
@@ -13,6 +13,7 @@ package org.eclipse.sirius.common.ui.tools.internal.interpreter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
@@ -23,8 +24,13 @@ import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
import org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
+import org.eclipse.sirius.common.tools.api.interpreter.TypeName;
import org.eclipse.sirius.common.tools.internal.interpreter.FeatureInterpreter;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
/**
* A {@link IProposalProvider} to provide completion for the feature
* interpreter.
@@ -56,10 +62,24 @@ public class FeatureProposalProvider implements IProposalProvider {
} else if (context.getContents() == null || context.getContents().length() == 0) {
proposals = Collections.singletonList(getNewEmtpyExpression());
} else {
- FeatureInterpreter featureInterpreter = (FeatureInterpreter) interpreter;
+ Set<ContentProposal> intersectingProposals = null;
IInterpreterContext interpreterContext = context.getInterpreterContext();
- EClass currentElementType = featureInterpreter.getCurrentElementType(interpreterContext);
- proposals = getProposals(context.getContents(), context.getPosition(), currentElementType);
+ for (TypeName type : interpreterContext.getTargetType().getPossibleTypes()) {
+ for (EClass possibleEClass : Iterables.filter(type.search(interpreterContext.getAvailableEPackages()), EClass.class)) {
+ Set<ContentProposal> proposalsForThisType = Sets.newLinkedHashSet(getProposals(context.getContents(), context.getPosition(), possibleEClass));
+ if (intersectingProposals == null) {
+ intersectingProposals = proposalsForThisType;
+ } else {
+ intersectingProposals = Sets.intersection(intersectingProposals, proposalsForThisType);
+ }
+ }
+ }
+
+ if (intersectingProposals != null) {
+ proposals = Lists.newArrayList(intersectingProposals);
+ } else {
+ proposals = Collections.<ContentProposal> emptyList();
+ }
}
return proposals;
}
diff --git a/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/VariableProposalProvider.java b/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/VariableProposalProvider.java
index 9cfb6aa3e1..ef27fe0a37 100644
--- a/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/VariableProposalProvider.java
+++ b/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/VariableProposalProvider.java
@@ -22,6 +22,8 @@ import org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
import org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
+import org.eclipse.sirius.common.tools.api.util.StringUtil;
import org.eclipse.sirius.common.tools.internal.interpreter.VariableInterpreter;
import com.google.common.base.Function;
@@ -50,10 +52,18 @@ public class VariableProposalProvider implements IProposalProvider {
final List<ContentProposal> proposals;
if (context == null || !(interpreter instanceof VariableInterpreter)) {
proposals = Collections.emptyList();
- } else if (context.getContents() == null || context.getContents().length() == 0) {
- proposals = Collections.singletonList(getNewEmtpyExpression());
} else {
- proposals = getProposals(context.getContents(), context.getPosition(), context.getInterpreterContext().getVariables().entrySet().iterator());
+ // Transform Entry<String,VariableType> to Entry<String,String>
+ Iterator<Entry<String, String>> variablesIterator = Iterators.transform(context.getInterpreterContext().getVariables().entrySet().iterator(),
+ new Function<Map.Entry<String, VariableType>, Map.Entry<String, String>>() {
+
+ @Override
+ public Entry<String, String> apply(Entry<String, VariableType> input) {
+ return Maps.immutableEntry(input.getKey(), input.getValue().toString());
+ }
+
+ });
+ proposals = getProposals(context.getContents(), context.getPosition(), variablesIterator);
}
return proposals;
}
@@ -65,18 +75,20 @@ public class VariableProposalProvider implements IProposalProvider {
final List<ContentProposal> proposals;
if (context == null || !(interpreter instanceof VariableInterpreter)) {
proposals = Collections.emptyList();
- } else if (context.getCurrentSelected() == null) {
- proposals = Collections.singletonList(getNewEmtpyExpression());
} else {
- // Transform Entry<String, Object> to Entry<String, String>
- VariableInterpreter variableInterpreter = (VariableInterpreter) interpreter;
- Iterator<Entry<String, String>> variablesIterator = Iterators.transform(variableInterpreter.getVariables().entrySet().iterator(),
- new Function<Entry<String, Object>, Entry<String, String>>() {
- public Map.Entry<String, String> apply(Map.Entry<String, Object> input) {
- return Maps.immutableEntry(input.getKey(), input.getValue().toString());
- };
- });
- proposals = getProposals(context.getTextSoFar(), context.getCursorPosition(), variablesIterator);
+ if (context.getCurrentSelected() == null) {
+ proposals = Collections.singletonList(getNewEmtpyExpression());
+ } else {
+ VariableInterpreter variableInterpreter = (VariableInterpreter) interpreter;
+ // Transform Entry<String, Object> to Entry<String, String>
+ Iterator<Entry<String, String>> variablesIterator = Iterators.transform(variableInterpreter.getVariables().entrySet().iterator(),
+ new Function<Entry<String, Object>, Entry<String, String>>() {
+ public Map.Entry<String, String> apply(Map.Entry<String, Object> input) {
+ return Maps.immutableEntry(input.getKey(), input.getValue().toString());
+ };
+ });
+ proposals = getProposals(context.getTextSoFar(), context.getCursorPosition(), variablesIterator);
+ }
}
return proposals;
}
@@ -95,30 +107,35 @@ public class VariableProposalProvider implements IProposalProvider {
* @return content proposal list.
*/
private List<ContentProposal> getProposals(String writtenExpression, int cursorPosition, Iterator<Entry<String, String>> variablesIterator) {
- final List<ContentProposal> proposals = new ArrayList<ContentProposal>();
- // Keep only characters before cursor
- String variableNamePrefix = writtenExpression.substring(0, cursorPosition);
- // Remove not needed space characters.
- variableNamePrefix = variableNamePrefix.trim();
- // Remove "var:" prefix if the cursor position is after the prefix
- // If the cursor position is before the prefix, there is no proposal
- // returned.
- if (variableNamePrefix.length() >= VariableInterpreter.PREFIX.length()) {
- variableNamePrefix = variableNamePrefix.substring(VariableInterpreter.PREFIX.length());
+ if (StringUtil.isEmpty(writtenExpression)) {
+ return Collections.singletonList(getNewEmtpyExpression());
+ } else {
- if (VariableInterpreter.SELF_VARIABLE_NAME.startsWith(variableNamePrefix)) {
- proposals.add(new ContentProposal(VariableInterpreter.SELF_VARIABLE_NAME, VariableInterpreter.SELF_VARIABLE_NAME, VariableInterpreter.SELF_VARIABLE_NAME));
- }
- while (variablesIterator.hasNext()) {
- Map.Entry<String, String> entry = variablesIterator.next();
- String variableName = entry.getKey();
- String variableType = entry.getValue();
- if (variableName.startsWith(variableNamePrefix)) {
- proposals.add(new ContentProposal(variableName, variableName + ": " + variableType, variableType));
+ final List<ContentProposal> proposals = new ArrayList<ContentProposal>();
+ // Keep only characters before cursor
+ String variableNamePrefix = writtenExpression.substring(0, cursorPosition);
+ // Remove not needed space characters.
+ variableNamePrefix = variableNamePrefix.trim();
+ // Remove "var:" prefix if the cursor position is after the prefix
+ // If the cursor position is before the prefix, there is no proposal
+ // returned.
+ if (variableNamePrefix.length() >= VariableInterpreter.PREFIX.length()) {
+ variableNamePrefix = variableNamePrefix.substring(VariableInterpreter.PREFIX.length());
+
+ if (VariableInterpreter.SELF_VARIABLE_NAME.startsWith(variableNamePrefix)) {
+ proposals.add(new ContentProposal(VariableInterpreter.SELF_VARIABLE_NAME, VariableInterpreter.SELF_VARIABLE_NAME, VariableInterpreter.SELF_VARIABLE_NAME));
+ }
+ while (variablesIterator.hasNext()) {
+ Map.Entry<String, String> entry = variablesIterator.next();
+ String variableName = entry.getKey();
+ String variableType = entry.getValue();
+ if (variableName.startsWith(variableNamePrefix)) {
+ proposals.add(new ContentProposal(variableName, variableName + ": " + variableType, variableType));
+ }
}
}
+ return proposals;
}
- return proposals;
}
}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/CompoundInterpreter.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/CompoundInterpreter.java
index d1f1b996a6..ba77ce8d6d 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/CompoundInterpreter.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/CompoundInterpreter.java
@@ -47,7 +47,7 @@ import com.google.common.collect.Sets;
*
* @author ymortier
*/
-public final class CompoundInterpreter implements IInterpreter, IProposalProvider {
+public final class CompoundInterpreter implements IInterpreter, IProposalProvider, TypedValidation {
/** The shared instance of the registry. */
public static final CompoundInterpreter INSTANCE = new CompoundInterpreter();
@@ -567,7 +567,7 @@ public final class CompoundInterpreter implements IInterpreter, IProposalProvide
*
* @author ymortier
*/
- private static class DefaultInterpreterProvider implements IInterpreterProvider, IInterpreter {
+ private static class DefaultInterpreterProvider implements IInterpreterProvider, IInterpreter, TypedValidation {
/** The shared instance. */
public static final DefaultInterpreterProvider INSTANCE = new DefaultInterpreterProvider();
@@ -762,6 +762,11 @@ public final class CompoundInterpreter implements IInterpreter, IProposalProvide
return false;
}
+ @Override
+ public ValidationResult analyzeExpression(IInterpreterContext context, String expression) {
+ return new ValidationResult();
+ }
+
}
/**
@@ -969,6 +974,17 @@ public final class CompoundInterpreter implements IInterpreter, IProposalProvide
return interpreter.validateExpression(context, expression);
}
+ @Override
+ public ValidationResult analyzeExpression(IInterpreterContext context, String expression) {
+ final IInterpreter interpreter = getInterpreterForExpression(expression);
+ if (interpreter instanceof TypedValidation) {
+ return ((TypedValidation) interpreter).analyzeExpression(context, expression);
+ }
+ ValidationResult result = new ValidationResult();
+ result.addAllStatus(interpreter.validateExpression(context, expression));
+ return result;
+ }
+
/**
*
* {@inheritDoc}
@@ -1001,4 +1017,5 @@ public final class CompoundInterpreter implements IInterpreter, IProposalProvide
return proposals;
}
+
}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/DefaultInterpreterContextFactory.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/DefaultInterpreterContextFactory.java
index a321536275..dd42ad48e4 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/DefaultInterpreterContextFactory.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/DefaultInterpreterContextFactory.java
@@ -16,7 +16,6 @@ import java.util.Map;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
-
import org.eclipse.sirius.common.tools.internal.interpreter.InterpretedContextImpl;
/**
@@ -53,8 +52,8 @@ public final class DefaultInterpreterContextFactory {
*
* @return a {@link IInterpreterContext} created from the given informations
*/
- public static IInterpreterContext createInterpreterContext(EObject element, boolean requiresTargetType, EStructuralFeature feature, Collection<String> targetTypes,
- Collection<EPackage> avalaiblePackages, Map<String, String> variables, Collection<String> dependencies) {
+ public static IInterpreterContext createInterpreterContext(EObject element, boolean requiresTargetType, EStructuralFeature feature, VariableType targetTypes,
+ Collection<EPackage> avalaiblePackages, Map<String, VariableType> variables, Collection<String> dependencies) {
return new InterpretedContextImpl(element, requiresTargetType, feature, targetTypes, avalaiblePackages, variables, dependencies);
}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/IInterpreterContext.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/IInterpreterContext.java
index 62da5d4992..55ac73bf1e 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/IInterpreterContext.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/IInterpreterContext.java
@@ -18,8 +18,8 @@ import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
/**
- * A context providing all informations required by {@link IInterpreter} to validate
- * statically an expression and compute completion proposals.
+ * A context providing all informations required by {@link IInterpreter} to
+ * validate statically an expression and compute completion proposals.
*
* @since 0.9.0
* @author alagarde
@@ -54,9 +54,12 @@ public interface IInterpreterContext {
* resulting list is empty and the requiresTargetTypes() method return
* false, the expected evaluation context type will be EObject.
*
+ * This method is deprecated, getTargetType() should be used instead.
+ *
* @return the names of all possible types for the target of the expression
* to evaluate
*/
+ @Deprecated
Collection<String> getTargetTypes();
/**
@@ -75,7 +78,7 @@ public interface IInterpreterContext {
* @return the available variables (Key is the variable name, value is the
* variable Type)
*/
- Map<String, String> getVariables();
+ Map<String, VariableType> getVariables();
/**
* Returns the feature containing the expression to evaluate.
@@ -93,4 +96,15 @@ public interface IInterpreterContext {
*/
Collection<String> getDependencies();
+ /**
+ * Returns a representation of the current receiver type. This type might be
+ * the union of several types.
+ *
+ * @return a representation of the current receiver type. This type might be
+ * the union of several types.
+ * @since 3.0
+ *
+ */
+ VariableType getTargetType();
+
}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/IInterpreterStatus.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/IInterpreterStatus.java
index ae612f0ac0..936f20076d 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/IInterpreterStatus.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/IInterpreterStatus.java
@@ -10,8 +10,6 @@
*******************************************************************************/
package org.eclipse.sirius.common.tools.api.interpreter;
-import java.util.Collection;
-
import org.eclipse.emf.ecore.EStructuralFeature;
/**
@@ -40,7 +38,7 @@ public interface IInterpreterStatus {
* @return the names of all possible types for the target of the evaluated
* expression to evaluate
*/
- Collection<String> getTargetTypes();
+ VariableType getTargetTypes();
/**
* Returns the feature containing the evaluated expression.
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/InterpreterStatusFactory.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/InterpreterStatusFactory.java
index 565be25226..cb76121ca5 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/InterpreterStatusFactory.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/InterpreterStatusFactory.java
@@ -13,7 +13,6 @@ package org.eclipse.sirius.common.tools.api.interpreter;
import java.util.Collection;
import org.eclipse.emf.ecore.EStructuralFeature;
-
import org.eclipse.sirius.common.tools.internal.interpreter.InterpreterStatusImpl;
/**
@@ -43,12 +42,15 @@ public final class InterpreterStatusFactory {
* @return a {@link IInterpreterStatus} created from the given informations
*/
public static IInterpreterStatus createInterpreterStatus(IInterpreterContext context, String severity, String message) {
- return new InterpreterStatusImpl(context.getTargetTypes(), context.getField(), severity, message, 1, 1, 2);
+ return new InterpreterStatusImpl(context.getTargetType(), context.getField(), severity, message, 1, 1, 2);
}
/**
* Creates a new {@link IInterpreterStatus} from the given informations.
*
+ * This method has been deprecated in favor of the variant using a
+ * {@link VariableType} instance in parameter.
+ *
* @param targetTypes
* the names of all possible types for the target of the
* expression to evaluate
@@ -62,13 +64,39 @@ public final class InterpreterStatusFactory {
* a message explaining the cause of the error
* @return a {@link IInterpreterStatus} created from the given informations
*/
+ @Deprecated
public static IInterpreterStatus createInterpreterStatus(Collection<String> targetTypes, EStructuralFeature field, String severity, String message) {
+ return createInterpreterStatus(VariableType.fromStrings(targetTypes), field, severity, message);
+ }
+
+ /**
+ * Creates a new {@link IInterpreterStatus} from the given informations.
+ *
+ * @param targetTypes
+ * the names of all possible types for the target of the
+ * expression to evaluate
+ * @param field
+ * the field containing the incorrect Interpreted Expression
+ * @param severity
+ * the severity of this error (can be
+ * {@link IInterpreterStatus#WARNING} or
+ * {@link IInterpreterStatus#ERROR}).
+ * @param message
+ * a message explaining the cause of the error
+ * @return a {@link IInterpreterStatus} created from the given informations
+ *
+ * @since 3.0
+ */
+ public static IInterpreterStatus createInterpreterStatus(VariableType targetTypes, EStructuralFeature field, String severity, String message) {
return new InterpreterStatusImpl(targetTypes, field, severity, message, 0, 0, 0);
}
/**
* Creates a new {@link IInterpreterStatus} from the given informations.
*
+ * This method has been deprecated in favor of the variant using a
+ * {@link VariableType} instance in parameter.
+ *
* @param targetTypes
* the names of all possible types for the target of the
* expression to evaluate
@@ -88,7 +116,36 @@ public final class InterpreterStatusFactory {
* the end position of the error
* @return a {@link IInterpreterStatus} created from the given informations
*/
+ @Deprecated
public static IInterpreterStatus createInterpreterStatus(Collection<String> targetTypes, EStructuralFeature field, String severity, String message, int line, int posBegin, int posEnd) {
+ return createInterpreterStatus(VariableType.fromStrings(targetTypes), field, severity, message, line, posBegin, posEnd);
+ }
+
+ /**
+ * Creates a new {@link IInterpreterStatus} from the given informations.
+ *
+ * @param targetTypes
+ * the names of all possible types for the target of the
+ * expression to evaluate
+ * @param field
+ * the field containing the incorrect Interpreted Expression
+ * @param severity
+ * the severity of this error (can be
+ * {@link IInterpreterStatus#WARNING} or
+ * {@link IInterpreterStatus#ERROR}).
+ * @param message
+ * a message explaining the cause of the error
+ * @param line
+ * the line of the error.
+ * @param posBegin
+ * the begin position of the error.
+ * @param posEnd
+ * the end position of the error
+ * @return a {@link IInterpreterStatus} created from the given informations
+ *
+ * @since 3.0
+ */
+ public static IInterpreterStatus createInterpreterStatus(VariableType targetTypes, EStructuralFeature field, String severity, String message, int line, int posBegin, int posEnd) {
return new InterpreterStatusImpl(targetTypes, field, severity, message, line, posBegin, posEnd);
}
}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/TypeName.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/TypeName.java
new file mode 100644
index 0000000000..931f58ea44
--- /dev/null
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/TypeName.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.common.tools.api.interpreter;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.sirius.common.tools.api.util.StringUtil;
+import org.eclipse.sirius.ext.base.Option;
+import org.eclipse.sirius.ext.base.Options;
+
+import com.google.common.collect.Sets;
+
+/**
+ * A class representing a type name.
+ *
+ *
+ * @author cedric
+ * @since 3.0
+ *
+ */
+public final class TypeName {
+
+ /**
+ * A singleton TypeName for any java.lang.Object.
+ */
+ public static final TypeName ANY_TYPENAME = new TypeName("ecore.EJavaObject");
+
+ /**
+ * A singleton TypeName for any EObject.
+ */
+ public static final TypeName EOBJECT_TYPENAME = new TypeName("ecore.EObject");
+
+ private static final String SEPARATOR = ".";
+
+ private final String typeName;
+
+ /**
+ * Create a new TypeName from a String representation. This constructor is
+ * not visible in order to provide the guarantee EObject or EJavaObject will
+ * always return the singleton instances.
+ *
+ * @param typeName
+ * a string representation of a type, can be 'SomeType', or
+ * 'ePackageName.SomeType' for instance.
+ */
+ private TypeName(String typeName) {
+ this.typeName = typeName;
+ }
+
+ /**
+ * return the string representation of the current {@link TypeName}.
+ *
+ * @return the string representation of the current {@link TypeName}.
+ */
+ public String getCompleteName() {
+ return typeName;
+ }
+
+ /**
+ * return the string representation of the current {@link TypeName} using
+ * the given separator in between package prefix (if specified in the
+ * typename) and the classifier name.
+ *
+ * @param separator
+ * the separator to use.
+ * @return the string representation of the current {@link TypeName} using
+ * the given separator.
+ */
+ public String getCompleteName(String separator) {
+ Option<String> packagePrefix = getPackagePrefix();
+ if (packagePrefix.some()) {
+ return packagePrefix.get() + separator + getClassifierName();
+ } else {
+ return getClassifierName();
+ }
+ }
+
+ /**
+ * Search for all the EClassifiers matching the current typename in a set of
+ * EPackages.
+ *
+ * @param availableEPackages
+ * a set of EPackages.
+ * @return all the EClassifiers matching the typename.
+ */
+ public Collection<EClassifier> search(Collection<EPackage> availableEPackages) {
+ Collection<EClassifier> matches = Sets.newLinkedHashSet();
+ Iterator<EPackage> it = availableEPackages.iterator();
+ while (it.hasNext()) {
+ EPackage pak = it.next();
+ EClassifier found = null;
+ if (typeName != null && typeName.contains(SEPARATOR)) {
+ if (pak.getName() != null && typeName.startsWith(pak.getName() + SEPARATOR)) {
+ String eClassName = typeName.substring(typeName.indexOf(SEPARATOR) + 1);
+ found = pak.getEClassifier(eClassName);
+ }
+ } else {
+ found = pak.getEClassifier(typeName);
+ }
+ if (found != null) {
+ matches.add(found);
+ }
+ }
+
+ return matches;
+ }
+
+ @Override
+ public String toString() {
+ return typeName;
+ }
+
+ /**
+ * Create a new TypeName from a String. returning one of the singleton
+ * instances if needed.
+ *
+ * @param typeName
+ * a string representation of a type, can be 'SomeType', or
+ * 'ePackageName.SomeType' for instance. If null or an empty
+ * string is passed then ANY_TYPENAME is returned.
+ * @return a TypeName instance.
+ */
+ public static TypeName fromString(String typeName) {
+ TypeName result = ANY_TYPENAME;
+ if (!StringUtil.isEmpty(typeName)) {
+ if ("ecore.EJavaObject".equals(typeName) || "EJavaObject".equals(typeName)) {
+ result = ANY_TYPENAME;
+ } else if ("ecore.EObject".equals(typeName) || "EObject".equals(typeName)) {
+ result = EOBJECT_TYPENAME;
+ } else {
+ result = new TypeName(typeName.trim());
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Create a new TypeName from a EClassifier. returning one of the singleton
+ * instances if needed.
+ *
+ * @param type
+ * the EClassifier instance.
+ * @return a TypeName instance.
+ */
+ public static TypeName fromEClassifier(EClassifier type) {
+ TypeName result = null;
+ if (type == EcorePackage.Literals.EJAVA_OBJECT) {
+ result = ANY_TYPENAME;
+ } else if (type == EcorePackage.Literals.EOBJECT) {
+ result = EOBJECT_TYPENAME;
+ } else {
+ if (type.getEPackage() != null && !StringUtil.isEmpty(type.getEPackage().getName())) {
+ result = new TypeName(type.getEPackage().getName() + SEPARATOR + type.getName());
+ } else {
+ result = new TypeName(type.getName());
+ }
+ }
+ return result;
+ }
+
+ /**
+ * return only the classifier name stripped down of any package prefix even
+ * if it was specified.
+ *
+ * @return only the classifier name stripped down of any package prefix even
+ * if it was specified.
+ */
+ public String getClassifierName() {
+ int indexOfSeparator = typeName.indexOf(SEPARATOR);
+ if (indexOfSeparator != -1) {
+ return typeName.substring(indexOfSeparator + 1);
+ } else {
+ return typeName;
+ }
+ }
+
+ /**
+ * return the type name package prefix if it was specified.
+ *
+ * @return the type name package prefix if it was specified.
+ */
+ public Option<String> getPackagePrefix() {
+ int indexOfSeparator = typeName.indexOf(SEPARATOR);
+ if (indexOfSeparator != -1) {
+ return Options.newSome(typeName.substring(0, indexOfSeparator));
+ } else {
+ return Options.newNone();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/TypedValidation.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/TypedValidation.java
new file mode 100644
index 0000000000..9ecc2f127c
--- /dev/null
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/TypedValidation.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.common.tools.api.interpreter;
+
+/**
+ * An interface for {@link IInterpreter} implementations which are able to
+ * provide rich information when analyzing an expression.
+ *
+ * This interface is introduced as an extension of the {@link IInterpreter}
+ * interface in order to keep compatibility with legacy implementations.
+ *
+ * @author cedric
+ * @since 3.0
+ */
+public interface TypedValidation {
+
+ /**
+ * Performs a static analysis of an expression and return the result.
+ *
+ * @param context
+ * the {@link IInterpreterContext} to use for validating this
+ * expression
+ * @param expression
+ * the expression to analyze
+ * @return a ValidationResult capturing errors, warning, and static analysis
+ * results.
+ *
+ * @since 3.0.0
+ */
+ ValidationResult analyzeExpression(IInterpreterContext context, String expression);
+
+}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/ValidationResult.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/ValidationResult.java
new file mode 100644
index 0000000000..84b38bb224
--- /dev/null
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/ValidationResult.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.common.tools.api.interpreter;
+
+import java.util.Collection;
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+/**
+ * The result of an expression validation.
+ *
+ * @author cedric
+ * @since 3.0
+ *
+ */
+public final class ValidationResult {
+
+ private List<IInterpreterStatus> statuses = Lists.newArrayList();
+
+ private VariableType returnType = VariableType.ANY_EOBJECT;
+
+ /**
+ * Add a status in the result.
+ *
+ * @param newStatus
+ * a status.
+ */
+ public void addStatus(IInterpreterStatus newStatus) {
+ this.statuses.add(newStatus);
+ }
+
+ /**
+ * Add several statuses at once in the validation result.
+ *
+ * @param newStatuses
+ * new statuses.
+ */
+ public void addAllStatus(Collection<IInterpreterStatus> newStatuses) {
+ this.statuses.addAll(newStatuses);
+ }
+
+ /**
+ * Specify the expression return type.
+ *
+ * @param returnType
+ * expression return type.
+ */
+ public void setReturnType(VariableType returnType) {
+ this.returnType = returnType;
+ }
+
+ /**
+ * return the validation statuses.
+ *
+ * @return the validation statuses.
+ */
+ public Collection<IInterpreterStatus> getStatuses() {
+ return this.statuses;
+ }
+
+ /**
+ * return the expression return types.
+ *
+ * @return the expression return types.
+ */
+ public VariableType getReturnTypes() {
+ return returnType;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/VariableType.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/VariableType.java
new file mode 100644
index 0000000000..092b352a36
--- /dev/null
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/VariableType.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.common.tools.api.interpreter;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * A class representing the type of a variable in a Viewpoint Specification
+ * model.
+ *
+ * @author cedric
+ * @since 3.0
+ *
+ */
+public final class VariableType {
+
+ /**
+ * The type to use for variables for which nothing more specific could be
+ * found.
+ */
+ public static final VariableType ANY_EOBJECT = fromString(TypeName.EOBJECT_TYPENAME.getCompleteName());
+
+ private List<TypeName> types = Lists.newArrayListWithExpectedSize(2);
+
+ private VariableType() {
+
+ }
+
+ /**
+ * Create a new {@link VariableType} from a unique type name.
+ *
+ * @param typeName
+ * the type name to use.
+ * @return the newly created instance.
+ */
+ public static VariableType fromString(String typeName) {
+ VariableType result = new VariableType();
+ result.types.add(TypeName.fromString(typeName));
+ return result;
+ }
+
+ /**
+ * Create a new {@link VariableType} from a collection of types.
+ *
+ * @param typeNames
+ * a collection of type names.
+ * @return the newly created instance.
+ */
+ public static VariableType fromStrings(Collection<String> typeNames) {
+ VariableType result = new VariableType();
+ for (String domainClass : typeNames) {
+ result.types.add(TypeName.fromString(domainClass));
+ }
+ return result;
+ }
+
+ /**
+ * Return a {@link TypeName} representation of a common type matching all
+ * the definitions. This should only be used by interpreters or code which
+ * can't take into account the fact that a Variable can have multiple types
+ * which no common super type in a Viewpoint Specification model.
+ *
+ * When a {@link VariableType} is defined by several typeNames common super
+ * types will be searched for but if several common types are found, then
+ * one will be arbitrarly choosen.
+ *
+ * @param availableEPackages
+ * the available EPackages to use.
+ *
+ * @return A TypeName of a type which matches all the definitions.
+ */
+ public TypeName getCommonType(Collection<EPackage> availableEPackages) {
+ TypeName result = TypeName.ANY_TYPENAME;
+ if (types.size() == 1) {
+ result = types.get(0);
+ }
+ if (types.size() > 1) {
+
+ Iterator<TypeName> typeNameIt = types.iterator();
+ Set<EClass> commonSuperTypes = Sets.newLinkedHashSet();
+ if (typeNameIt.hasNext()) {
+ TypeName first = typeNameIt.next();
+ commonSuperTypes = getAllSuperTypes(first, availableEPackages);
+ }
+ while (typeNameIt.hasNext() && commonSuperTypes.size() > 0) {
+ TypeName type = typeNameIt.next();
+ Set<EClass> nextTypeSuperTypes = getAllSuperTypes(type, availableEPackages);
+ commonSuperTypes = Sets.intersection(commonSuperTypes, nextTypeSuperTypes);
+ }
+
+ if (commonSuperTypes.size() > 0) {
+ EClass firstCommonSuperType = commonSuperTypes.iterator().next();
+ result = TypeName.fromEClassifier(firstCommonSuperType);
+ } else {
+ result = TypeName.EOBJECT_TYPENAME;
+ }
+ }
+ return result;
+ }
+
+ private Set<EClass> getAllSuperTypes(TypeName type, Collection<EPackage> collection) {
+ Set<EClass> allSuperTypes = Sets.newLinkedHashSet();
+ Iterator<EClass> it = Iterators.filter(type.search(collection).iterator(), EClass.class);
+ while (it.hasNext()) {
+ EClass curEClass = it.next();
+ allSuperTypes.add(curEClass);
+ allSuperTypes.addAll(curEClass.getEAllSuperTypes());
+ }
+ return allSuperTypes;
+ }
+
+ /**
+ * return true if the type has an actual definition, false if the variable
+ * is completely untyped.
+ *
+ * @return true if the type has an actual definition.
+ */
+ public boolean hasDefinition() {
+ return types.size() > 0;
+ }
+
+ /**
+ * return all the possible types this Variable is defined with.
+ *
+ * @return all the possible types this Variable is defined with.
+ */
+ public Collection<TypeName> getPossibleTypes() {
+ return types;
+ }
+
+ @Override
+ public String toString() {
+ return "[" + Joiner.on(',').join(this.types) + "]";
+ }
+}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/AbstractInterpreter.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/AbstractInterpreter.java
index 4d3663f09f..0164d57cb4 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/AbstractInterpreter.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/AbstractInterpreter.java
@@ -21,6 +21,7 @@ import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterStatus;
import org.eclipse.sirius.common.tools.api.interpreter.IVariableStatusListener;
+import org.eclipse.sirius.common.tools.api.interpreter.TypedValidation;
import org.eclipse.sirius.ecore.extender.business.api.accessor.MetamodelDescriptor;
import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
@@ -32,7 +33,7 @@ import com.google.common.collect.Lists;
*
* @author pcdavid
*/
-public abstract class AbstractInterpreter implements IInterpreter {
+public abstract class AbstractInterpreter implements IInterpreter, TypedValidation {
/** The separator between EPackage name and EClass name for domain class. */
protected static final String SEPARATOR = ".";
@@ -237,7 +238,7 @@ public abstract class AbstractInterpreter implements IInterpreter {
* {@inheritDoc}
*/
public Collection<IInterpreterStatus> validateExpression(IInterpreterContext context, String expression) {
- return Collections.emptySet();
+ return analyzeExpression(context, expression).getStatuses();
}
/**
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/FeatureInterpreter.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/FeatureInterpreter.java
index 07e320ce6b..92b2438bcb 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/FeatureInterpreter.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/FeatureInterpreter.java
@@ -10,23 +10,23 @@
*******************************************************************************/
package org.eclipse.sirius.common.tools.internal.interpreter;
-import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Iterator;
import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
-
-import com.google.common.collect.Lists;
-
import org.eclipse.sirius.common.tools.api.interpreter.EvaluationException;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterProvider;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterStatus;
import org.eclipse.sirius.common.tools.api.interpreter.InterpreterStatusFactory;
+import org.eclipse.sirius.common.tools.api.interpreter.TypeName;
+import org.eclipse.sirius.common.tools.api.interpreter.ValidationResult;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
+
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
/**
* A specialized interpreter which only supports direct access to a named
@@ -110,14 +110,24 @@ public class FeatureInterpreter extends AbstractInterpreter implements org.eclip
* {@inheritDoc}
*/
@Override
- public Collection<IInterpreterStatus> validateExpression(IInterpreterContext context, String expression) {
- Collection<IInterpreterStatus> interpreterStatus = new ArrayList<IInterpreterStatus>();
+ public ValidationResult analyzeExpression(IInterpreterContext context, String expression) {
+ ValidationResult interpreterStatus = new ValidationResult();
if (expression != null && context != null && expression.startsWith(PREFIX)) {
String featureName = expression.substring(PREFIX.length());
- EClass currentElementType = getCurrentElementType(context);
- if (currentElementType != null && !(hasFeatureName(currentElementType, featureName) || isDefaultFeatureName(featureName))) {
- interpreterStatus.add(InterpreterStatusFactory.createInterpreterStatus(context, IInterpreterStatus.ERROR, "The current element " + currentElementType.getEPackage().getName() + "::"
- + currentElementType.getName() + " does not have the feature named : " + featureName));
+ VariableType targetType = context.getTargetType();
+ if (!isDefaultFeatureName(featureName)) {
+ for (TypeName typeName : targetType.getPossibleTypes()) {
+ Iterator<EClass> possibleEClasses = Iterators.filter(typeName.search(context.getAvailableEPackages()).iterator(), EClass.class);
+ boolean foundAtLeastOneValid = false;
+ while (!foundAtLeastOneValid && possibleEClasses.hasNext()) {
+ EClass cur = possibleEClasses.next();
+ foundAtLeastOneValid = hasFeatureName(cur, featureName);
+ }
+ if (!foundAtLeastOneValid) {
+ interpreterStatus.addStatus(InterpreterStatusFactory.createInterpreterStatus(context, IInterpreterStatus.ERROR, "The current element " + typeName.getCompleteName("::")
+ + " does not have the feature named : " + featureName));
+ }
+ }
}
}
return interpreterStatus;
@@ -139,44 +149,4 @@ public class FeatureInterpreter extends AbstractInterpreter implements org.eclip
return isDefaultFeatureName;
}
- /**
- * Get the type of the current element from the specified
- * {@link IInterpreterContext}.
- *
- * @param interpreterContext
- * the specified {@link IInterpreterContext}
- * @return the type of the current element
- */
- public EClass getCurrentElementType(IInterpreterContext interpreterContext) {
- EClass currentElementType = null;
- Collection<String> targetTypes = interpreterContext.getTargetTypes();
- if (!targetTypes.isEmpty()) {
- String targetType = targetTypes.iterator().next();
- Collection<EPackage> availableEPackages = interpreterContext.getAvailableEPackages();
- if (targetType != null && targetType.contains(SEPARATOR)) {
- // If the current targetType has a EPackage prefix then look for
- // the corresponding EPackage
- for (EPackage availableEPackage : availableEPackages) {
- if (availableEPackage.getName() != null && targetType.startsWith(availableEPackage.getName() + SEPARATOR)) {
- String eClassName = targetType.substring(targetType.indexOf(SEPARATOR) + 1);
- EClassifier eClassifier = availableEPackage.getEClassifier(eClassName);
- if (eClassifier instanceof EClass) {
- currentElementType = (EClass) eClassifier;
- break;
- }
- }
- }
- } else {
- // Else look for in all EPackages
- for (EPackage availableEPackage : availableEPackages) {
- EClassifier eClassifier = availableEPackage.getEClassifier(targetType);
- if (eClassifier instanceof EClass) {
- currentElementType = (EClass) eClassifier;
- break;
- }
- }
- }
- }
- return currentElementType;
- }
}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/InterpretedContextImpl.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/InterpretedContextImpl.java
index 7ac1dca439..06eef7a203 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/InterpretedContextImpl.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/InterpretedContextImpl.java
@@ -16,8 +16,11 @@ import java.util.Map;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
-
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
+import org.eclipse.sirius.common.tools.api.interpreter.TypeName;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
+
+import com.google.common.collect.Sets;
/**
* Default implementation for of {@link IInterpreterContext}.
@@ -28,11 +31,11 @@ public class InterpretedContextImpl implements IInterpreterContext {
private EStructuralFeature field;
- private Map<String, String> variables;
+ private Map<String, VariableType> variables;
private Collection<EPackage> avalaiblePackages;
- private Collection<String> targetTypes;
+ private VariableType targetTypes;
private final EObject element;
@@ -65,8 +68,8 @@ public class InterpretedContextImpl implements IInterpreterContext {
* @param dependencies
* the list of available dependencies.
*/
- public InterpretedContextImpl(EObject element, boolean requiresTargetType, EStructuralFeature field, Collection<String> targetTypes, Collection<EPackage> avalaiblePackages,
- Map<String, String> variables, Collection<String> dependencies) {
+ public InterpretedContextImpl(EObject element, boolean requiresTargetType, EStructuralFeature field, VariableType targetTypes, Collection<EPackage> avalaiblePackages,
+ Map<String, VariableType> variables, Collection<String> dependencies) {
this.element = element;
this.requiresTargetType = requiresTargetType;
this.targetTypes = targetTypes;
@@ -90,9 +93,9 @@ public class InterpretedContextImpl implements IInterpreterContext {
*
* {@inheritDoc}
*
- * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext#getTargetTypes()
+ * @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext#getTargetType()
*/
- public Collection<String> getTargetTypes() {
+ public VariableType getTargetType() {
return targetTypes;
}
@@ -112,7 +115,7 @@ public class InterpretedContextImpl implements IInterpreterContext {
*
* @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext#getVariables()
*/
- public Map<String, String> getVariables() {
+ public Map<String, VariableType> getVariables() {
return variables;
}
@@ -146,4 +149,14 @@ public class InterpretedContextImpl implements IInterpreterContext {
return requiresTargetType;
}
+ @Override
+ public Collection<String> getTargetTypes() {
+ Collection<String> typeNames = Sets.newLinkedHashSet();
+ for (TypeName type : getTargetType().getPossibleTypes()) {
+ typeNames.add(type.getCompleteName());
+ }
+ return typeNames;
+
+ }
+
}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/InterpreterStatusImpl.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/InterpreterStatusImpl.java
index a1ecdb5277..dac2a5888c 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/InterpreterStatusImpl.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/InterpreterStatusImpl.java
@@ -10,11 +10,9 @@
*******************************************************************************/
package org.eclipse.sirius.common.tools.internal.interpreter;
-import java.util.Collection;
-
import org.eclipse.emf.ecore.EStructuralFeature;
-
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterStatus;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
/**
* A concrete {@link IInterpreterStatus}.
@@ -42,7 +40,7 @@ public class InterpreterStatusImpl implements IInterpreterStatus {
*/
private int posEnd;
- private Collection<String> targets;
+ private VariableType targets;
private EStructuralFeature field;
@@ -69,7 +67,7 @@ public class InterpreterStatusImpl implements IInterpreterStatus {
* @param posEnd
* the end position of the error
*/
- public InterpreterStatusImpl(Collection<String> targets, EStructuralFeature field, String severity, String message, int line, int posBegin, int posEnd) {
+ public InterpreterStatusImpl(VariableType targets, EStructuralFeature field, String severity, String message, int line, int posBegin, int posEnd) {
this.targets = targets;
this.field = field;
this.severity = severity;
@@ -130,7 +128,7 @@ public class InterpreterStatusImpl implements IInterpreterStatus {
*
* @see org.eclipse.sirius.common.tools.api.interpreter.IInterpreterStatus#getTargetTypes()
*/
- public Collection<String> getTargetTypes() {
+ public VariableType getTargetTypes() {
return targets;
}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/ServiceInterpreter.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/ServiceInterpreter.java
index 9e7467b6da..12bd196455 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/ServiceInterpreter.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/ServiceInterpreter.java
@@ -12,7 +12,6 @@ package org.eclipse.sirius.common.tools.internal.interpreter;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -24,8 +23,8 @@ import org.eclipse.sirius.common.tools.api.interpreter.EvaluationException;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterProvider;
-import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterStatus;
import org.eclipse.sirius.common.tools.api.interpreter.JavaExtensionsManager;
+import org.eclipse.sirius.common.tools.api.interpreter.ValidationResult;
import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.ext.base.Options;
@@ -260,9 +259,8 @@ public class ServiceInterpreter extends VariableInterpreter implements org.eclip
}
@Override
- public Collection<IInterpreterStatus> validateExpression(IInterpreterContext context, String expression) {
- Collection<IInterpreterStatus> interpreterStatus = new ArrayList<IInterpreterStatus>();
- return interpreterStatus;
+ public ValidationResult analyzeExpression(IInterpreterContext context, String expression) {
+ return new ValidationResult();
}
@Override
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/VariableInterpreter.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/VariableInterpreter.java
index c49cfd3bc0..c98bc37a5e 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/VariableInterpreter.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/VariableInterpreter.java
@@ -10,8 +10,6 @@
*******************************************************************************/
package org.eclipse.sirius.common.tools.internal.interpreter;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.Map;
import org.eclipse.emf.ecore.EObject;
@@ -21,7 +19,9 @@ import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterProvider;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterStatus;
import org.eclipse.sirius.common.tools.api.interpreter.InterpreterStatusFactory;
+import org.eclipse.sirius.common.tools.api.interpreter.ValidationResult;
import org.eclipse.sirius.common.tools.api.interpreter.VariableManager;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
/**
* A specialized interpreter which can only directly access variables (and
@@ -131,14 +131,28 @@ public class VariableInterpreter extends AbstractInterpreter implements org.ecli
* {@inheritDoc}
*/
@Override
- public Collection<IInterpreterStatus> validateExpression(IInterpreterContext context, String expression) {
- Collection<IInterpreterStatus> interpreterStatus = new ArrayList<IInterpreterStatus>();
+ public ValidationResult analyzeExpression(IInterpreterContext context, String expression) {
+ ValidationResult result = new ValidationResult();
if (expression != null && context != null && expression.startsWith(PREFIX)) {
String variableName = expression.substring(PREFIX.length());
if (!context.getVariables().containsKey(variableName) && !SELF_VARIABLE_NAME.equals(variableName)) {
- interpreterStatus.add(InterpreterStatusFactory.createInterpreterStatus(context, IInterpreterStatus.ERROR, "The current context does not contains variable named : " + variableName));
+ result.addStatus(InterpreterStatusFactory.createInterpreterStatus(context, IInterpreterStatus.ERROR, "The current context does not contains variable named : " + variableName));
}
+
+ if (SELF_VARIABLE_NAME.equals(variableName)) {
+ VariableType firstType = context.getTargetType();
+ if (firstType != null) {
+ result.setReturnType(firstType);
+ }
+ } else {
+ VariableType returnType = context.getVariables().get(variableName);
+ if (returnType != null) {
+ result.setReturnType(returnType);
+ }
+ }
+
}
- return interpreterStatus;
+
+ return result;
}
}
diff --git a/plugins/org.eclipse.sirius.diagram/src-core/org/eclipse/sirius/diagram/business/internal/dialect/description/DiagramInterpretedExpressionQuery.java b/plugins/org.eclipse.sirius.diagram/src-core/org/eclipse/sirius/diagram/business/internal/dialect/description/DiagramInterpretedExpressionQuery.java
index 747cf69855..651adbcaef 100644
--- a/plugins/org.eclipse.sirius.diagram/src-core/org/eclipse/sirius/diagram/business/internal/dialect/description/DiagramInterpretedExpressionQuery.java
+++ b/plugins/org.eclipse.sirius.diagram/src-core/org/eclipse/sirius/diagram/business/internal/dialect/description/DiagramInterpretedExpressionQuery.java
@@ -11,6 +11,7 @@
package org.eclipse.sirius.diagram.business.internal.dialect.description;
import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import org.eclipse.emf.ecore.EObject;
@@ -19,13 +20,22 @@ import org.eclipse.sirius.business.api.dialect.description.AbstractInterpretedEx
import org.eclipse.sirius.business.api.dialect.description.DefaultInterpretedExpressionTargetSwitch;
import org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQuery;
import org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionTargetSwitch;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterSiriusVariables;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
+import org.eclipse.sirius.common.tools.api.util.StringUtil;
import org.eclipse.sirius.diagram.business.api.diagramtype.DiagramTypeDescriptorRegistry;
import org.eclipse.sirius.diagram.business.api.diagramtype.IDiagramTypeDescriptor;
+import org.eclipse.sirius.diagram.description.AbstractNodeMapping;
+import org.eclipse.sirius.diagram.description.DiagramElementMapping;
import org.eclipse.sirius.diagram.description.DiagramExtensionDescription;
+import org.eclipse.sirius.diagram.description.EdgeMapping;
import org.eclipse.sirius.diagram.description.EdgeMappingImport;
+import org.eclipse.sirius.diagram.description.tool.ContainerCreationDescription;
import org.eclipse.sirius.diagram.description.tool.CreateView;
import org.eclipse.sirius.diagram.description.tool.DirectEditLabel;
import org.eclipse.sirius.diagram.description.tool.EdgeCreationDescription;
+import org.eclipse.sirius.diagram.description.tool.NodeCreationDescription;
+import org.eclipse.sirius.diagram.description.tool.ReconnectEdgeDescription;
import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.ext.base.Options;
import org.eclipse.sirius.viewpoint.description.RepresentationDescription;
@@ -33,6 +43,8 @@ import org.eclipse.sirius.viewpoint.description.RepresentationElementMapping;
import org.eclipse.sirius.viewpoint.description.tool.EditMaskVariables;
import org.eclipse.sirius.viewpoint.description.tool.ToolPackage;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
/**
@@ -45,6 +57,10 @@ import com.google.common.collect.Sets;
*/
public class DiagramInterpretedExpressionQuery extends AbstractInterpretedExpressionQuery implements IInterpretedExpressionQuery {
+ private static final String DIAGRAM_D_EDGE_TYPE = "diagram.DEdge";
+
+ private static final String DIAGRAM_EDGE_TARGET_TYPE = "diagram.EdgeTarget";
+
/**
* Default constructor.
*
@@ -74,7 +90,7 @@ public class DiagramInterpretedExpressionQuery extends AbstractInterpretedExpres
* {@inheritDoc}
*/
@Override
- protected void appendAllLocalVariableDefinitions(Map<String, Collection<String>> definitions, EObject context) {
+ protected void appendAllLocalVariableDefinitions(Map<String, Collection<VariableType>> definitions, EObject context) {
super.appendAllLocalVariableDefinitions(definitions, context);
// Direct edit defines numbered variables based on their mask.
if (context instanceof DirectEditLabel && ((DirectEditLabel) context).getMask() != null) {
@@ -84,12 +100,69 @@ public class DiagramInterpretedExpressionQuery extends AbstractInterpretedExpres
// Add CreateViewn and CreateEdgeView Variable Name to available
// variables
if (context instanceof CreateView) {
- availableVariables.put(((CreateView) context).getVariableName(), AbstractInterpretedExpressionQuery.DEFAULT_VARIABLE_TYPE);
+ availableVariables.put(((CreateView) context).getVariableName(), VariableType.ANY_EOBJECT);
}
+
}
@Override
- public Map<String, String> getAvailableVariables() {
+ public Map<String, VariableType> getAvailableVariables() {
+
+ Map<String, VariableType> availableVariables = super.getAvailableVariables();
+
+ if (getToolContext().some()) {
+ EObject operationContext = getToolContext().get();
+ if (operationContext instanceof EdgeCreationDescription) {
+ EdgeCreationDescription tool = (EdgeCreationDescription) operationContext;
+ declareEdgeSourceTargets(availableVariables, tool.getEdgeMappings(), tool.getExtraSourceMappings(), tool.getExtraTargetMappings());
+ }
+ if (operationContext instanceof ReconnectEdgeDescription) {
+ ReconnectEdgeDescription tool = (ReconnectEdgeDescription) operationContext;
+ declareEdgeSourceTargets(availableVariables, tool.getMappings(), Collections.<DiagramElementMapping> emptyList(), Collections.<DiagramElementMapping> emptyList());
+ availableVariables.put("otherEnd", VariableType.fromString(DIAGRAM_EDGE_TARGET_TYPE));
+ availableVariables.put("edgeView", VariableType.fromString(DIAGRAM_D_EDGE_TYPE));
+
+ Collection<String> possibleSources = Lists.newArrayList();
+ for (EdgeMapping eMapping : tool.getMappings()) {
+ collectSemanticElementType(possibleSources, eMapping);
+ }
+ if (possibleSources.size() > 0) {
+ VariableType sourceTypes = VariableType.fromStrings(possibleSources);
+ availableVariables.put(IInterpreterSiriusVariables.ELEMENT, sourceTypes);
+ }
+
+ }
+ if (operationContext instanceof NodeCreationDescription) {
+ NodeCreationDescription tool = (NodeCreationDescription) operationContext;
+ Collection<String> possibleTypes = Sets.newLinkedHashSet();
+ /*
+ * gather types for the "container" variable.
+ */
+ for (AbstractNodeMapping np : tool.getExtraMappings()) {
+ String domainClass = np.getDomainClass();
+ if (!StringUtil.isEmpty(domainClass)) {
+ possibleTypes.add(domainClass);
+ }
+ }
+ availableVariables.put(IInterpreterSiriusVariables.CONTAINER, VariableType.fromStrings(possibleTypes));
+ }
+
+ if (operationContext instanceof ContainerCreationDescription) {
+ ContainerCreationDescription tool = (ContainerCreationDescription) operationContext;
+ Collection<String> possibleTypes = Sets.newLinkedHashSet();
+ /*
+ * gather types for the "container" variable.
+ */
+ for (AbstractNodeMapping np : tool.getExtraMappings()) {
+ String domainClass = np.getDomainClass();
+ if (!StringUtil.isEmpty(domainClass)) {
+ possibleTypes.add(domainClass);
+ }
+ }
+ availableVariables.put(IInterpreterSiriusVariables.CONTAINER, VariableType.fromStrings(possibleTypes));
+ }
+
+ }
/*
* [428757] tool variables and not displayed in autocompletion This
* patch adds hard coded variables and hence is a temporary solution.
@@ -98,19 +171,76 @@ public class DiagramInterpretedExpressionQuery extends AbstractInterpretedExpres
* complete the AbstractInterpretedExpressionQuery to make it able to
* find specific variables for concrete types.
*/
- Map<String, String> availableVariables = super.getAvailableVariables();
-
if (target instanceof EdgeCreationDescription && ToolPackage.Literals.ABSTRACT_TOOL_DESCRIPTION__PRECONDITION.equals(feature)) {
- availableVariables.put("diagram", "diagram.DDiagram");
- availableVariables.put("preSource", "ecore.EObject");
- availableVariables.put("preSourceView", "diagram.EdgeTarget");
- availableVariables.put("preTarget", "ecore.EObject");
- availableVariables.put("preTargetView", "diagram.EdgeTarget");
+ availableVariables.put("diagram", VariableType.fromString("diagram.DDiagram"));
+ availableVariables.put("preSource", VariableType.fromString("ecore.EObject"));
+ availableVariables.put("preSourceView", VariableType.fromString(DIAGRAM_EDGE_TARGET_TYPE));
+ availableVariables.put("preTarget", VariableType.fromString("ecore.EObject"));
+ availableVariables.put("preTargetView", VariableType.fromString(DIAGRAM_EDGE_TARGET_TYPE));
+
}
return availableVariables;
}
+ private void declareEdgeSourceTargets(Map<String, VariableType> availableVariables, Collection<EdgeMapping> eMappings, Collection<DiagramElementMapping> extraSourceMappings,
+ Collection<DiagramElementMapping> extraTargetMappings) {
+ Collection<String> possibleSources = Sets.newLinkedHashSet();
+ Collection<String> possibleTargets = Sets.newLinkedHashSet();
+ for (EdgeMapping eMapping : eMappings) {
+ for (DiagramElementMapping endMapping : eMapping.getSourceMapping()) {
+ collectTypes(possibleSources, endMapping);
+ }
+ for (DiagramElementMapping endMapping : eMapping.getTargetMapping()) {
+ collectTypes(possibleTargets, endMapping);
+ }
+ }
+ for (DiagramElementMapping extraSource : extraSourceMappings) {
+ collectTypes(possibleSources, extraSource);
+ }
+ for (DiagramElementMapping extraTarget : extraTargetMappings) {
+ collectTypes(possibleTargets, extraTarget);
+ }
+ if (possibleSources.size() > 0) {
+ VariableType sourceTypes = VariableType.fromStrings(possibleSources);
+ availableVariables.put(IInterpreterSiriusVariables.SOURCE_PRE, sourceTypes);
+ availableVariables.put(IInterpreterSiriusVariables.SOURCE, sourceTypes);
+ }
+ if (possibleTargets.size() > 0 && feature != org.eclipse.sirius.diagram.description.tool.ToolPackage.Literals.EDGE_CREATION_DESCRIPTION__CONNECTION_START_PRECONDITION) {
+ VariableType targetTypes = VariableType.fromStrings(possibleTargets);
+ availableVariables.put(IInterpreterSiriusVariables.TARGET_PRE, targetTypes);
+ availableVariables.put(IInterpreterSiriusVariables.TARGET, targetTypes);
+ }
+ }
+
+ private void collectTypes(Collection<String> possibleSources, DiagramElementMapping endMapping) {
+ if (endMapping instanceof AbstractNodeMapping) {
+ String domainClass = ((AbstractNodeMapping) endMapping).getDomainClass();
+ if (!StringUtil.isEmpty(domainClass)) {
+ possibleSources.add(domainClass);
+ }
+ } else if (endMapping instanceof EdgeMapping) {
+ EdgeMapping edgeMapping = (EdgeMapping) endMapping;
+ collectSemanticElementType(possibleSources, edgeMapping);
+ }
+ }
+
+ private void collectSemanticElementType(Collection<String> possibleSources, EdgeMapping edgeMapping) {
+ if (edgeMapping.isUseDomainElement()) {
+ String domainClass = edgeMapping.getDomainClass();
+ if (!StringUtil.isEmpty(domainClass)) {
+ possibleSources.add(domainClass);
+ }
+ } else {
+ for (AbstractNodeMapping nMapping : Iterables.filter(edgeMapping.getSourceMapping(), AbstractNodeMapping.class)) {
+ String domainClass = nMapping.getDomainClass();
+ if (!StringUtil.isEmpty(domainClass)) {
+ possibleSources.add(domainClass);
+ }
+ }
+ }
+ }
+
/**
* An {@link IInterpretedExpressionTargetSwitch} that delegates to the
* defaultSwitch or the diagram specific switch, according to the package of
@@ -208,7 +338,8 @@ public class DiagramInterpretedExpressionQuery extends AbstractInterpretedExpres
}
private boolean isRelevant(EObject container) {
- return container instanceof RepresentationDescription || container instanceof RepresentationElementMapping || container instanceof EdgeMappingImport || container instanceof DiagramExtensionDescription;
+ return container instanceof RepresentationDescription || container instanceof RepresentationElementMapping || container instanceof EdgeMappingImport
+ || container instanceof DiagramExtensionDescription;
}
}
}
diff --git a/plugins/org.eclipse.sirius.doc/doc/Release Notes.html b/plugins/org.eclipse.sirius.doc/doc/Release Notes.html
index 119aafc5f3..a831280b96 100644
--- a/plugins/org.eclipse.sirius.doc/doc/Release Notes.html
+++ b/plugins/org.eclipse.sirius.doc/doc/Release Notes.html
@@ -242,6 +242,36 @@
<li>A new class
<code>org.eclipse.sirius.common.tools.api.interpreter.JavaExtensionsManager</code> can now be used by langages interpreters to benefit from a consistent handling of Java extensions and support for loading Java services from the workspace.
</li>
+ <li>The static method
+ <code>org.eclipse.sirius.common.tools.api.interpreter.DefaultInterpreterContextFactory.createInterpreterContext(...)</code> now requires a
+ <code>Map&lt;String, VariableType&gt;</code> for the accessible variables instead of a
+ <code>Map&lt;String, String&gt;</code>.
+ </li>
+ <li>The method
+ <code>org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext.getTargetTypes()</code> has been deprecated in favor of
+ <code>org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext.getTargetType()</code> which returns a
+ <code>VariableType</code> instance instead of encoded Strings.
+ </li>
+ <li>The methods
+ <code>org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext.getVariables()</code> and
+ <code>org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQuery.getAvailableVariables()</code> are now returning a map containing
+ <code>VariableType</code> instances instead of encoded Strings.
+ </li>
+ <li>The method
+ <code>org.eclipse.sirius.common.tools.api.interpreter.IInterpreterStatus.getTargetTypes()</code> no longer returns a list of encoded Strings but a
+ <code>VariableType</code> instance instead.
+ </li>
+ <li>The class
+ <code>org.eclipse.sirius.common.tools.api.interpreter.TypeName</code> has been introduced to represent in the codebase any type which was previously represented as a plain String.
+ </li>
+ <li>A new interface
+ <code>org.eclipse.sirius.common.tools.api.interpreter.TypedValidation</code> has been introduced for
+ <code>IInterpreter</code> implementations able to provide richer information when validating an expression. This information is captured through a
+ <code>org.eclipse.sirius.common.tools.api.interpreter.ValidationResult</code> instance.
+ </li>
+ <li>The class
+ <code>org.eclipse.sirius.common.tools.api.interpreter.VariableType</code> has been introduced to represent the possible types a variable can have in a Viewpoint specification model.
+ </li>
</ul>
<h4 id="Changesinorg.eclipse.sirius.ecore.extender">Changes in
<code>org.eclipse.sirius.ecore.extender</code>
diff --git a/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile b/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile
index 03f12641ea..46665476fe 100644
--- a/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile
+++ b/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile
@@ -68,6 +68,13 @@ h4. Changes in @org.eclipse.sirius.common@
* The interface @org.eclipse.sirius.business.api.migration.IMigrationParticipant@ exposes a new method @postXMLEndElement([..])@ which is called during a migration operation. This method should be overrided by participants which have to hook the loading process after each end of XML tag. The corresponding abstract class @org.eclipse.sirius.business.api.migration.AbstractMigrationParticipant@ provides a default NO-OP implementation.
* @org.eclipse.sirius.common.tools.api.util.EclipseUtil.getConfigurationElementsFor()@ added to call @org.eclipse.core.runtime.Platform.getExtensionRegistry().getConfigurationElementsFor()@ and check @Platform.isRunning()@ before.
* A new class @org.eclipse.sirius.common.tools.api.interpreter.JavaExtensionsManager@ can now be used by langages interpreters to benefit from a consistent handling of Java extensions and support for loading Java services from the workspace.
+* The static method @org.eclipse.sirius.common.tools.api.interpreter.DefaultInterpreterContextFactory.createInterpreterContext(...)@ now requires a @Map<String, VariableType>@ for the accessible variables instead of a @Map<String, String>@.
+* The method @org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext.getTargetTypes()@ has been deprecated in favor of @org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext.getTargetType()@ which returns a @VariableType@ instance instead of encoded Strings.
+* The methods @org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext.getVariables()@ and @org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQuery.getAvailableVariables()@ are now returning a map containing @VariableType@ instances instead of encoded Strings.
+* The method @org.eclipse.sirius.common.tools.api.interpreter.IInterpreterStatus.getTargetTypes()@ no longer returns a list of encoded Strings but a @VariableType@ instance instead.
+* The class @org.eclipse.sirius.common.tools.api.interpreter.TypeName@ has been introduced to represent in the codebase any type which was previously represented as a plain String.
+* A new interface @org.eclipse.sirius.common.tools.api.interpreter.TypedValidation@ has been introduced for @IInterpreter@ implementations able to provide richer information when validating an expression. This information is captured through a @org.eclipse.sirius.common.tools.api.interpreter.ValidationResult@ instance.
+* The class @org.eclipse.sirius.common.tools.api.interpreter.VariableType@ has been introduced to represent the possible types a variable can have in a Viewpoint specification model.
h4. Changes in @org.eclipse.sirius.ecore.extender@
diff --git a/plugins/org.eclipse.sirius.table/src/org/eclipse/sirius/table/business/internal/dialect/description/TableInterpretedExpressionQuery.java b/plugins/org.eclipse.sirius.table/src/org/eclipse/sirius/table/business/internal/dialect/description/TableInterpretedExpressionQuery.java
index f30413bec0..539c9dd352 100644
--- a/plugins/org.eclipse.sirius.table/src/org/eclipse/sirius/table/business/internal/dialect/description/TableInterpretedExpressionQuery.java
+++ b/plugins/org.eclipse.sirius.table/src/org/eclipse/sirius/table/business/internal/dialect/description/TableInterpretedExpressionQuery.java
@@ -19,6 +19,7 @@ import org.eclipse.sirius.business.api.dialect.description.AbstractInterpretedEx
import org.eclipse.sirius.business.api.dialect.description.DefaultInterpretedExpressionTargetSwitch;
import org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionTargetSwitch;
import org.eclipse.sirius.business.api.query.EObjectQuery;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.ext.base.Options;
import org.eclipse.sirius.table.metamodel.table.description.CreateCellTool;
@@ -59,7 +60,7 @@ public class TableInterpretedExpressionQuery extends AbstractInterpretedExpressi
}
@Override
- protected void appendAllLocalVariableDefinitions(Map<String, Collection<String>> definitions, EObject context) {
+ protected void appendAllLocalVariableDefinitions(Map<String, Collection<VariableType>> definitions, EObject context) {
super.appendAllLocalVariableDefinitions(definitions, context);
// The "Direct edit" and the "Create Cell" tools define numbered
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/api/interpreter/CompletionTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/api/interpreter/CompletionTests.java
index 5af4029a1a..f78ce7c573 100644
--- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/api/interpreter/CompletionTests.java
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/api/interpreter/CompletionTests.java
@@ -22,6 +22,8 @@ import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
import org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider;
import org.eclipse.sirius.common.tools.api.interpreter.DefaultInterpreterContextFactory;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
+import org.eclipse.sirius.common.tools.api.interpreter.TypeName;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.diagram.DiagramPackage;
import org.eclipse.sirius.diagram.description.tool.NodeCreationDescription;
import org.eclipse.sirius.diagram.description.tool.ToolFactory;
@@ -70,8 +72,8 @@ public class CompletionTests extends SiriusDiagramTestCase implements EcoreModel
}
private ContentContext getContext(EObject element, EStructuralFeature feature, String domainClass, String text, int cursorPosition) {
- IInterpreterContext interContext = DefaultInterpreterContextFactory.createInterpreterContext(element, true, feature, Collections.singletonList(domainClass),
- Collections.<EPackage> emptyList(), Collections.<String, String> emptyMap(), Collections.<String> emptyList());
+ IInterpreterContext interContext = DefaultInterpreterContextFactory.createInterpreterContext(element, true, feature, VariableType.fromString(domainClass), Collections.<EPackage> emptyList(),
+ Collections.<String, VariableType> emptyMap(), Collections.<String> emptyList());
ContentContext context = new ContentContext(text, cursorPosition, interContext);
return context;
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/AbstractCompletionTestCase.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/AbstractCompletionTestCase.java
index e05eb26330..0e64325c92 100644
--- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/AbstractCompletionTestCase.java
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/AbstractCompletionTestCase.java
@@ -30,6 +30,8 @@ import org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider;
import org.eclipse.sirius.common.tools.api.interpreter.CompoundInterpreter;
import org.eclipse.sirius.common.tools.api.interpreter.DefaultInterpreterContextFactory;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.common.tools.api.interpreter.TypeName;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
@@ -157,7 +159,7 @@ public class AbstractCompletionTestCase extends TestCase {
* @return a new {@link ContentContext}
*/
protected ContentContext createContentContext(String expression, int cursorPosition, String eClass) {
- return createContentContext(expression, cursorPosition, eClass, Collections.<String, String> emptyMap());
+ return createContentContext(expression, cursorPosition, eClass, Collections.<String, VariableType> emptyMap());
}
/**
@@ -174,7 +176,7 @@ public class AbstractCompletionTestCase extends TestCase {
* @return a new {@link ContentContext}
*/
protected ContentContext createContentContext(String expression, int cursorPosition, EObject element, String eClass) {
- return createContentContext(expression, cursorPosition, element, eClass, null, Collections.<String, String> emptyMap(), Collections.<String> emptyList());
+ return createContentContext(expression, cursorPosition, element, eClass, null, Collections.<String, VariableType> emptyMap(), Collections.<String> emptyList());
}
/**
@@ -190,7 +192,7 @@ public class AbstractCompletionTestCase extends TestCase {
* declared variables
* @return a new {@link ContentContext}
*/
- protected ContentContext createContentContext(String expression, int cursorPosition, String eClass, Map<String, String> variables) {
+ protected ContentContext createContentContext(String expression, int cursorPosition, String eClass, Map<String, VariableType> variables) {
return createContentContext(expression, cursorPosition, eClass, null, variables, Collections.<String> emptyList());
}
@@ -208,7 +210,7 @@ public class AbstractCompletionTestCase extends TestCase {
* @return a new {@link ContentContext}
*/
protected ContentContext createContentContext(String expression, int cursorPosition, String eClass, EPackage ePackage) {
- return createContentContext(expression, cursorPosition, eClass, ePackage, Collections.<String, String> emptyMap(), Collections.<String> emptyList());
+ return createContentContext(expression, cursorPosition, eClass, ePackage, Collections.<String, VariableType> emptyMap(), Collections.<String> emptyList());
}
/**
@@ -227,7 +229,7 @@ public class AbstractCompletionTestCase extends TestCase {
* @return a new {@link ContentContext}
*/
protected ContentContext createContentContext(String expression, int cursorPosition, EObject element, String eClass, EPackage ePackage) {
- return createContentContext(expression, cursorPosition, element, eClass, ePackage, Collections.<String, String> emptyMap(), Collections.<String> emptyList());
+ return createContentContext(expression, cursorPosition, element, eClass, ePackage, Collections.<String, VariableType> emptyMap(), Collections.<String> emptyList());
}
/**
@@ -247,7 +249,7 @@ public class AbstractCompletionTestCase extends TestCase {
* the list of available dependencies
* @return a new {@link ContentContext}
*/
- protected ContentContext createContentContext(String expression, int cursorPosition, String eClass, EPackage ePackage, Map<String, String> variables, Collection<String> dependencies) {
+ protected ContentContext createContentContext(String expression, int cursorPosition, String eClass, EPackage ePackage, Map<String, VariableType> variables, Collection<String> dependencies) {
return createContentContext(expression, cursorPosition, null, eClass, ePackage, variables, dependencies);
}
@@ -270,10 +272,10 @@ public class AbstractCompletionTestCase extends TestCase {
* the list of available dependencies
* @return a new {@link ContentContext}
*/
- protected ContentContext createContentContext(String expression, int cursorPosition, EObject element, String eClass, EPackage ePackage, Map<String, String> variables,
+ protected ContentContext createContentContext(String expression, int cursorPosition, EObject element, String eClass, EPackage ePackage, Map<String, VariableType> variables,
Collection<String> dependencies) {
Collection<EPackage> pList = ePackage == null ? Collections.<EPackage> emptyList() : Collections.singletonList(ePackage);
- return new ContentContext(expression, cursorPosition, DefaultInterpreterContextFactory.createInterpreterContext(element, true, null, Collections.singletonList(eClass), pList, variables,
+ return new ContentContext(expression, cursorPosition, DefaultInterpreterContextFactory.createInterpreterContext(element, true, null, VariableType.fromString(eClass), pList, variables,
dependencies));
}
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/mtl/AcceleoMTLCompletionTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/mtl/AcceleoMTLCompletionTests.java
index 0724f0ab7e..11f3d2ae87 100644
--- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/mtl/AcceleoMTLCompletionTests.java
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/mtl/AcceleoMTLCompletionTests.java
@@ -27,6 +27,8 @@ import org.eclipse.sirius.common.tools.api.contentassist.ContentContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.common.tools.api.interpreter.TypeName;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.common.tools.api.util.StringUtil;
import org.eclipse.sirius.diagram.DNode;
import org.eclipse.sirius.diagram.DiagramFactory;
@@ -275,13 +277,13 @@ public class AcceleoMTLCompletionTests extends AbstractCompletionTestCase {
public void testAcceleoMTLCompletionOnOtherM2() {
DNode dNode = DiagramFactory.eINSTANCE.createDNode();
- ContentContext cc = createContentContext("[/]", 0, "DNode", DiagramPackage.eINSTANCE, Collections.<String, String> emptyMap(), Collections.<String> emptyList());
+ ContentContext cc = createContentContext("[/]", 0, "DNode", DiagramPackage.eINSTANCE, Collections.<String, VariableType> emptyMap(), Collections.<String> emptyList());
// No completion before [
List<ContentProposal> contentProposals = getProposals(cc);
// assertTrue(contentProposals.isEmpty());
- cc = createContentContext("[/]", 1, "DNode", DiagramPackage.eINSTANCE, Collections.<String, String> emptyMap(), Collections.<String> emptyList());
+ cc = createContentContext("[/]", 1, "DNode", DiagramPackage.eINSTANCE, Collections.<String, VariableType> emptyMap(), Collections.<String> emptyList());
contentProposals = getProposals(cc);
Set<String> vars = Sets.newHashSet();
@@ -290,12 +292,12 @@ public class AcceleoMTLCompletionTests extends AbstractCompletionTestCase {
checkCompletionProposal(dNode.eClass(), contentProposals, vars, true);
- cc = createContentContext("[self./]", 6, "DNode", DiagramPackage.eINSTANCE, Collections.<String, String> emptyMap(), Collections.<String> emptyList());
+ cc = createContentContext("[self./]", 6, "DNode", DiagramPackage.eINSTANCE, Collections.<String, VariableType> emptyMap(), Collections.<String> emptyList());
contentProposals = getProposals(cc);
checkCompletionProposal(dNode.eClass(), contentProposals, concreteInterpreter.getVariables().keySet(), false);
- cc = createContentContext("[self./]", 6, "diagram.DNode", DiagramPackage.eINSTANCE, Collections.<String, String> emptyMap(), Collections.<String> emptyList());
+ cc = createContentContext("[self./]", 6, "diagram.DNode", DiagramPackage.eINSTANCE, Collections.<String, VariableType> emptyMap(), Collections.<String> emptyList());
contentProposals = getProposals(cc);
checkCompletionProposal(dNode.eClass(), contentProposals, concreteInterpreter.getVariables().keySet(), false);
@@ -342,7 +344,7 @@ public class AcceleoMTLCompletionTests extends AbstractCompletionTestCase {
EClass c = EcoreFactory.eINSTANCE.createEClass();
String varName = "maClasse";
- String varType = c.eClass().getName();
+ VariableType varType = VariableType.fromString(c.eClass().getName());
ContentContext c1 = createContentContext("[/]", 1, "EClass", Collections.singletonMap(varName, varType));
ContentContext c2 = createContentContext("[self.name.concat()/]", 18, "EClass", Collections.singletonMap(varName, varType));
@@ -396,8 +398,8 @@ public class AcceleoMTLCompletionTests extends AbstractCompletionTestCase {
EClass c = EcoreFactory.eINSTANCE.createEClass();
Collection<String> dependencies = Lists.newArrayList(IMPORT, SERVICE);
- ContentContext c1 = createContentContext("[/]", 1, "EClass", EcorePackage.eINSTANCE, Collections.<String, String> emptyMap(), dependencies);
- ContentContext c2 = createContentContext("[self./]", 6, "EClass", EcorePackage.eINSTANCE, Collections.<String, String> emptyMap(), dependencies);
+ ContentContext c1 = createContentContext("[/]", 1, "EClass", EcorePackage.eINSTANCE, Collections.<String, VariableType> emptyMap(), dependencies);
+ ContentContext c2 = createContentContext("[self./]", 6, "EClass", EcorePackage.eINSTANCE, Collections.<String, VariableType> emptyMap(), dependencies);
ContentContext c3 = createContentContext("[self.name.concat()/]", 18, "EClass");
doTestAcceleoMTLCompletionWithDependencies(c, c1, c2, c3, proposalFunction, dependencies);
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/service/ServiceProposalProviderTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/service/ServiceProposalProviderTests.java
index d25cac5b59..2b87dce3c4 100644
--- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/service/ServiceProposalProviderTests.java
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/service/ServiceProposalProviderTests.java
@@ -24,6 +24,7 @@ import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
import org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.common.tools.internal.interpreter.ServiceInterpreter;
import org.eclipse.sirius.common.tools.internal.interpreter.VariableInterpreter;
import org.eclipse.sirius.common.ui.tools.internal.interpreter.ServiceProposalProvider;
@@ -69,7 +70,7 @@ public class ServiceProposalProviderTests extends TestCase {
EAttribute eAttribute = EcoreFactory.eINSTANCE.createEAttribute();
eAttribute.setName("a1");
interpreter.setVariable(GETAWAY_VARIABLE, eAttribute);
- interpreterContext.getVariables().put(GETAWAY_VARIABLE, "newVariable");
+ interpreterContext.getVariables().put(GETAWAY_VARIABLE, VariableType.ANY_EOBJECT);
}
return interpreterContext;
}
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/variable/VariableInterpreterTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/variable/VariableInterpreterTests.java
index db5838f12c..75bd1b0c2c 100644
--- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/variable/VariableInterpreterTests.java
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/variable/VariableInterpreterTests.java
@@ -23,6 +23,7 @@ import org.eclipse.sirius.common.tools.api.interpreter.EvaluationException;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterStatus;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.common.tools.internal.interpreter.AbstractInterpreter;
import org.eclipse.sirius.common.tools.internal.interpreter.FeatureInterpreter;
import org.eclipse.sirius.common.tools.internal.interpreter.ServiceInterpreter;
@@ -165,7 +166,7 @@ public class VariableInterpreterTests extends TestCase {
IInterpreterContext context = SiriusInterpreterContextFactory.createInterpreterContext(diagramDescription, DescriptionPackage.Literals.DIAGRAM_DESCRIPTION__PRECONDITION_EXPRESSION);
String varExampleName = "varExampleName";
String varExampleValue = "varExampleValue";
- context.getVariables().put(varExampleName, varExampleValue);
+ context.getVariables().put(varExampleName, VariableType.fromString(varExampleValue));
// Test
Collection<IInterpreterStatus> status = interpreter.validateExpression(context, VariableInterpreter.PREFIX + varExampleName);
// Check
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/variable/VariableProposalProviderTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/variable/VariableProposalProviderTests.java
index 7de2490d47..defcdc0392 100644
--- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/variable/VariableProposalProviderTests.java
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/variable/VariableProposalProviderTests.java
@@ -20,6 +20,8 @@ import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
import org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
+import org.eclipse.sirius.common.tools.api.interpreter.TypeName;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.common.tools.internal.interpreter.VariableInterpreter;
import org.eclipse.sirius.common.ui.tools.internal.interpreter.VariableProposalProvider;
import org.eclipse.sirius.diagram.description.DescriptionFactory;
@@ -54,10 +56,10 @@ public class VariableProposalProviderTests extends TestCase {
public void testVariableProposalProviderWithoutVariables() {
DiagramDescription diagramDescription = DescriptionFactory.eINSTANCE.createDiagramDescription();
diagramDescription.setDomainClass(EcorePackage.eNAME + "." + EcorePackage.Literals.EPACKAGE.getName());
- IInterpreterContext interpreterContext = SiriusInterpreterContextFactory.createInterpreterContext(diagramDescription,
- DescriptionPackage.Literals.DIAGRAM_DESCRIPTION__PRECONDITION_EXPRESSION);
+ IInterpreterContext interpreterContext = SiriusInterpreterContextFactory.createInterpreterContext(diagramDescription, DescriptionPackage.Literals.DIAGRAM_DESCRIPTION__PRECONDITION_EXPRESSION);
- ContentContext context = new ContentContext(VariableInterpreter.PREFIX, VariableInterpreter.PREFIX.length(), interpreterContext); List<ContentProposal> proposals = proposalProvider.getProposals(interpreter, context);
+ ContentContext context = new ContentContext(VariableInterpreter.PREFIX, VariableInterpreter.PREFIX.length(), interpreterContext);
+ List<ContentProposal> proposals = proposalProvider.getProposals(interpreter, context);
assertNotNull("proposals should not be null", proposals);
assertEquals("There should be only one proposal", 1, proposals.size());
ContentProposal contentProposal = proposals.get(0);
@@ -67,11 +69,10 @@ public class VariableProposalProviderTests extends TestCase {
public void testVariableProposalProviderWithVariables() {
DiagramDescription diagramDescription = DescriptionFactory.eINSTANCE.createDiagramDescription();
diagramDescription.setDomainClass(EcorePackage.eNAME + "." + EcorePackage.Literals.EPACKAGE.getName());
- IInterpreterContext interpreterContext = SiriusInterpreterContextFactory.createInterpreterContext(diagramDescription,
- DescriptionPackage.Literals.DIAGRAM_DESCRIPTION__PRECONDITION_EXPRESSION);
+ IInterpreterContext interpreterContext = SiriusInterpreterContextFactory.createInterpreterContext(diagramDescription, DescriptionPackage.Literals.DIAGRAM_DESCRIPTION__PRECONDITION_EXPRESSION);
String varExampleName = "varExampleName";
String varExampleValue = "varExampleValue";
- interpreterContext.getVariables().put(varExampleName, varExampleValue);
+ interpreterContext.getVariables().put(varExampleName, VariableType.fromString(varExampleValue));
ContentContext context = new ContentContext(VariableInterpreter.PREFIX, VariableInterpreter.PREFIX.length(), interpreterContext);
List<ContentProposal> proposals = proposalProvider.getProposals(interpreter, context);
@@ -91,11 +92,10 @@ public class VariableProposalProviderTests extends TestCase {
public void testVariableProposalProviderWithVariablesWithPrefix() {
DiagramDescription diagramDescription = DescriptionFactory.eINSTANCE.createDiagramDescription();
diagramDescription.setDomainClass(EcorePackage.eNAME + "." + EcorePackage.Literals.EPACKAGE.getName());
- IInterpreterContext interpreterContext = SiriusInterpreterContextFactory.createInterpreterContext(diagramDescription,
- DescriptionPackage.Literals.DIAGRAM_DESCRIPTION__PRECONDITION_EXPRESSION);
+ IInterpreterContext interpreterContext = SiriusInterpreterContextFactory.createInterpreterContext(diagramDescription, DescriptionPackage.Literals.DIAGRAM_DESCRIPTION__PRECONDITION_EXPRESSION);
String varExampleName = "varExampleName";
String varExampleValue = "varExampleValue";
- interpreterContext.getVariables().put(varExampleName, varExampleValue);
+ interpreterContext.getVariables().put(varExampleName, VariableType.fromString(varExampleValue));
ContentContext context = new ContentContext(VariableInterpreter.PREFIX + VariableInterpreter.SELF_VARIABLE_NAME.substring(0, 2), VariableInterpreter.PREFIX.length() + 2, interpreterContext);
List<ContentProposal> proposals = proposalProvider.getProposals(interpreter, context);
@@ -105,7 +105,6 @@ public class VariableProposalProviderTests extends TestCase {
assertEquals("The proposal should be the self variable", VariableInterpreter.SELF_VARIABLE_NAME, contentProposal1.getProposal());
}
-
@Override
protected void tearDown() throws Exception {
interpreter = null;
diff --git a/plugins/org.eclipse.sirius.tree/src/org/eclipse/sirius/tree/business/internal/dialect/description/TreeInterpretedExpressionQuery.java b/plugins/org.eclipse.sirius.tree/src/org/eclipse/sirius/tree/business/internal/dialect/description/TreeInterpretedExpressionQuery.java
index 6381391c5a..a31f40d86a 100644
--- a/plugins/org.eclipse.sirius.tree/src/org/eclipse/sirius/tree/business/internal/dialect/description/TreeInterpretedExpressionQuery.java
+++ b/plugins/org.eclipse.sirius.tree/src/org/eclipse/sirius/tree/business/internal/dialect/description/TreeInterpretedExpressionQuery.java
@@ -18,6 +18,7 @@ import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.sirius.business.api.dialect.description.AbstractInterpretedExpressionQuery;
import org.eclipse.sirius.business.api.dialect.description.DefaultInterpretedExpressionTargetSwitch;
import org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionTargetSwitch;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.ext.base.Options;
import org.eclipse.sirius.tree.description.DescriptionPackage;
@@ -65,7 +66,7 @@ public class TreeInterpretedExpressionQuery extends AbstractInterpretedExpressio
* {@inheritDoc}
*/
@Override
- protected void appendAllLocalVariableDefinitions(Map<String, Collection<String>> definitions, EObject context) {
+ protected void appendAllLocalVariableDefinitions(Map<String, Collection<VariableType>> definitions, EObject context) {
super.appendAllLocalVariableDefinitions(definitions, context);
// Direct edit defines numbered variables based on their mask.
if (context instanceof TreeItemEditionTool && ((TreeItemEditionTool) context).getMask() != null) {
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java
index f8e6d37782..d6fdcc4637 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java
@@ -23,17 +23,30 @@ import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.sirius.business.api.query.EObjectQuery;
+import org.eclipse.sirius.common.tools.api.interpreter.CompoundInterpreter;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
+import org.eclipse.sirius.common.tools.api.interpreter.TypeName;
+import org.eclipse.sirius.common.tools.api.interpreter.TypedValidation;
+import org.eclipse.sirius.common.tools.api.interpreter.ValidationResult;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.common.tools.api.util.StringUtil;
import org.eclipse.sirius.ext.base.Option;
+import org.eclipse.sirius.ext.base.Options;
import org.eclipse.sirius.ext.emf.AllContents;
+import org.eclipse.sirius.tools.api.interpreter.context.SiriusInterpreterContextFactory;
import org.eclipse.sirius.viewpoint.description.JavaExtension;
import org.eclipse.sirius.viewpoint.description.RepresentationDescription;
import org.eclipse.sirius.viewpoint.description.Viewpoint;
import org.eclipse.sirius.viewpoint.description.tool.AbstractToolDescription;
import org.eclipse.sirius.viewpoint.description.tool.AbstractVariable;
+import org.eclipse.sirius.viewpoint.description.tool.ChangeContext;
import org.eclipse.sirius.viewpoint.description.tool.CreateInstance;
import org.eclipse.sirius.viewpoint.description.tool.EditMaskVariables;
+import org.eclipse.sirius.viewpoint.description.tool.ExternalJavaAction;
import org.eclipse.sirius.viewpoint.description.tool.For;
+import org.eclipse.sirius.viewpoint.description.tool.InitialOperation;
+import org.eclipse.sirius.viewpoint.description.tool.ModelOperation;
import org.eclipse.sirius.viewpoint.description.tool.ToolPackage;
import org.eclipse.sirius.viewpoint.description.tool.VariableContainer;
@@ -74,12 +87,6 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted
protected static final String VARIABLE_TYPE_KEY = "type";
/**
- * The type to use for variables for which nothing more specific could be
- * found.
- */
- protected static final String DEFAULT_VARIABLE_TYPE = "ecore.EObject";
-
- /**
* The target containing the InterpretedExpression (NodeMapping,
* ModelOperation...).
*/
@@ -112,7 +119,12 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted
* A map representing all available variables. Keys of the map are the
* variable names, and values of the map their type.
*/
- protected Map<String, String> availableVariables;
+ protected Map<String, VariableType> availableVariables;
+
+ /**
+ * The most specific type we could find for the current Receiver.
+ */
+ protected VariableType selfType;
/**
* The available {@link IInterpretedExpressionTargetSwitch} that will be
@@ -150,8 +162,24 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted
*/
public Option<Collection<String>> getTargetDomainClasses() {
if (targetDomainClass == null) {
- // Use the available TargetSwitches to get the domain class
- targetDomainClass = targetSwitch.doSwitch(target, feature != null);
+ /*
+ * the "self" variable might be redefined by a containing
+ * ModelOperation (CreateInstance, ChangeContext by example). We
+ * have to trigger the computation of the available variables as
+ * this will update the "self" type computation at the same time.
+ */
+ getAvailableVariables();
+
+ if (selfType != null && selfType.hasDefinition()) {
+ Collection<String> possibleTypes = Sets.newLinkedHashSet();
+ for (TypeName typeName : selfType.getPossibleTypes()) {
+ possibleTypes.add(typeName.getCompleteName());
+ }
+ targetDomainClass = Options.fromNullable(possibleTypes);
+ } else {
+ // Use the available TargetSwitches to get the domain class
+ targetDomainClass = targetSwitch.doSwitch(target, feature != null);
+ }
}
return targetDomainClass;
}
@@ -232,20 +260,47 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted
*
* @see org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQuery#getAvailableVariables()
*/
- public Map<String, String> getAvailableVariables() {
+ public Map<String, VariableType> getAvailableVariables() {
if (availableVariables == null) {
availableVariables = Maps.newLinkedHashMap();
}
Option<EObject> toolContext = getToolContext();
if (toolContext.some()) {
- collectContextualVariableDefinitions(availableVariables, toolContext.get(), target);
+ EObject operationContext = toolContext.get();
+ collectContextualVariableDefinitions(availableVariables, operationContext, target);
}
collectLocalVariablesDefinitions();
return availableVariables;
}
+ /**
+ * return the EObject which represents the top-level execution context.
+ *
+ * @return the EObject which represents the top-level execution context.
+ */
protected Option<EObject> getToolContext() {
- return new EObjectQuery(target).getFirstAncestorOfType(ToolPackage.eINSTANCE.getAbstractToolDescription());
+ Option<EObject> found = Options.newNone();
+ /*
+ * ValidationFix can contains operations and is not a subclas of a tool.
+ * We need to return it as the "tool context" or the logic will find the
+ * global diagram definition instead.
+ */
+ found = new EObjectQuery(target).getFirstAncestorOfType(org.eclipse.sirius.viewpoint.description.validation.ValidationPackage.eINSTANCE.getValidationRule());
+ if (!found.some()) {
+ found = new EObjectQuery(target).getFirstAncestorOfType(ToolPackage.eINSTANCE.getAbstractToolDescription());
+ if (found.some() && found.get() instanceof ExternalJavaAction) {
+ /*
+ * an ExternalJavaAction is a special case as it can also be
+ * embedded as an Operation. We need to make sure it is not the
+ * case.
+ */
+ EObject container = found.get().eContainer();
+ if (container instanceof ModelOperation || container instanceof InitialOperation) {
+ found = new EObjectQuery(container).getFirstAncestorOfType(ToolPackage.eINSTANCE.getAbstractToolDescription());
+ }
+ }
+ }
+ return found;
}
/**
@@ -273,15 +328,19 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted
* @see #TYPE_DEFINTION_SEPARATOR
*/
private void collectLocalVariablesDefinitions() {
- EAnnotation varAnnotations = feature.getEAnnotation(AbstractInterpretedExpressionQuery.VARIABLES_ANNOTATION_SOURCE);
- if (varAnnotations != null) {
- for (String varName : varAnnotations.getDetails().keySet()) {
- String doc = varAnnotations.getDetails().get(varName);
- String typeName = AbstractInterpretedExpressionQuery.DEFAULT_VARIABLE_TYPE;
- if (doc != null && doc.indexOf(AbstractInterpretedExpressionQuery.TYPE_DEFINTION_SEPARATOR) != -1) {
- typeName = doc.substring(0, doc.indexOf(AbstractInterpretedExpressionQuery.TYPE_DEFINTION_SEPARATOR)).trim();
+ if (feature != null) {
+ EAnnotation varAnnotations = feature.getEAnnotation(AbstractInterpretedExpressionQuery.VARIABLES_ANNOTATION_SOURCE);
+ if (varAnnotations != null) {
+ for (String varName : varAnnotations.getDetails().keySet()) {
+ String doc = varAnnotations.getDetails().get(varName);
+ VariableType typeName = VariableType.ANY_EOBJECT;
+ if (doc != null && doc.indexOf(AbstractInterpretedExpressionQuery.TYPE_DEFINTION_SEPARATOR) != -1) {
+ typeName = VariableType.fromString(doc.substring(0, doc.indexOf(AbstractInterpretedExpressionQuery.TYPE_DEFINTION_SEPARATOR)).trim());
+ }
+ if (!availableVariables.containsKey(varName)) {
+ availableVariables.put(varName, typeName);
+ }
}
- availableVariables.put(varName, typeName);
}
}
}
@@ -293,25 +352,63 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted
* shadowing, priority is given to the the value defined closest to
* <code>bottom</code> (lexical scoping).
*/
- private void collectContextualVariableDefinitions(Map<String, String> vars, EObject top, EObject bottom) {
+ private void collectContextualVariableDefinitions(Map<String, VariableType> vars, EObject top, EObject bottom) {
// A map with multiple values is not strictly required as we only use
// one value, but it is useful when debugging to have all the
// information.
- Map<String, Collection<String>> definitions = Maps.newHashMap();
+ Map<String, Collection<VariableType>> definitions = Maps.newHashMap();
// Walk up from bottom to top and gather every definition in the scope.
EObject context = bottom;
- do {
+
+ while (context != null && context != top.eContainer()) {
appendAllLocalVariableDefinitions(definitions, context);
- context = precedingSiblingOrContainer(context);
- } while (context != null && context != top.eContainer());
+ if (context instanceof ChangeContext && context != bottom) {
+ ChangeContext f = (ChangeContext) context;
+
+ IInterpreter interpreterForExpression = CompoundInterpreter.INSTANCE.getInterpreterForExpression(f.getBrowseExpression());
+
+ if (interpreterForExpression.supportsValidation() && interpreterForExpression instanceof TypedValidation) {
+ IInterpreterContext iContext = SiriusInterpreterContextFactory.createInterpreterContext(f, ToolPackage.Literals.CHANGE_CONTEXT__BROWSE_EXPRESSION);
+ ValidationResult res = ((TypedValidation) interpreterForExpression).analyzeExpression(iContext, f.getBrowseExpression());
+ VariableType returnTypes = res.getReturnTypes();
+ changeSelfType(definitions, returnTypes);
+ }
+
+ }
+ if (context instanceof CreateInstance) {
+ CreateInstance f = (CreateInstance) context;
+ changeSelfType(definitions, VariableType.fromString(f.getTypeName()));
+ }
+ if (context != top) {
+ EObject sibling = precedingSibling(context);
+ while (sibling != null) {
+ appendAllLocalVariableDefinitions(definitions, sibling);
+ sibling = precedingSibling(sibling);
+ }
+ }
+ context = context.eContainer();
+
+ }
+
// Merge all the definitions, by taking the one closest to
// <code>bottom</code> when there are multiple ones.
for (String var : definitions.keySet()) {
- vars.put(var, ((List<String>) definitions.get(var)).get(0));
+ vars.put(var, ((List<VariableType>) definitions.get(var)).get(0));
+ }
+ }
+
+ private void changeSelfType(Map<String, Collection<VariableType>> definitions, VariableType returnTypes) {
+ /*
+ * We only set the self type once as we are browsing the model from most
+ * to less specific. The first assignation will be the most specific,
+ * further assignations should not be considered.
+ */
+ if (selfType == null) {
+ selfType = returnTypes;
}
}
- private EObject precedingSiblingOrContainer(EObject context) {
+ private EObject precedingSibling(EObject context) {
EObject container = context.eContainer();
EStructuralFeature containingFeature = context.eContainingFeature();
if (container != null && containingFeature != null) {
@@ -334,8 +431,7 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted
}
}
}
-
- return container;
+ return null;
}
/**
@@ -348,14 +444,14 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted
* {@link #DEFAULT_VARIABLE_TYPE} if nothing more specified was
* specified in the meta-model.
*/
- protected String getVariableTypeName(AbstractVariable var) {
+ protected VariableType getVariableTypeName(AbstractVariable var) {
Preconditions.checkNotNull(var);
Preconditions.checkNotNull(var.eContainingFeature());
- String typeName = AbstractInterpretedExpressionQuery.DEFAULT_VARIABLE_TYPE;
+ VariableType typeName = VariableType.ANY_EOBJECT;
EAnnotation varAnnotation = var.eContainingFeature().getEAnnotation(AbstractInterpretedExpressionQuery.VARIABLES_ANNOTATION_SOURCE);
if (varAnnotation != null && varAnnotation.getDetails().containsKey(AbstractInterpretedExpressionQuery.VARIABLE_TYPE_KEY)) {
- typeName = varAnnotation.getDetails().get(AbstractInterpretedExpressionQuery.VARIABLE_TYPE_KEY);
+ typeName = VariableType.fromString(varAnnotation.getDetails().get(AbstractInterpretedExpressionQuery.VARIABLE_TYPE_KEY));
}
return typeName;
}
@@ -372,7 +468,7 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted
* @param context
* the element which may define new variables.
*/
- protected void appendAllLocalVariableDefinitions(Map<String, Collection<String>> definitions, EObject context) {
+ protected void appendAllLocalVariableDefinitions(Map<String, Collection<VariableType>> definitions, EObject context) {
// Tool definitions can contain variables, but they do not share a
// common type/feature name for this containment, so we must do a
// eAllContent(). This is ugly, and possibly broken if AbstractVariables
@@ -405,8 +501,9 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted
// reference the newly created instance.
if (context instanceof For) {
For f = (For) context;
- addDefinition(definitions, f.getIteratorName(), AbstractInterpretedExpressionQuery.DEFAULT_VARIABLE_TYPE);
+ addDefinition(definitions, f.getIteratorName(), VariableType.ANY_EOBJECT);
}
+
}
/**
@@ -421,7 +518,7 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted
* @param definitions
* the set of variables definition to which to append.
*/
- protected void appendEditMaskVariables(EditMaskVariables mask, Map<String, Collection<String>> definitions) {
+ protected void appendEditMaskVariables(EditMaskVariables mask, Map<String, Collection<VariableType>> definitions) {
Pattern p = Pattern.compile("\\{\\d\\}");
Matcher m = p.matcher(mask.getMask());
while (m.find()) {
@@ -445,12 +542,26 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted
* @param value
* the value of the variable to (re-)define.
*/
- protected void addDefinition(Map<String, Collection<String>> definitions, String name, String value) {
- Collection<String> defs = definitions.get(name);
+ protected void addDefinition(Map<String, Collection<VariableType>> definitions, String name, String value) {
+ addDefinition(definitions, name, VariableType.fromString(value));
+ }
+
+ /**
+ * Add a new definition for a variable, shadowing any previously added ones.
+ *
+ * @param definitions
+ * the definitions of all the variables.
+ * @param name
+ * the name of the variable to (re-)define.
+ * @param type
+ * the variable type
+ */
+ protected void addDefinition(Map<String, Collection<VariableType>> definitions, String name, VariableType type) {
+ Collection<VariableType> defs = definitions.get(name);
if (defs == null) {
defs = Lists.newArrayList();
definitions.put(name, defs);
}
- defs.add(value);
+ defs.add(type);
}
}
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/IInterpretedExpressionQuery.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/IInterpretedExpressionQuery.java
index 4ff26aaf6a..f180265de2 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/IInterpretedExpressionQuery.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/IInterpretedExpressionQuery.java
@@ -14,6 +14,7 @@ import java.util.Collection;
import java.util.Map;
import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.ext.base.Option;
/**
@@ -56,6 +57,6 @@ public interface IInterpretedExpressionQuery {
*
* @return a map representing all available variables
*/
- Map<String, String> getAvailableVariables();
+ Map<String, VariableType> getAvailableVariables();
}
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/api/interpreter/context/SiriusInterpreterContextFactory.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/api/interpreter/context/SiriusInterpreterContextFactory.java
index 0e37b85fc4..b9aefe57a8 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/api/interpreter/context/SiriusInterpreterContextFactory.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/api/interpreter/context/SiriusInterpreterContextFactory.java
@@ -20,6 +20,7 @@ import org.eclipse.sirius.business.api.dialect.DialectManager;
import org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQuery;
import org.eclipse.sirius.common.tools.api.interpreter.DefaultInterpreterContextFactory;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
+import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.ext.base.Option;
import com.google.common.collect.Maps;
@@ -57,7 +58,7 @@ public final class SiriusInterpreterContextFactory {
Collection<String> targetDomainClasses = Sets.newLinkedHashSet();
Collection<EPackage> avalaiblePackages = Sets.newLinkedHashSet();
Collection<String> dependencies = Sets.newLinkedHashSet();
- Map<String, String> variables = Maps.newLinkedHashMap();
+ Map<String, VariableType> variables = Maps.newLinkedHashMap();
boolean requiresTargetType = true;
// Step 1 : getting the InterpretedExpressionQuery from the given
@@ -72,7 +73,9 @@ public final class SiriusInterpreterContextFactory {
if (!targetDomainClassesOption.some()) {
requiresTargetType = false;
} else {
- targetDomainClasses = targetDomainClassesOption.get();
+ for (String domainClass : targetDomainClassesOption.get()) {
+ targetDomainClasses.add(domainClass);
+ }
}
if (!targetDomainClassesOption.some() || !targetDomainClassesOption.get().isEmpty()) {
@@ -88,7 +91,8 @@ public final class SiriusInterpreterContextFactory {
}
// Step 5 : building the IInterpretedContext
- IInterpreterContext context = DefaultInterpreterContextFactory.createInterpreterContext(element, requiresTargetType, feature, targetDomainClasses, avalaiblePackages, variables, dependencies);
+ IInterpreterContext context = DefaultInterpreterContextFactory.createInterpreterContext(element, requiresTargetType, feature, VariableType.fromStrings(targetDomainClasses), avalaiblePackages,
+ variables, dependencies);
return context;
}
}
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/interpreter/ODesignGenericInterpreter.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/interpreter/ODesignGenericInterpreter.java
index 456ac48246..85c248a24d 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/interpreter/ODesignGenericInterpreter.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/interpreter/ODesignGenericInterpreter.java
@@ -54,8 +54,8 @@ public class ODesignGenericInterpreter implements IInterpreter, IProposalProvide
private Collection<String> dependencies = Sets.newLinkedHashSet();
/**
- * If Sirius knows of any additional metamodel that may be necessary for
- * the interpreter, they'll be registered here.
+ * If Sirius knows of any additional metamodel that may be necessary for the
+ * interpreter, they'll be registered here.
*/
private Collection<MetamodelDescriptor> additionalMetamodels = Sets.newLinkedHashSet();

Back to the top