Newer
Older
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.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.DataUse;
import org.etsi.mts.tdl.ElementImport;
import org.etsi.mts.tdl.FormalParameterUse;
import org.etsi.mts.tdl.FunctionCall;
import org.etsi.mts.tdl.GateInstance;
import org.etsi.mts.tdl.GateReference;
Philip Makedonski
committed
import org.etsi.mts.tdl.LocalExpression;
import org.etsi.mts.tdl.Member;
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.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.VariableUse;
import org.etsi.mts.tdl.tdlPackage;
import org.etsi.mts.tdl.impl.ComponentInstanceBindingImpl;
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 TDLan2ScopeProvider 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<EObject> 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().getGateInstance());
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<ComponentInstance> 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.eINSTANCE.COMPONENT_INSTANCE_BINDING__FORMAL_COMPONENT) {
testDescription = ((TestDescriptionReference)context.eContainer()).getTestDescription();
}
TestConfiguration configuration = testDescription.getTestConfiguration();
EList<ComponentInstance> 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<EObject> elements = new BasicEList<>();
for (Connection c : configuration.getConnection()) {
if (context instanceof Message) {
Philip Makedonski
committed
//TODO: quick hack until a better solution is found
ICompositeNode oppositeNode = NodeModelUtils.findActualNodeFor(((Message) context).getTarget().get(0));
Philip Makedonski
committed
String targetGateName = oppositeNode.getText().replaceAll("where\\s+it\\s+is.+", "").trim();
String[] split = targetGateName.split("\\.");
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));
}
// 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 = ((Message) 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());
}
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
}
IScope scope = Scopes.scopeFor(elements, new Function<EObject, QualifiedName>() {
@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) {
IScope scope = Scopes.scopeFor(((StructuredDataType)((StructuredDataInstance)context.eContainer()).getDataType()).getMember());
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()).getMember());
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()).getMember());
return scope;
} else if (context.eContainer().eContainer() instanceof MemberAssignment) {
IScope scope = Scopes.scopeFor(((StructuredDataType)((MemberAssignment)context.eContainer().eContainer()).getMember().getDataType()).getMember());
return scope;
} else if (((DataInstanceUse)context.eContainer()).getDataType() instanceof StructuredDataType) {
IScope scope = Scopes.scopeFor(((StructuredDataType)((DataInstanceUse)context.eContainer()).getDataType()).getMember());
return scope;
} else if (context.eContainer().eContainer() instanceof ParameterBinding) {
IScope scope = Scopes.scopeFor(((StructuredDataType)((ParameterBinding)context.eContainer().eContainer()).getParameter().getDataType()).getMember());
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()).getMember());
return scope;
} else if (context.eContainer() instanceof VariableUse) {
IScope scope = Scopes.scopeFor(((StructuredDataType)((VariableUse)context.eContainer()).getVariable().getDataType()).getMember());
} 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()).getMember());
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()).getMember());
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()).getMember());
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()).getMember());
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()).getMember());
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().getVariable());
return scope;
Philip Makedonski
committed
}
}
if (context instanceof VariableUse) {
if (((VariableUse)context).getComponentInstance()!=null) {
IScope scope = Scopes.scopeFor(((VariableUse)context).getComponentInstance().getType().getVariable());
return scope;
}
}
else if (context instanceof ValueAssignment) {
if (((Target)context.eContainer()).getTargetGate().getComponent()!=null) {
IScope scope = Scopes.scopeFor(((Target)context.eContainer()).getTargetGate().getComponent().getType().getVariable());
Philip Makedonski
committed
return scope;
} else if (reference.getEType().getInstanceClass() == Timer.class) {
IScope scope = Scopes.scopeFor(((TimerOperation)context).getComponentInstance().getType().getTimer());
return scope;
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();
}
}
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
return null;
}
public IScope scope_ElementImport_importedElement(ElementImport context, EReference ref) {
EList<EObject> 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<EObject> getScopedElementsOfType(EObject context, Class c) {
EList<EObject> 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;