From 4559a6581bf85c03cc7fefadb831e35a83be8be6 Mon Sep 17 00:00:00 2001 From: Philip Makedonski Date: Fri, 26 Jun 2020 22:31:05 +0200 Subject: [PATCH] + added common scope provider --- plugins/org.etsi.mts.tdl.common/.classpath | 7 + plugins/org.etsi.mts.tdl.common/.project | 28 ++ .../.settings/org.eclipse.jdt.core.prefs | 9 + .../META-INF/MANIFEST.MF | 16 + .../org.etsi.mts.tdl.common/build.properties | 4 + .../mts/tdl/scoping/TDLScopeProvider.java | 402 ++++++++++++++++++ 6 files changed, 466 insertions(+) create mode 100644 plugins/org.etsi.mts.tdl.common/.classpath create mode 100644 plugins/org.etsi.mts.tdl.common/.project create mode 100644 plugins/org.etsi.mts.tdl.common/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/org.etsi.mts.tdl.common/META-INF/MANIFEST.MF create mode 100644 plugins/org.etsi.mts.tdl.common/build.properties create mode 100644 plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/scoping/TDLScopeProvider.java diff --git a/plugins/org.etsi.mts.tdl.common/.classpath b/plugins/org.etsi.mts.tdl.common/.classpath new file mode 100644 index 00000000..e801ebfb --- /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 00000000..e3eceb4c --- /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 00000000..c9545f06 --- /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 00000000..f3c568bf --- /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 00000000..34d2e4d2 --- /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 00000000..44dccf46 --- /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 -- GitLab