use of org.eclipse.n4js.n4JS.ControlFlowElement in project n4js by eclipse.
the class CFGraph method build.
@Override
public void build(CFGraphProvider provider, Object input) {
clear();
nodeMap.clear();
gProvider = provider;
Collection<ControlFlowElement> cfes = gProvider.getElements(input);
for (ControlFlowElement cfe : cfes) {
if (cfe instanceof Script) {
continue;
}
if (FGUtils.isCFContainer(cfe)) {
CFNode entryNode = gProvider.getEntryNode(cfe);
CFNode exitNode = gProvider.getExitNode(cfe);
nodeMap.put(entryNode, entryNode.getControlFlowElement());
nodeMap.put(exitNode, exitNode.getControlFlowElement());
nodes.add(entryNode);
nodes.add(exitNode);
List<Edge> succs = gProvider.getConnectedEdges(entryNode, null);
edges.addAll(succs);
} else {
CFNode node = gProvider.getNode(cfe);
nodes.add(node);
nodeMap.put(node, cfe);
List<Edge> succs = gProvider.getConnectedEdges(node, null);
edges.addAll(succs);
}
}
}
use of org.eclipse.n4js.n4JS.ControlFlowElement in project n4js by eclipse.
the class FlowgraphsXpectMethod method astOrder.
/**
* This xpect method can evaluate the direct predecessors of a code element. The predecessors can be limited when
* specifying the edge type.
* <p>
* <b>Attention:</b> The type parameter <i>does not</i> work on self loops!
*/
@ParameterParser(syntax = "('of' arg2=OFFSET)?")
@Xpect
public void astOrder(@N4JSCommaSeparatedValuesExpectation IN4JSCommaSeparatedValuesExpectation expectation, IEObjectCoveringRegion offset) {
EObject context = offset.getEObject();
Iterator<ControlFlowElement> astIter = new ASTIterator(context);
int idx = 0;
List<String> astElements = new LinkedList<>();
while (astIter.hasNext()) {
ControlFlowElement cfe = astIter.next();
String elem = idx + ": " + FGUtils.getSourceText(cfe);
astElements.add(elem);
idx++;
}
expectation.assertEquals(astElements);
}
use of org.eclipse.n4js.n4JS.ControlFlowElement in project n4js by eclipse.
the class FlowgraphsXpectMethod method path.
/**
* This xpect method can evaluate if the tested element is a transitive predecessor of the given element.
*/
@ParameterParser(syntax = "'from' arg0=OFFSET ('to' arg1=OFFSET)? ('notTo' arg2=OFFSET)? ('via' arg3=OFFSET)? ('notVia' arg4=OFFSET)? ('pleaseNeverUseThisParameterSinceItExistsOnlyToGetAReferenceOffset' arg5=OFFSET)?")
@Xpect
public void path(IEObjectCoveringRegion fromOffset, IEObjectCoveringRegion toOffset, IEObjectCoveringRegion notToOffset, IEObjectCoveringRegion viaOffset, IEObjectCoveringRegion notViaOffset, IEObjectCoveringRegion referenceOffset) {
EObjectCoveringRegion toOffsetImpl = (EObjectCoveringRegion) toOffset;
EObjectCoveringRegion notToOffsetImpl = (EObjectCoveringRegion) notToOffset;
EObjectCoveringRegion viaOffsetImpl = (EObjectCoveringRegion) viaOffset;
EObjectCoveringRegion notViaOffsetImpl = (EObjectCoveringRegion) notViaOffset;
EObjectCoveringRegion referenceOffsetImpl = (EObjectCoveringRegion) referenceOffset;
ControlFlowElement fromCFE = getCFE(fromOffset);
ControlFlowElement toCFE = getCFEWithReference(toOffsetImpl, referenceOffsetImpl);
ControlFlowElement notToCFE = getCFEWithReference(notToOffsetImpl, referenceOffsetImpl);
ControlFlowElement viaCFE = getCFEWithReference(viaOffsetImpl, referenceOffsetImpl);
ControlFlowElement notViaCFE = getCFEWithReference(notViaOffsetImpl, referenceOffsetImpl);
ControlFlowElement targetCFE = (toCFE != null) ? toCFE : notToCFE;
boolean expectPathExists = toCFE != null;
if (fromCFE == null) {
fail("Element 'from' could not be found");
}
if (targetCFE == null) {
fail("Element 'to' or 'notTo' could not be found or before 'from'");
}
boolean actualPathExists;
if (viaCFE != null) {
actualPathExists = getFlowAnalyzer(fromCFE).isTransitiveSuccessor(fromCFE, viaCFE, notViaCFE);
actualPathExists &= getFlowAnalyzer(fromCFE).isTransitiveSuccessor(viaCFE, targetCFE, notViaCFE);
} else {
actualPathExists = getFlowAnalyzer(fromCFE).isTransitiveSuccessor(fromCFE, targetCFE, notViaCFE);
}
if (expectPathExists && !actualPathExists) {
fail("Path not found");
}
if (!expectPathExists && actualPathExists) {
fail("A path was found");
}
}
use of org.eclipse.n4js.n4JS.ControlFlowElement in project n4js by eclipse.
the class FlowgraphsXpectMethod method getCFE.
private ControlFlowElement getCFE(IEObjectCoveringRegion offset) {
EObject context = offset.getEObject();
if (!(context instanceof ControlFlowElement)) {
fail("Element '" + FGUtils.getSourceText(context) + "' is not a control flow element");
}
ControlFlowElement cfe = (ControlFlowElement) context;
return cfe;
}
use of org.eclipse.n4js.n4JS.ControlFlowElement in project n4js by eclipse.
the class FlowgraphsXpectMethod method instanceofguard.
/**
* This xpect method can evaluate the control flow container of a given {@link ControlFlowElement}.
*/
@ParameterParser(syntax = "('of' arg1=OFFSET)? (arg2=STRING)?")
@Xpect
public void instanceofguard(@N4JSCommaSeparatedValuesExpectation IN4JSCommaSeparatedValuesExpectation expectation, IEObjectCoveringRegion offset, String holdsName) {
ControlFlowElement cfe = getCFE(offset);
GuardAssertion assertion = null;
if (holdsName != null) {
assertion = GuardAssertion.valueOf(holdsName);
}
InstanceofGuardAnalyser iga = new InstanceofGuardAnalyser();
N4JSFlowAnalyser flowAnalyzer = getFlowAnalyzer(cfe);
flowAnalyzer.accept(iga);
Collection<InstanceofGuard> ioGuards = null;
if (assertion == GuardAssertion.MayHolds) {
ioGuards = iga.getMayHoldingTypes(cfe);
} else if (assertion == GuardAssertion.NeverHolds) {
ioGuards = iga.getNeverHoldingTypes(cfe);
} else {
ioGuards = iga.getAlwaysHoldingTypes(cfe);
}
List<String> commonPredStrs = new LinkedList<>();
for (InstanceofGuard ioGuard : ioGuards) {
String symbolText = FGUtils.getSourceText(ioGuard.symbolCFE);
String typeText = FGUtils.getSourceText(ioGuard.typeIdentifier);
commonPredStrs.add(symbolText + "<:" + typeText);
}
expectation.assertEquals(commonPredStrs);
}
Aggregations