Loading de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/TTCN3.xtext +1 −1 Original line number Diff line number Diff line Loading @@ -402,7 +402,7 @@ FunctionInstance: // ext ref ok? // usage / semantic of PreDefFunctionIdentifier? FunctionRef: FunctionDef | ExtFunctionDef | BaseTemplate; FunctionDef | ExtFunctionDef | BaseTemplate | AltstepDef; //(IDENTIFIER DOT)? IDENTIFIER; FunctionActualParList: Loading de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/validation/TTCN3Validator.xtend +181 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,9 @@ import java.util.Collection import org.eclipse.emf.ecore.util.EcoreUtil.UsageCrossReferencer import org.eclipse.emf.ecore.util.EcoreUtil.ExternalCrossReferencer import de.ugoe.cs.swe.tTCN3.InLineTemplate import de.ugoe.cs.swe.tTCN3.RunsOnSpec import de.ugoe.cs.swe.tTCN3.FunctionInstance import de.ugoe.cs.swe.tTCN3.AltstepInstance class CheckDefinitionComeFirstParameter { public boolean hasOtherDefinitions Loading Loading @@ -1157,6 +1160,184 @@ class TTCN3Validator extends AbstractTTCN3Validator { ); } @Check def checkNoOverSpecificRunsOnClauses(RunsOnSpec runsOn) { if (!activeProfile.checkNoOverSpecificRunsOnClauses) return; //As of v1.0.3, test cases are not considered in this check val parent = runsOn.eContainer var ComponentDef component = null var isUnreferenced = false val ArrayList<TTCN3Reference> consideredAltOrFunc = newArrayList if (parent instanceof AltstepDef) { component = parent.spec.component if (!parent.specifiedComponentResolved(component)) { return; } } else if (parent instanceof FunctionDef) { component = parent.runsOn.component if (!parent.specifiedComponentResolved(component)) { return; } } else { return; } val overSpecifiedFirstLevel = !component.isReferencedComponentSpec(parent) val message = "Definition for \"" + (parent as TTCN3Reference).name + "\" contains an over specific runs on clause!" val INode node = NodeModelUtils.getNode(parent) if (overSpecifiedFirstLevel) { var overSpecified = true if (activeProfile.recursionInCheckNoOverSpecificRunsOnClauses) { consideredAltOrFunc.add(parent as TTCN3Reference) overSpecified = !(parent as TTCN3Reference).isReferencedInHierarchy(consideredAltOrFunc) } if (overSpecified) { warning( message, null, //TODO: EStructuralFeature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.13, " + MiscTools.getMethodName() ); } } } private def boolean specifiedComponentResolved(TTCN3Reference parent, ComponentDef component) { if (Strings.isNullOrEmpty(component.name)) { val message = "" + "Runs on component reference of \"" + parent.name + "\" cannot be resolved. It may not be possible to determine whether construct has an over-specific runs on clause!" val INode node = NodeModelUtils.getNode(parent) info( message, null, MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.13, " + MiscTools.getMethodName(), LogLevel.INFORMATION.toString ); return false } return true } private def ArrayList<TTCN3Reference> nextLevelFunctionsOrAltsteps(TTCN3Reference parent, ArrayList<TTCN3Reference> consideredAltOrFunc) { val ArrayList<TTCN3Reference> nextLevelCheck = newArrayList for (f : parent.getAllContentsOfType(FunctionInstance).map[it.ref]) { if (consideredAltOrFunc.contains(f)) { val message = "" + "Possible cyclic call sequence: \"" + f.name + "\". Skipping..." val INode node = NodeModelUtils.getNode(f) info( message, null, MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.13, " + MiscTools.getMethodName(), LogLevel.INFORMATION.toString ); } else { nextLevelCheck.add(f) } } for (a : parent.getAllContentsOfType(AltstepInstance).map[it.ref]) { if (consideredAltOrFunc.contains(a)) { val message = "" + "Possible cyclic call sequence: \"" + a.name + "\". Skipping..." val INode node = NodeModelUtils.getNode(a) info( message, null, MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.13, " + MiscTools.getMethodName(), LogLevel.INFORMATION.toString ); } else { nextLevelCheck.add(a) } } return nextLevelCheck } private def boolean isReferencedInHierarchy(TTCN3Reference parent, ArrayList<TTCN3Reference> consideredAltOrFunc) { var ArrayList<TTCN3Reference> nextLevelCheck = parent.nextLevelFunctionsOrAltsteps(consideredAltOrFunc) do { for (o : nextLevelCheck) { if (o instanceof FunctionDef) { if (o.runsOn != null) { if (o.specifiedComponentResolved(o.runsOn.component)) { if (o.runsOn.component.isReferencedComponentSpec(o)) return true } } else { //TODO: error message? } } else if (o instanceof AltstepDef) { if (o.spec != null) { if (o.specifiedComponentResolved(o.spec.component)) { if (o.spec.component.isReferencedComponentSpec(o)) return true } } else { // TODO: error message? } } nextLevelCheck = o.nextLevelFunctionsOrAltsteps(consideredAltOrFunc) } } while (!nextLevelCheck.empty) return false } private def boolean isReferencedComponentSpec(ComponentDef component, EObject parent) { for (d : component.defs) { val element = d.element if (element.port != null) { for (p : element.port.instances) { if (!p.isUnreferenced(parent)) return true } } else if (element.const != null) { for (c : element.const.defs.list) { if (!c.isUnreferenced(parent)) return true } } else if (element.timer != null) { for (t : element.timer.list.variables) { if (!t.isUnreferenced(parent)) return true } } else if (element.variable != null) { if (element.variable.list != null) { for (v : element.variable.list.variables) { if (!v.isUnreferenced(parent)) return true } } if (element.variable.tempList != null) { for (tv : element.variable.tempList.variables) { if (!tv.isUnreferenced(parent)) return true } } } } false } /** * END: Code Style ------------------------------------------------------------------------------ */ Loading Loading
de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/TTCN3.xtext +1 −1 Original line number Diff line number Diff line Loading @@ -402,7 +402,7 @@ FunctionInstance: // ext ref ok? // usage / semantic of PreDefFunctionIdentifier? FunctionRef: FunctionDef | ExtFunctionDef | BaseTemplate; FunctionDef | ExtFunctionDef | BaseTemplate | AltstepDef; //(IDENTIFIER DOT)? IDENTIFIER; FunctionActualParList: Loading
de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/validation/TTCN3Validator.xtend +181 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,9 @@ import java.util.Collection import org.eclipse.emf.ecore.util.EcoreUtil.UsageCrossReferencer import org.eclipse.emf.ecore.util.EcoreUtil.ExternalCrossReferencer import de.ugoe.cs.swe.tTCN3.InLineTemplate import de.ugoe.cs.swe.tTCN3.RunsOnSpec import de.ugoe.cs.swe.tTCN3.FunctionInstance import de.ugoe.cs.swe.tTCN3.AltstepInstance class CheckDefinitionComeFirstParameter { public boolean hasOtherDefinitions Loading Loading @@ -1157,6 +1160,184 @@ class TTCN3Validator extends AbstractTTCN3Validator { ); } @Check def checkNoOverSpecificRunsOnClauses(RunsOnSpec runsOn) { if (!activeProfile.checkNoOverSpecificRunsOnClauses) return; //As of v1.0.3, test cases are not considered in this check val parent = runsOn.eContainer var ComponentDef component = null var isUnreferenced = false val ArrayList<TTCN3Reference> consideredAltOrFunc = newArrayList if (parent instanceof AltstepDef) { component = parent.spec.component if (!parent.specifiedComponentResolved(component)) { return; } } else if (parent instanceof FunctionDef) { component = parent.runsOn.component if (!parent.specifiedComponentResolved(component)) { return; } } else { return; } val overSpecifiedFirstLevel = !component.isReferencedComponentSpec(parent) val message = "Definition for \"" + (parent as TTCN3Reference).name + "\" contains an over specific runs on clause!" val INode node = NodeModelUtils.getNode(parent) if (overSpecifiedFirstLevel) { var overSpecified = true if (activeProfile.recursionInCheckNoOverSpecificRunsOnClauses) { consideredAltOrFunc.add(parent as TTCN3Reference) overSpecified = !(parent as TTCN3Reference).isReferencedInHierarchy(consideredAltOrFunc) } if (overSpecified) { warning( message, null, //TODO: EStructuralFeature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.13, " + MiscTools.getMethodName() ); } } } private def boolean specifiedComponentResolved(TTCN3Reference parent, ComponentDef component) { if (Strings.isNullOrEmpty(component.name)) { val message = "" + "Runs on component reference of \"" + parent.name + "\" cannot be resolved. It may not be possible to determine whether construct has an over-specific runs on clause!" val INode node = NodeModelUtils.getNode(parent) info( message, null, MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.13, " + MiscTools.getMethodName(), LogLevel.INFORMATION.toString ); return false } return true } private def ArrayList<TTCN3Reference> nextLevelFunctionsOrAltsteps(TTCN3Reference parent, ArrayList<TTCN3Reference> consideredAltOrFunc) { val ArrayList<TTCN3Reference> nextLevelCheck = newArrayList for (f : parent.getAllContentsOfType(FunctionInstance).map[it.ref]) { if (consideredAltOrFunc.contains(f)) { val message = "" + "Possible cyclic call sequence: \"" + f.name + "\". Skipping..." val INode node = NodeModelUtils.getNode(f) info( message, null, MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.13, " + MiscTools.getMethodName(), LogLevel.INFORMATION.toString ); } else { nextLevelCheck.add(f) } } for (a : parent.getAllContentsOfType(AltstepInstance).map[it.ref]) { if (consideredAltOrFunc.contains(a)) { val message = "" + "Possible cyclic call sequence: \"" + a.name + "\". Skipping..." val INode node = NodeModelUtils.getNode(a) info( message, null, MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.13, " + MiscTools.getMethodName(), LogLevel.INFORMATION.toString ); } else { nextLevelCheck.add(a) } } return nextLevelCheck } private def boolean isReferencedInHierarchy(TTCN3Reference parent, ArrayList<TTCN3Reference> consideredAltOrFunc) { var ArrayList<TTCN3Reference> nextLevelCheck = parent.nextLevelFunctionsOrAltsteps(consideredAltOrFunc) do { for (o : nextLevelCheck) { if (o instanceof FunctionDef) { if (o.runsOn != null) { if (o.specifiedComponentResolved(o.runsOn.component)) { if (o.runsOn.component.isReferencedComponentSpec(o)) return true } } else { //TODO: error message? } } else if (o instanceof AltstepDef) { if (o.spec != null) { if (o.specifiedComponentResolved(o.spec.component)) { if (o.spec.component.isReferencedComponentSpec(o)) return true } } else { // TODO: error message? } } nextLevelCheck = o.nextLevelFunctionsOrAltsteps(consideredAltOrFunc) } } while (!nextLevelCheck.empty) return false } private def boolean isReferencedComponentSpec(ComponentDef component, EObject parent) { for (d : component.defs) { val element = d.element if (element.port != null) { for (p : element.port.instances) { if (!p.isUnreferenced(parent)) return true } } else if (element.const != null) { for (c : element.const.defs.list) { if (!c.isUnreferenced(parent)) return true } } else if (element.timer != null) { for (t : element.timer.list.variables) { if (!t.isUnreferenced(parent)) return true } } else if (element.variable != null) { if (element.variable.list != null) { for (v : element.variable.list.variables) { if (!v.isUnreferenced(parent)) return true } } if (element.variable.tempList != null) { for (tv : element.variable.tempList.variables) { if (!tv.isUnreferenced(parent)) return true } } } } false } /** * END: Code Style ------------------------------------------------------------------------------ */ Loading