diff --git a/plugins/org.etsi.mts.tdl.common/.classpath b/plugins/org.etsi.mts.tdl.common/.classpath
new file mode 100644
index 0000000000000000000000000000000000000000..e801ebfb4680123285c15553dc70584276fe0057
--- /dev/null
+++ b/plugins/org.etsi.mts.tdl.common/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/plugins/org.etsi.mts.tdl.common/.project b/plugins/org.etsi.mts.tdl.common/.project
new file mode 100644
index 0000000000000000000000000000000000000000..e3eceb4c269e1dac398005d668d11f8dcda030c8
--- /dev/null
+++ b/plugins/org.etsi.mts.tdl.common/.project
@@ -0,0 +1,28 @@
+
+
+ org.etsi.mts.tdl.common
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/plugins/org.etsi.mts.tdl.common/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.common/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..c9545f06a4120d5b4a1228fb19f67a1171bc0f5b
--- /dev/null
+++ b/plugins/org.etsi.mts.tdl.common/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,9 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=11
diff --git a/plugins/org.etsi.mts.tdl.common/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.common/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..f3c568bf24413de831191d7277ebefccffbe20df
--- /dev/null
+++ b/plugins/org.etsi.mts.tdl.common/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Common
+Bundle-SymbolicName: org.etsi.mts.tdl.common
+Bundle-Version: 1.0.0.qualifier
+Automatic-Module-Name: org.etsi.mts.tdl.common
+Bundle-RequiredExecutionEnvironment: JavaSE-11
+Require-Bundle: org.eclipse.xtext,
+ org.etsi.mts.tdl.model,
+ org.eclipse.xtext.xbase,
+ org.eclipse.equinox.common;bundle-version="3.5.0",
+ org.eclipse.xtext.xbase.lib;bundle-version="2.14.0",
+ org.antlr.runtime;bundle-version="[3.2.0,3.2.1)",
+ org.eclipse.xtext.util,
+ org.eclipse.xtend.lib
+Export-Package: org.etsi.mts.tdl.scoping
diff --git a/plugins/org.etsi.mts.tdl.common/build.properties b/plugins/org.etsi.mts.tdl.common/build.properties
new file mode 100644
index 0000000000000000000000000000000000000000..34d2e4d2dad529ceaeb953bfcdb63c51d69ffed2
--- /dev/null
+++ b/plugins/org.etsi.mts.tdl.common/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/scoping/TDLScopeProvider.java b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/scoping/TDLScopeProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..44dccf46665a0b64f03425d8081b06772333b8d1
--- /dev/null
+++ b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/scoping/TDLScopeProvider.java
@@ -0,0 +1,402 @@
+package org.etsi.mts.tdl.scoping;
+
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.xtext.naming.IQualifiedNameConverter;
+import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.nodemodel.ICompositeNode;
+import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
+import org.eclipse.xtext.scoping.IScope;
+import org.eclipse.xtext.scoping.Scopes;
+import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
+import org.etsi.mts.tdl.Action;
+import org.etsi.mts.tdl.ActionReference;
+import org.etsi.mts.tdl.Assignment;
+import org.etsi.mts.tdl.Behaviour;
+import org.etsi.mts.tdl.Block;
+import org.etsi.mts.tdl.ComponentInstance;
+import org.etsi.mts.tdl.ComponentInstanceBinding;
+import org.etsi.mts.tdl.Connection;
+import org.etsi.mts.tdl.DataElementMapping;
+import org.etsi.mts.tdl.DataInstanceUse;
+import org.etsi.mts.tdl.DataType;
+import org.etsi.mts.tdl.DataUse;
+import org.etsi.mts.tdl.Element;
+import org.etsi.mts.tdl.ElementImport;
+import org.etsi.mts.tdl.Extension;
+import org.etsi.mts.tdl.FormalParameterUse;
+import org.etsi.mts.tdl.FunctionCall;
+import org.etsi.mts.tdl.GateInstance;
+import org.etsi.mts.tdl.GateReference;
+import org.etsi.mts.tdl.LocalExpression;
+import org.etsi.mts.tdl.MemberAssignment;
+import org.etsi.mts.tdl.MemberReference;
+import org.etsi.mts.tdl.Message;
+import org.etsi.mts.tdl.Package;
+import org.etsi.mts.tdl.PackageableElement;
+import org.etsi.mts.tdl.Parameter;
+import org.etsi.mts.tdl.ParameterBinding;
+import org.etsi.mts.tdl.ParameterMapping;
+import org.etsi.mts.tdl.ProcedureCall;
+import org.etsi.mts.tdl.SimpleDataInstance;
+import org.etsi.mts.tdl.SimpleDataType;
+import org.etsi.mts.tdl.StructuredDataInstance;
+import org.etsi.mts.tdl.StructuredDataType;
+import org.etsi.mts.tdl.Target;
+import org.etsi.mts.tdl.TestConfiguration;
+import org.etsi.mts.tdl.TestDescription;
+import org.etsi.mts.tdl.TestDescriptionReference;
+import org.etsi.mts.tdl.Timer;
+import org.etsi.mts.tdl.TimerOperation;
+import org.etsi.mts.tdl.ValueAssignment;
+import org.etsi.mts.tdl.Variable;
+import org.etsi.mts.tdl.VariableUse;
+import org.etsi.mts.tdl.tdlPackage;
+import org.etsi.mts.tdl.structuredobjectives.StructuredTestObjective;
+
+import com.google.common.base.Function;
+import com.google.inject.Inject;
+
+/**
+ * This class contains custom scoping description.
+ *
+ * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping on
+ * how and when to use it
+ *
+ */
+public class TDLScopeProvider extends AbstractDeclarativeScopeProvider {
+ @Inject
+ private IQualifiedNameConverter qualifiedNameConverter;
+
+ @Override
+ public IScope getScope(EObject context, EReference reference) {
+ if (PackageableElement.class.isAssignableFrom(reference.getEType().getInstanceClass())
+ && !(context instanceof ElementImport)) {
+ EList elements = getScopedElementsOfType(context, reference.getEType().getInstanceClass());
+ return Scopes.scopeFor(elements);
+ }
+ if (reference.getEType().getInstanceClass() == GateInstance.class) {
+ if (context instanceof GateReference) {
+ GateReference gate = (GateReference) context;
+ if (gate.getComponent().getType()!=null) {
+ IScope scope = Scopes.scopeFor(gate.getComponent().getType().allGates());
+ return scope;
+ }
+ }
+ } else if (reference.getEType().getInstanceClass() == ComponentInstance.class) {
+ if (context instanceof Behaviour || context instanceof Block || context instanceof LocalExpression || context instanceof VariableUse) {
+ TestDescription testDescription = getTestDescription((Element) context);
+ if (testDescription!=null) {
+ TestConfiguration configuration = testDescription.getTestConfiguration();
+ IScope scope = Scopes.scopeFor(configuration.getComponentInstance());
+ return scope;
+ }
+ } else if (context instanceof GateReference) {
+ TestConfiguration configuration = getTestConfiguration((Element) context);
+ EList components = configuration.getComponentInstance();
+ IScope scope = Scopes.scopeFor(components);
+ return scope;
+ } else if (context instanceof ComponentInstanceBinding) {
+ //assume actual
+ TestDescription testDescription = getTestDescription((Element) context);
+ if (reference.getFeatureID() == tdlPackage.COMPONENT_INSTANCE_BINDING__FORMAL_COMPONENT) {
+ testDescription = ((TestDescriptionReference)context.eContainer()).getTestDescription();
+ }
+ TestConfiguration configuration = testDescription.getTestConfiguration();
+ EList components = configuration.getComponentInstance();
+ IScope scope = Scopes.scopeFor(components);
+ return scope;
+ }
+ } else if (reference.getEType().getInstanceClass() == GateReference.class) {
+ //TODO: safety checks in case invalid configuration is specified
+ //TODO: only suggest connected gates as targets?
+
+ if (context instanceof Behaviour || context instanceof Target || context instanceof Block) {
+ TestConfiguration configuration = getTestDescription((Element) context).getTestConfiguration();
+ EList elements = new BasicEList<>();
+ for (Connection c : configuration.getConnection()) {
+ if (context instanceof Message) {
+ //TODO: quick hack until a better solution is found
+ ICompositeNode oppositeNode = NodeModelUtils.findActualNodeFor(((Message) context).getTarget().get(0));
+ if (oppositeNode != null) {
+ String targetGateName = oppositeNode.getText()
+ .replaceAll("(?s)where\\s+it\\s+is.+", "")
+ .replaceAll("(?s)with\\s*\\{.+", "")
+ .trim();
+ String[] split = targetGateName.split("\\.");
+ if (split.length == 2) {
+ String gate = split[1];
+ String component = split[0];
+ if (component.equals(c.getEndPoint().get(0).getComponent().getName()) &&
+ gate.equals(c.getEndPoint().get(0).getGate().getName())) {
+ elements.add(c.getEndPoint().get(1));
+ } else if (component.equals(c.getEndPoint().get(1).getComponent().getName()) &&
+ gate.equals(c.getEndPoint().get(1).getGate().getName())) {
+ elements.add(c.getEndPoint().get(0));
+ }
+ } else {
+ //TODO: handle?
+ }
+ }
+
+// GateReference opposite = ((Message) context).getTarget().get(0).getTargetGate();
+// if (c.getEndPoint().get(0) == opposite) {
+// elements.add(c.getEndPoint().get(1));
+// } else if (c.getEndPoint().get(1) == opposite) {
+// elements.add(c.getEndPoint().get(0));
+// }
+ } else if (context instanceof Target) {
+ GateReference opposite = null;
+ if (context.eContainer() instanceof Message) {
+ opposite = ((Message) context.eContainer()).getSourceGate();
+ } else {
+ opposite = ((ProcedureCall) context.eContainer()).getSourceGate();
+ }
+ if (c.getEndPoint().get(0) == opposite) {
+ elements.add(c.getEndPoint().get(1));
+ } else if (c.getEndPoint().get(1) == opposite) {
+ elements.add(c.getEndPoint().get(0));
+ }
+ } else {
+ elements.addAll(c.getEndPoint());
+ }
+
+ }
+
+ IScope scope = Scopes.scopeFor(elements, new Function() {
+ @Override
+ public QualifiedName apply(EObject o) {
+ GateReference r = (GateReference) o;
+ String n = r.getComponent().getName()+"."+r.getGate().getName();
+ QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(n);
+ return qualifiedName;
+ }
+
+ }, IScope.NULLSCOPE);
+
+ return scope;
+ }
+ } else if (Parameter.class.isAssignableFrom(reference.getEType().getInstanceClass())) {
+ if (context instanceof MemberAssignment) {
+ if (context.eContainer() instanceof StructuredDataInstance && ((StructuredDataInstance)context.eContainer()).getDataType() instanceof StructuredDataType) {
+ IScope scope = Scopes.scopeFor(((StructuredDataType)((StructuredDataInstance)context.eContainer()).getDataType()).allMembers());
+ return scope;
+ }
+ } else if (context instanceof ParameterMapping) {
+ if (context.eContainer() instanceof DataElementMapping) {
+ if (((DataElementMapping)context.eContainer()).getMappableDataElement() instanceof StructuredDataType) {
+ IScope scope = Scopes.scopeFor(((StructuredDataType)((DataElementMapping)context.eContainer()).getMappableDataElement()).allMembers());
+ return scope;
+ } else if (((DataElementMapping)context.eContainer()).getMappableDataElement() instanceof Action) {
+ IScope scope = Scopes.scopeFor(((Action)((DataElementMapping)context.eContainer()).getMappableDataElement()).getFormalParameter());
+ return scope;
+ }
+ }
+ } else if (context instanceof ParameterBinding) {
+ if (context.eContainer() instanceof DataInstanceUse) {
+ if (((DataInstanceUse)context.eContainer()).getDataInstance() instanceof StructuredDataInstance) {
+ IScope scope = Scopes.scopeFor(((StructuredDataType)((StructuredDataInstance)((DataInstanceUse)context.eContainer()).getDataInstance()).getDataType()).allMembers());
+ return scope;
+ } else if (((DataInstanceUse)context.eContainer()).getDataType() instanceof StructuredDataType) {
+ IScope scope = Scopes.scopeFor(((StructuredDataType)((DataInstanceUse)context.eContainer()).getDataType()).allMembers());
+ return scope;
+ } else if (context.eContainer().eContainer() instanceof MemberAssignment) {
+ DataType dataType = ((MemberAssignment)context
+ .eContainer()
+ .eContainer())
+ .getMember()
+ .getDataType();
+ if (dataType!=null) {
+ IScope scope = Scopes.scopeFor(((StructuredDataType)dataType)
+ .allMembers());
+ return scope;
+ }
+ } else if (context.eContainer().eContainer() instanceof ParameterBinding) {
+ IScope scope = Scopes.scopeFor(((StructuredDataType)((ParameterBinding)context.eContainer().eContainer()).getParameter().getDataType()).allMembers());
+ return scope;
+ }
+ } else if (context.eContainer() instanceof FunctionCall) {
+// if (((FunctionCall)context.eContainer()).getFunction().get instanceof StructuredDataInstance) {
+ IScope scope = Scopes.scopeFor(((FunctionCall)context.eContainer()).getFunction().getFormalParameter());
+ return scope;
+// }
+ } else if (context.eContainer() instanceof ActionReference) {
+// if (((FunctionCall)context.eContainer()).getFunction().get instanceof StructuredDataInstance) {
+ IScope scope = Scopes.scopeFor(((ActionReference)context.eContainer()).getAction().getFormalParameter());
+ return scope;
+// }
+ } else if (context.eContainer() instanceof TestDescriptionReference) {
+// if (((FunctionCall)context.eContainer()).getFunction().get instanceof StructuredDataInstance) {
+ IScope scope = Scopes.scopeFor(((TestDescriptionReference)context.eContainer()).getTestDescription().getFormalParameter());
+ return scope;
+// }
+ } else if (context.eContainer() instanceof FormalParameterUse) {
+ IScope scope = Scopes.scopeFor(((StructuredDataType)((FormalParameterUse)context.eContainer()).getParameter().getDataType()).allMembers());
+ return scope;
+ } else if (context.eContainer() instanceof VariableUse) {
+ IScope scope = Scopes.scopeFor(((StructuredDataType)((VariableUse)context.eContainer()).getVariable().getDataType()).allMembers());
+ return scope;
+ } else if (context.eContainer() instanceof ProcedureCall) {
+// if (((FunctionCall)context.eContainer()).getFunction().get instanceof StructuredDataInstance) {
+ IScope scope = Scopes.scopeFor(((ProcedureCall)context.eContainer()).getSignature().getParameter());
+ return scope;
+// }
+ }
+ } else if (context instanceof MemberReference) {
+ if (((DataUse)context.eContainer()).getReduction().indexOf(context)>0) {
+ EObject targetContext = ((DataUse)context.eContainer()).getReduction().get(((DataUse)context.eContainer()).getReduction().indexOf(context)-1);
+ if (((MemberReference)targetContext).getMember()!=null) {
+ if (((MemberReference)targetContext).getMember().getDataType() instanceof StructuredDataType) {
+ IScope scope = Scopes.scopeFor(((StructuredDataType)((MemberReference)targetContext).getMember().getDataType()).allMembers());
+ return scope;
+ }
+ }
+ }
+ if (context.eContainer() instanceof DataInstanceUse) {
+ if (((DataInstanceUse)context.eContainer()).getDataInstance() instanceof StructuredDataInstance) {
+ IScope scope = Scopes.scopeFor(((StructuredDataType)((StructuredDataInstance)((DataInstanceUse)context.eContainer()).getDataInstance()).getDataType()).allMembers());
+ return scope;
+ }
+ } else if (context.eContainer() instanceof FunctionCall) {
+ if (((FunctionCall)context.eContainer()).getFunction().getReturnType() instanceof StructuredDataType) {
+ IScope scope = Scopes.scopeFor(((StructuredDataType)((FunctionCall)context.eContainer()).getFunction().getReturnType()).allMembers());
+ return scope;
+ }
+ } else if (context.eContainer() instanceof FormalParameterUse) {
+ if (((FormalParameterUse)context.eContainer()).getParameter().getDataType() instanceof StructuredDataType) {
+ IScope scope = Scopes.scopeFor(((StructuredDataType)((FormalParameterUse)context.eContainer()).getParameter().getDataType()).allMembers());
+ return scope;
+ }
+ } else if (context.eContainer() instanceof VariableUse) {
+ if (((VariableUse)context.eContainer()).getVariable().getDataType() instanceof StructuredDataType) {
+ IScope scope = Scopes.scopeFor(((StructuredDataType)((VariableUse)context.eContainer()).getVariable().getDataType()).allMembers());
+ return scope;
+ }
+ } else {
+ }
+ }
+ } else if (reference.getEType().getInstanceClass() == Variable.class) {
+ if (context instanceof Assignment) {
+ if (((Assignment)context).getComponentInstance()!=null) {
+ IScope scope = Scopes.scopeFor(((Assignment)context).getComponentInstance().getType().allVariables());
+ return scope;
+ }
+ }
+ if (context instanceof VariableUse) {
+ if (((VariableUse)context).getComponentInstance()!=null) {
+ IScope scope = Scopes.scopeFor(((VariableUse)context).getComponentInstance().getType().allVariables());
+ return scope;
+ }
+ }
+ else if (context instanceof ValueAssignment) {
+ if (((Target)context.eContainer()).getTargetGate().getComponent()!=null) {
+ IScope scope = Scopes.scopeFor(((Target)context.eContainer()).getTargetGate().getComponent().getType().allVariables());
+ return scope;
+ }
+ }
+ } else if (reference.getEType().getInstanceClass() == Timer.class) {
+ if (context instanceof TimerOperation) {
+ IScope scope = Scopes.scopeFor(((TimerOperation)context).getComponentInstance().getType().allTimers());
+ return scope;
+ }
+ } else if (context instanceof Extension) {
+ EList elements = getScopedElementsOfType(context, ((Element)context.eContainer()).getClass());
+ return Scopes.scopeFor(elements);
+ } else {
+ }
+
+
+ if (context instanceof Block) {
+ TestDescription testDescription = getTestDescription((Element) context);
+ if (testDescription!=null) {
+ TestConfiguration configuration = testDescription.getTestConfiguration();
+ IScope scope = Scopes.scopeFor(configuration.getComponentInstance());
+ return scope;
+ }
+ }
+ return super.getScope(context, reference);
+ }
+
+ private TestConfiguration getTestConfiguration(Element self) {
+ if (self.eContainer()!=null) {
+ if (!(self.eContainer() instanceof TestConfiguration)) {
+ return getTestConfiguration((Element) self.eContainer());
+ } else {
+ return (TestConfiguration)self.eContainer();
+ }
+ }
+ return null;
+ }
+
+
+ private TestDescription getTestDescription(Element self) {
+ if (self.eContainer()!=null) {
+ if (!(self.eContainer() instanceof TestDescription)) {
+ return getTestDescription((Element) self.eContainer());
+ } else {
+ return (TestDescription)self.eContainer();
+ }
+ }
+ return null;
+ }
+
+ public IScope scope_ElementImport_importedElement(ElementImport context, EReference ref) {
+ EList elements = new BasicEList<>();
+ Package ip = context.getImportedPackage();
+ for (PackageableElement e : ip.getPackagedElement()) {
+ elements.add(e);
+ }
+ IScope scope = Scopes.scopeFor(elements);
+ return scope;
+ }
+
+ private Package getPackage(EObject e) {
+ if (e.eContainer()!=null) {
+ if (e.eContainer() instanceof Package) {
+ return (Package)e.eContainer();
+ } else {
+ return getPackage(e.eContainer());
+ }
+ } else {
+ return (Package)e;
+ }
+ }
+
+ private EList getScopedElementsOfType(EObject context, Class c) {
+ EList elements = new BasicEList<>();
+ Package p = getPackage(context);
+
+ //within same package
+ for (PackageableElement e : p.getPackagedElement()) {
+ if (c.isInstance(e)) {
+ elements.add(e);
+ }
+ }
+
+ //within imported packages
+ for (ElementImport i : p.getImport()) {
+ Package ip = i.getImportedPackage();
+ if (ip != null) {
+ if (i.getImportedElement().isEmpty()) {
+ //import all
+ for (PackageableElement e : ip.getPackagedElement()) {
+ if (c.isInstance(e)) {
+ elements.add(e);
+ }
+ }
+ } else {
+ //specific imports
+ for (PackageableElement e : i.getImportedElement()) {
+ if (c.isInstance(e)) {
+ elements.add(e);
+ }
+ }
+ }
+ }
+ }
+ return elements;
+ }
+
+}
\ No newline at end of file