Loading de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/validation/TTCN3Validator.xtend +447 −24 Original line number Diff line number Diff line package de.ugoe.cs.swe.validation import com.google.common.base.Strings import de.ugoe.cs.swe.TTCN3Configuration.QualityCheckProfile import de.ugoe.cs.swe.common.ConfigTools import de.ugoe.cs.swe.common.MiscTools import de.ugoe.cs.swe.common.logging.LoggingInterface.LogLevel import de.ugoe.cs.swe.common.logging.LoggingInterface.MessageClass import de.ugoe.cs.swe.tTCN3.AllOrSignatureList import de.ugoe.cs.swe.tTCN3.AllOrTypeList import de.ugoe.cs.swe.tTCN3.AltConstruct import de.ugoe.cs.swe.tTCN3.AltstepDef import de.ugoe.cs.swe.tTCN3.AltstepLocalDef import de.ugoe.cs.swe.tTCN3.AltstepLocalDefList import de.ugoe.cs.swe.tTCN3.BaseTemplate import de.ugoe.cs.swe.tTCN3.ComponentDef import de.ugoe.cs.swe.tTCN3.ComponentDefList import de.ugoe.cs.swe.tTCN3.ComponentElementDef import de.ugoe.cs.swe.tTCN3.ConstDef import de.ugoe.cs.swe.tTCN3.ConstList import de.ugoe.cs.swe.tTCN3.ControlStatementOrDefList Loading @@ -23,21 +33,29 @@ import de.ugoe.cs.swe.tTCN3.FunctionDef import de.ugoe.cs.swe.tTCN3.FunctionDefList import de.ugoe.cs.swe.tTCN3.FunctionFormalPar import de.ugoe.cs.swe.tTCN3.FunctionFormalParList import de.ugoe.cs.swe.tTCN3.GotoStatement import de.ugoe.cs.swe.tTCN3.GroupDef import de.ugoe.cs.swe.tTCN3.ImportDef import de.ugoe.cs.swe.tTCN3.Initial import de.ugoe.cs.swe.tTCN3.LabelStatement import de.ugoe.cs.swe.tTCN3.MatchingSymbol import de.ugoe.cs.swe.tTCN3.ModuleControlPart import de.ugoe.cs.swe.tTCN3.ModuleDefinition import de.ugoe.cs.swe.tTCN3.ModuleDefinitionsList import de.ugoe.cs.swe.tTCN3.ModulePar import de.ugoe.cs.swe.tTCN3.ModuleParDef import de.ugoe.cs.swe.tTCN3.ModuleParameter import de.ugoe.cs.swe.tTCN3.PermutationMatch import de.ugoe.cs.swe.tTCN3.PortDef import de.ugoe.cs.swe.tTCN3.PortInstance import de.ugoe.cs.swe.tTCN3.ProcOrTypeList import de.ugoe.cs.swe.tTCN3.RecordDefNamed import de.ugoe.cs.swe.tTCN3.RecordOfDefNamed import de.ugoe.cs.swe.tTCN3.RefValue import de.ugoe.cs.swe.tTCN3.ReferencedType import de.ugoe.cs.swe.tTCN3.SetDefNamed import de.ugoe.cs.swe.tTCN3.SetOfDefNamed import de.ugoe.cs.swe.tTCN3.Signature import de.ugoe.cs.swe.tTCN3.SignatureDef import de.ugoe.cs.swe.tTCN3.SingleConstDef import de.ugoe.cs.swe.tTCN3.SingleTempVarInstance Loading @@ -45,6 +63,8 @@ import de.ugoe.cs.swe.tTCN3.SingleVarInstance import de.ugoe.cs.swe.tTCN3.StatementBlock import de.ugoe.cs.swe.tTCN3.StructDefBody import de.ugoe.cs.swe.tTCN3.StructFieldDef import de.ugoe.cs.swe.tTCN3.StructuredTypeDef import de.ugoe.cs.swe.tTCN3.SubTypeDef import de.ugoe.cs.swe.tTCN3.SubTypeDefNamed import de.ugoe.cs.swe.tTCN3.TTCN3Module import de.ugoe.cs.swe.tTCN3.TTCN3Package Loading @@ -53,12 +73,19 @@ import de.ugoe.cs.swe.tTCN3.TemplateDef import de.ugoe.cs.swe.tTCN3.TemplateOrValueFormalPar import de.ugoe.cs.swe.tTCN3.TemplateOrValueFormalParList import de.ugoe.cs.swe.tTCN3.TestcaseDef import de.ugoe.cs.swe.tTCN3.TimerInstance import de.ugoe.cs.swe.tTCN3.Type import de.ugoe.cs.swe.tTCN3.TypeDef import de.ugoe.cs.swe.tTCN3.TypeDefBody import de.ugoe.cs.swe.tTCN3.UnionDefNamed import de.ugoe.cs.swe.tTCN3.VarInstance import java.util.ArrayList import java.util.List import java.util.Map import java.util.concurrent.ConcurrentHashMap import java.util.regex.Matcher import java.util.regex.Pattern import org.eclipse.emf.ecore.EClass import org.eclipse.emf.ecore.EObject import org.eclipse.emf.ecore.EStructuralFeature import org.eclipse.xtext.nodemodel.INode Loading @@ -67,30 +94,19 @@ import org.eclipse.xtext.validation.Check import static extension de.ugoe.cs.swe.common.TTCN3ScopeHelper.* import static extension org.eclipse.xtext.EcoreUtil2.* import de.ugoe.cs.swe.tTCN3.TimerInstance import de.ugoe.cs.swe.tTCN3.ComponentElementDef import de.ugoe.cs.swe.common.ConfigTools import de.ugoe.cs.swe.TTCN3Configuration.QualityCheckProfile import de.ugoe.cs.swe.common.logging.LoggingInterface.LogLevel import de.ugoe.cs.swe.common.logging.LoggingInterface.MessageClass import de.ugoe.cs.swe.tTCN3.BaseTemplate import de.ugoe.cs.swe.common.MiscTools import de.ugoe.cs.swe.tTCN3.MatchingSymbol import de.ugoe.cs.swe.tTCN3.StructuredTypeDef import de.ugoe.cs.swe.tTCN3.SubTypeDef import java.util.List import de.ugoe.cs.swe.tTCN3.Type import de.ugoe.cs.swe.tTCN3.Signature import de.ugoe.cs.swe.tTCN3.ProcOrTypeList import de.ugoe.cs.swe.tTCN3.AllOrSignatureList import de.ugoe.cs.swe.tTCN3.AllOrTypeList import de.ugoe.cs.swe.tTCN3.GotoStatement import de.ugoe.cs.swe.tTCN3.LabelStatement import de.ugoe.cs.swe.tTCN3.AltConstruct import de.ugoe.cs.swe.tTCN3.PermutationMatch import de.ugoe.cs.swe.tTCN3.impl.TTCN3PackageImpl 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 class CheckDefinitionComeFirstParameter { public boolean hasOtherDefinitions public int previousLocalDefinitionsOrderLevel } class TTCN3Validator extends AbstractTTCN3Validator { val static Map<String, ArrayList<String>> moduleLevelIdentifiersMap = new ConcurrentHashMap<String, ArrayList<String>>(); val ConfigTools configTools = ConfigTools.getInstance; var QualityCheckProfile activeProfile = null; Loading Loading @@ -738,9 +754,415 @@ class TTCN3Validator extends AbstractTTCN3Validator { } } @Check def checkLocalDefinitionsComeFirst(ModuleDefinition moduleDefinition) { if (!activeProfile.checkLocalDefinitionsComeFirst) return; val definition = moduleDefinition.def if (definition instanceof FunctionDef) { definition.statement.checkLocalDefinitionsComeFirstStatemanet } else if (definition instanceof TestcaseDef) { definition.statement.checkLocalDefinitionsComeFirstStatemanet } else if (definition instanceof AltstepDef) { definition.checkLocalDefinitionsComeFirstAltstepDef } else if (definition instanceof TypeDef) { if (definition.body.structured != null && definition.body.structured.component != null) { definition.body.structured.component.checkLocalDefinitionsComeFirstComponent } } } private def checkLocalDefinitionsComeFirstStatemanet(StatementBlock statement) { val CheckDefinitionComeFirstParameter params = new CheckDefinitionComeFirstParameter for (d : statement.def) { if (d.locDef != null && d.locDef.constDef != null) { d.locDef.constDef.checkLocalDefinitionsComeFirstOrder(params) } else if (d.locInst != null && d.locInst.timer != null) { d.locInst.timer.checkLocalDefinitionsComeFirstOrder(params) } else if (d.locInst != null && d.locInst.variable != null) { d.locInst.variable.checkLocalDefinitionsComeFirstOrder(params) } } for (s : statement.stat) { s.checkLocalDefinitionsComeFirstOther } } private def checkLocalDefinitionsComeFirstAltstepDef(AltstepDef altstep) { val CheckDefinitionComeFirstParameter params = new CheckDefinitionComeFirstParameter for (d : altstep.local.defs) { if (d.variable != null) { d.variable.checkLocalDefinitionsComeFirstOrder(params) } else if (d.timer != null) { d.timer.checkLocalDefinitionsComeFirstOrder(params) } else if (d.const != null) { d.const.checkLocalDefinitionsComeFirstOrder(params) } } altstep.guard.checkLocalDefinitionsComeFirstOther } private def checkLocalDefinitionsComeFirstComponent(ComponentDef component) { val CheckDefinitionComeFirstParameter params = new CheckDefinitionComeFirstParameter for (d : component.defs) { if (d.element.port != null) d.element.port.checkLocalDefinitionsComeFirstOrder(params) else if (d.element.variable != null) d.element.variable.checkLocalDefinitionsComeFirstOrder(params) else if (d.element.timer != null) d.element.timer.checkLocalDefinitionsComeFirstOrder(params) else if (d.element.const != null) d.element.const.checkLocalDefinitionsComeFirstOrder(params) } } private def checkLocalDefinitionsComeFirstOther(EObject parent) { val configuredOrder = localDefOrderClasses val List<EObject> foundChilds = newArrayList for (t : configuredOrder) { // TODO: find a way to get the Class<EObject> to fix the hack if (t.instanceClassName.contains("VarInstance")) { foundChilds.addAll(parent.getAllContentsOfType(VarInstance)) } else if (t.instanceClassName.contains("ConstDef")) { foundChilds.addAll(parent.getAllContentsOfType(ConstDef)) } else if (t.instanceClassName.contains("TimerInstance")) { foundChilds.addAll(parent.getAllContentsOfType(TimerInstance)) } else if (t.instanceClassName.contains("PortInstance")) { foundChilds.addAll(parent.getAllContentsOfType(PortInstance)) } } for (c : foundChilds) { val message = "Local definition is not at the beginning!" val INode node = NodeModelUtils.getNode(c) warning( message, null, //TODO: struct feature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.8, " + "checkLocalDefinitionsComeFirst" ); } } private def checkLocalDefinitionsComeFirstOrder(EObject o, CheckDefinitionComeFirstParameter params) { val configuredOrder = localDefOrderClasses val int currentLocalDefinitionTypeOrderLevel = configuredOrder.indexOf(o.eClass); val INode node = NodeModelUtils.getNode(o) if (configuredOrder.contains(o.eClass)) { if (params.hasOtherDefinitions) { val message = "Local definition is not at the beginning!" warning( message, null, //TODO: struct feature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.8, " + "checkLocalDefinitionsComeFirst" ); } else { if ((currentLocalDefinitionTypeOrderLevel < params.previousLocalDefinitionsOrderLevel)) { val message = "Local definition order is not maintained as configured (" + configuredOrder.eClassesToString + ")!" warning( message, null, //TODO: struct feature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.8, " + "checkLocalDefinitionsComeFirst" ); } else { params.previousLocalDefinitionsOrderLevel = currentLocalDefinitionTypeOrderLevel } } } else { params.hasOtherDefinitions = true } } private def String eClassesToString(List<EClass> order) { var String res = " " for (c : order) { res += c.name + " " } res } private def List<EClass> localDefOrderClasses() { val defs = activeProfile.localDefinitionTypes.toList val res = newArrayList for (d : defs) { if (d == "VarInstance") { res.add(TTCN3Package.eINSTANCE.varInstance) } else if (d == "ConstDef") { res.add(TTCN3Package.eINSTANCE.constDef) } else if (d == "TimerInstance") { res.add(TTCN3Package.eINSTANCE.timerInstance) } else if (d == "PortInstance") { res.add(TTCN3Package.eINSTANCE.portInstance) } } return res } @Check def checkImportsComeFirst(TTCN3Module module) { if (!activeProfile.checkImportsComeFirst) return; if (module.defs == null) return; var hasOtherDefs = false for (d : module.defs.definitions) { if (d.def instanceof ImportDef) { if (hasOtherDefs) { val message = "Import statement is not at the beginning!" val INode node = NodeModelUtils.getNode(d) warning( message, null, //TODO: EStructuralFeature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.9, " + MiscTools.getMethodName() ); } } else { hasOtherDefs = true } } } @Check def checkNoDuplicatedModuleDefinitionIdentifiers(ModuleDefinition definition) { if (!activeProfile.checkNoDuplicatedModuleDefinitionIdentifiers) return; val parentModule = definition.findDesiredParent(TTCN3Module) var ArrayList<String> identifiers = newArrayList var idExists = false var TTCN3Reference detailDef = null if (moduleLevelIdentifiersMap.containsKey(parentModule.name)) { identifiers = moduleLevelIdentifiersMap.get(parentModule.name) } else { moduleLevelIdentifiersMap.put(parentModule.name, identifiers) } if (definition.def instanceof ConstDef) { val constDefList = (definition.def as ConstDef).defs as ConstList for (SingleConstDef d : constDefList.list) { idExists = d.name.checkIdentifier(identifiers) detailDef = d } } else if (definition.def instanceof ModuleParDef) { if ((definition.def as ModuleParDef).param != null) { for (ModuleParameter p : (definition.def as ModuleParDef).param.list.params) { idExists = p.name.checkIdentifier(identifiers) detailDef = p } } else if ((definition.def as ModuleParDef).multitypeParam != null) { for (ModulePar p : (definition.def as ModuleParDef).multitypeParam.params) { for (ModuleParameter pa : p.list.params) { idExists = pa.name.checkIdentifier(identifiers) detailDef = pa } } } } else if (definition.def instanceof FunctionDef) { idExists = (definition.def as FunctionDef).name.checkIdentifier(identifiers) detailDef = definition.def as FunctionDef } else if (definition.def instanceof TemplateDef) { idExists = (definition.def as TemplateDef).base.name.checkIdentifier(identifiers) detailDef = (definition.def as TemplateDef).base } else if (definition.def instanceof SignatureDef) { idExists = (definition.def as SignatureDef).name.checkIdentifier(identifiers) detailDef = definition.def as SignatureDef } else if (definition.def instanceof TestcaseDef) { idExists = (definition.def as TestcaseDef).name.checkIdentifier(identifiers) detailDef = definition.def as TestcaseDef } else if (definition.def instanceof AltstepDef) { idExists = (definition.def as AltstepDef).name.checkIdentifier(identifiers) detailDef = definition.def as AltstepDef } else if (definition.def instanceof GroupDef) { idExists = (definition.def as GroupDef).name.checkIdentifier(identifiers) detailDef = definition.def as GroupDef } if (idExists) { val message = "Identifier \"" + detailDef.name + "\" on the module level has already been used in " + parentModule.name + "!" val INode node = NodeModelUtils.getNode(detailDef) warning( message, null, //TODO: EStructuralFeature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.10, " + MiscTools.getMethodName() ); } } private def boolean checkIdentifier(String name, ArrayList<String> ids) { var res = false if (ids.contains(name)) { res = true } else { ids.add(name) } res } // TODO: create own check method for every type??? @Check def checkZeroReferencedModuleDefinitions(ModuleDefinition definition) { if (!activeProfile.checkZeroReferencedModuleDefinitions) return; // do not consider declarations groups? //val parentGroup = definition.findDesiredParent(GroupDef) //if (parentGroup != null) // return; val parentModule = definition.findDesiredParent(TTCN3Module) val Pattern zeroReferencedModuleDefinitionsExcludedPattern = Pattern.compile( activeProfile.getZeroReferencedModuleDefinitionsExcludedRegExp()) val Matcher zeroReferencedModuleDefinitionsExcludedMatcher = zeroReferencedModuleDefinitionsExcludedPattern. matcher(parentModule.name) if (zeroReferencedModuleDefinitionsExcludedMatcher.matches()) return; var TTCN3Reference detailDef = null var notReferenced = false //TODO: maybe use another type of cross referencer // TODO: find global cross references if (definition.def instanceof ConstDef) { val constDefList = (definition.def as ConstDef).defs as ConstList for (SingleConstDef d : constDefList.list) { notReferenced = d.isUnreferenced(parentModule) detailDef = d } } else if (definition.def instanceof ModuleParDef) { if ((definition.def as ModuleParDef).param != null) { for (ModuleParameter p : (definition.def as ModuleParDef).param.list.params) { notReferenced = p.isUnreferenced(parentModule) detailDef = p } } else if ((definition.def as ModuleParDef).multitypeParam != null) { for (ModulePar p : (definition.def as ModuleParDef).multitypeParam.params) { for (ModuleParameter pa : p.list.params) { notReferenced = pa.isUnreferenced(parentModule) detailDef = pa } } } } else if (definition.def instanceof FunctionDef) { notReferenced = definition.def.isUnreferenced(parentModule) detailDef = definition.def as FunctionDef } else if (definition.def instanceof TemplateDef) { notReferenced = (definition.def as TemplateDef).base.isUnreferenced(parentModule) detailDef = (definition.def as TemplateDef).base } else if (definition.def instanceof SignatureDef) { notReferenced = definition.def.isUnreferenced(parentModule) detailDef = definition.def as SignatureDef } else if (definition.def instanceof TestcaseDef) { notReferenced = definition.def.isUnreferenced(parentModule) detailDef = definition.def as TestcaseDef } else if (definition.def instanceof AltstepDef) { notReferenced = definition.def.isUnreferenced(parentModule) detailDef = definition.def as AltstepDef } else if (definition.def instanceof TypeDef) { val body = (definition.def as TypeDef).body if (body.structured != null) { if (body.structured.recordOf != null && body.structured.recordOf instanceof RecordOfDefNamed) { notReferenced = body.structured.recordOf.isUnreferenced(parentModule) detailDef = body.structured.recordOf as RecordOfDefNamed } if (body.structured.setOf != null && body.structured.setOf instanceof SetOfDefNamed) { notReferenced = body.structured.setOf.isUnreferenced(parentModule) detailDef = body.structured.setOf as SetOfDefNamed } if (body.structured.record != null && body.structured.record instanceof RecordDefNamed) { notReferenced = body.structured.record.isUnreferenced(parentModule) detailDef = body.structured.record as RecordDefNamed } if (body.structured.union != null && body.structured.union instanceof UnionDefNamed) { notReferenced = body.structured.union.isUnreferenced(parentModule) detailDef = body.structured.union as UnionDefNamed } if (body.structured.set != null && body.structured.set instanceof SetDefNamed) { notReferenced = body.structured.set.isUnreferenced(parentModule) detailDef = body.structured.set as SetDefNamed } if (body.structured.port != null && body.structured.port instanceof PortDef) { notReferenced = body.structured.port.isUnreferenced(parentModule) detailDef = body.structured.port as PortDef } if (body.structured.component != null && body.structured.component instanceof ComponentDef) { notReferenced = body.structured.component.isUnreferenced(parentModule) detailDef = body.structured.component as ComponentDef } } else if (body.sub != null) { if (body.sub instanceof SubTypeDefNamed) { notReferenced = body.sub.isUnreferenced(parentModule) detailDef = body.sub as SubTypeDefNamed } } } if (notReferenced) { val message = "Definition for \"" + detailDef.name + "\" is never referenced!" val INode node = NodeModelUtils.getNode(detailDef) warning( message, null, //TODO: EStructuralFeature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.17, " + MiscTools.getMethodName() ); } } private def boolean isUnreferenced(EObject type, EObject parent) { val result = UsageCrossReferencer.find(type, parent) result.size == 0 } @Check def checkNoInlineTemplates(InLineTemplate template) { if (!activeProfile.checkNoInlineTemplates) return; val message = "Inline Template is used!" val INode node = NodeModelUtils.getNode(template) warning( message, null, //TODO: EStructuralFeature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.13, " + MiscTools.getMethodName() ); } /** * END: Code Style ------------------------------------------------------------------------------ */ //TODO: update error parameters /* @Check def checkUniqueNameNestedVariable(RefValue variable) { variable.isNameClashInHierarchy Loading Loading @@ -1214,4 +1636,5 @@ class TTCN3Validator extends AbstractTTCN3Validator { } return false; } */ } Loading
de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/validation/TTCN3Validator.xtend +447 −24 Original line number Diff line number Diff line package de.ugoe.cs.swe.validation import com.google.common.base.Strings import de.ugoe.cs.swe.TTCN3Configuration.QualityCheckProfile import de.ugoe.cs.swe.common.ConfigTools import de.ugoe.cs.swe.common.MiscTools import de.ugoe.cs.swe.common.logging.LoggingInterface.LogLevel import de.ugoe.cs.swe.common.logging.LoggingInterface.MessageClass import de.ugoe.cs.swe.tTCN3.AllOrSignatureList import de.ugoe.cs.swe.tTCN3.AllOrTypeList import de.ugoe.cs.swe.tTCN3.AltConstruct import de.ugoe.cs.swe.tTCN3.AltstepDef import de.ugoe.cs.swe.tTCN3.AltstepLocalDef import de.ugoe.cs.swe.tTCN3.AltstepLocalDefList import de.ugoe.cs.swe.tTCN3.BaseTemplate import de.ugoe.cs.swe.tTCN3.ComponentDef import de.ugoe.cs.swe.tTCN3.ComponentDefList import de.ugoe.cs.swe.tTCN3.ComponentElementDef import de.ugoe.cs.swe.tTCN3.ConstDef import de.ugoe.cs.swe.tTCN3.ConstList import de.ugoe.cs.swe.tTCN3.ControlStatementOrDefList Loading @@ -23,21 +33,29 @@ import de.ugoe.cs.swe.tTCN3.FunctionDef import de.ugoe.cs.swe.tTCN3.FunctionDefList import de.ugoe.cs.swe.tTCN3.FunctionFormalPar import de.ugoe.cs.swe.tTCN3.FunctionFormalParList import de.ugoe.cs.swe.tTCN3.GotoStatement import de.ugoe.cs.swe.tTCN3.GroupDef import de.ugoe.cs.swe.tTCN3.ImportDef import de.ugoe.cs.swe.tTCN3.Initial import de.ugoe.cs.swe.tTCN3.LabelStatement import de.ugoe.cs.swe.tTCN3.MatchingSymbol import de.ugoe.cs.swe.tTCN3.ModuleControlPart import de.ugoe.cs.swe.tTCN3.ModuleDefinition import de.ugoe.cs.swe.tTCN3.ModuleDefinitionsList import de.ugoe.cs.swe.tTCN3.ModulePar import de.ugoe.cs.swe.tTCN3.ModuleParDef import de.ugoe.cs.swe.tTCN3.ModuleParameter import de.ugoe.cs.swe.tTCN3.PermutationMatch import de.ugoe.cs.swe.tTCN3.PortDef import de.ugoe.cs.swe.tTCN3.PortInstance import de.ugoe.cs.swe.tTCN3.ProcOrTypeList import de.ugoe.cs.swe.tTCN3.RecordDefNamed import de.ugoe.cs.swe.tTCN3.RecordOfDefNamed import de.ugoe.cs.swe.tTCN3.RefValue import de.ugoe.cs.swe.tTCN3.ReferencedType import de.ugoe.cs.swe.tTCN3.SetDefNamed import de.ugoe.cs.swe.tTCN3.SetOfDefNamed import de.ugoe.cs.swe.tTCN3.Signature import de.ugoe.cs.swe.tTCN3.SignatureDef import de.ugoe.cs.swe.tTCN3.SingleConstDef import de.ugoe.cs.swe.tTCN3.SingleTempVarInstance Loading @@ -45,6 +63,8 @@ import de.ugoe.cs.swe.tTCN3.SingleVarInstance import de.ugoe.cs.swe.tTCN3.StatementBlock import de.ugoe.cs.swe.tTCN3.StructDefBody import de.ugoe.cs.swe.tTCN3.StructFieldDef import de.ugoe.cs.swe.tTCN3.StructuredTypeDef import de.ugoe.cs.swe.tTCN3.SubTypeDef import de.ugoe.cs.swe.tTCN3.SubTypeDefNamed import de.ugoe.cs.swe.tTCN3.TTCN3Module import de.ugoe.cs.swe.tTCN3.TTCN3Package Loading @@ -53,12 +73,19 @@ import de.ugoe.cs.swe.tTCN3.TemplateDef import de.ugoe.cs.swe.tTCN3.TemplateOrValueFormalPar import de.ugoe.cs.swe.tTCN3.TemplateOrValueFormalParList import de.ugoe.cs.swe.tTCN3.TestcaseDef import de.ugoe.cs.swe.tTCN3.TimerInstance import de.ugoe.cs.swe.tTCN3.Type import de.ugoe.cs.swe.tTCN3.TypeDef import de.ugoe.cs.swe.tTCN3.TypeDefBody import de.ugoe.cs.swe.tTCN3.UnionDefNamed import de.ugoe.cs.swe.tTCN3.VarInstance import java.util.ArrayList import java.util.List import java.util.Map import java.util.concurrent.ConcurrentHashMap import java.util.regex.Matcher import java.util.regex.Pattern import org.eclipse.emf.ecore.EClass import org.eclipse.emf.ecore.EObject import org.eclipse.emf.ecore.EStructuralFeature import org.eclipse.xtext.nodemodel.INode Loading @@ -67,30 +94,19 @@ import org.eclipse.xtext.validation.Check import static extension de.ugoe.cs.swe.common.TTCN3ScopeHelper.* import static extension org.eclipse.xtext.EcoreUtil2.* import de.ugoe.cs.swe.tTCN3.TimerInstance import de.ugoe.cs.swe.tTCN3.ComponentElementDef import de.ugoe.cs.swe.common.ConfigTools import de.ugoe.cs.swe.TTCN3Configuration.QualityCheckProfile import de.ugoe.cs.swe.common.logging.LoggingInterface.LogLevel import de.ugoe.cs.swe.common.logging.LoggingInterface.MessageClass import de.ugoe.cs.swe.tTCN3.BaseTemplate import de.ugoe.cs.swe.common.MiscTools import de.ugoe.cs.swe.tTCN3.MatchingSymbol import de.ugoe.cs.swe.tTCN3.StructuredTypeDef import de.ugoe.cs.swe.tTCN3.SubTypeDef import java.util.List import de.ugoe.cs.swe.tTCN3.Type import de.ugoe.cs.swe.tTCN3.Signature import de.ugoe.cs.swe.tTCN3.ProcOrTypeList import de.ugoe.cs.swe.tTCN3.AllOrSignatureList import de.ugoe.cs.swe.tTCN3.AllOrTypeList import de.ugoe.cs.swe.tTCN3.GotoStatement import de.ugoe.cs.swe.tTCN3.LabelStatement import de.ugoe.cs.swe.tTCN3.AltConstruct import de.ugoe.cs.swe.tTCN3.PermutationMatch import de.ugoe.cs.swe.tTCN3.impl.TTCN3PackageImpl 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 class CheckDefinitionComeFirstParameter { public boolean hasOtherDefinitions public int previousLocalDefinitionsOrderLevel } class TTCN3Validator extends AbstractTTCN3Validator { val static Map<String, ArrayList<String>> moduleLevelIdentifiersMap = new ConcurrentHashMap<String, ArrayList<String>>(); val ConfigTools configTools = ConfigTools.getInstance; var QualityCheckProfile activeProfile = null; Loading Loading @@ -738,9 +754,415 @@ class TTCN3Validator extends AbstractTTCN3Validator { } } @Check def checkLocalDefinitionsComeFirst(ModuleDefinition moduleDefinition) { if (!activeProfile.checkLocalDefinitionsComeFirst) return; val definition = moduleDefinition.def if (definition instanceof FunctionDef) { definition.statement.checkLocalDefinitionsComeFirstStatemanet } else if (definition instanceof TestcaseDef) { definition.statement.checkLocalDefinitionsComeFirstStatemanet } else if (definition instanceof AltstepDef) { definition.checkLocalDefinitionsComeFirstAltstepDef } else if (definition instanceof TypeDef) { if (definition.body.structured != null && definition.body.structured.component != null) { definition.body.structured.component.checkLocalDefinitionsComeFirstComponent } } } private def checkLocalDefinitionsComeFirstStatemanet(StatementBlock statement) { val CheckDefinitionComeFirstParameter params = new CheckDefinitionComeFirstParameter for (d : statement.def) { if (d.locDef != null && d.locDef.constDef != null) { d.locDef.constDef.checkLocalDefinitionsComeFirstOrder(params) } else if (d.locInst != null && d.locInst.timer != null) { d.locInst.timer.checkLocalDefinitionsComeFirstOrder(params) } else if (d.locInst != null && d.locInst.variable != null) { d.locInst.variable.checkLocalDefinitionsComeFirstOrder(params) } } for (s : statement.stat) { s.checkLocalDefinitionsComeFirstOther } } private def checkLocalDefinitionsComeFirstAltstepDef(AltstepDef altstep) { val CheckDefinitionComeFirstParameter params = new CheckDefinitionComeFirstParameter for (d : altstep.local.defs) { if (d.variable != null) { d.variable.checkLocalDefinitionsComeFirstOrder(params) } else if (d.timer != null) { d.timer.checkLocalDefinitionsComeFirstOrder(params) } else if (d.const != null) { d.const.checkLocalDefinitionsComeFirstOrder(params) } } altstep.guard.checkLocalDefinitionsComeFirstOther } private def checkLocalDefinitionsComeFirstComponent(ComponentDef component) { val CheckDefinitionComeFirstParameter params = new CheckDefinitionComeFirstParameter for (d : component.defs) { if (d.element.port != null) d.element.port.checkLocalDefinitionsComeFirstOrder(params) else if (d.element.variable != null) d.element.variable.checkLocalDefinitionsComeFirstOrder(params) else if (d.element.timer != null) d.element.timer.checkLocalDefinitionsComeFirstOrder(params) else if (d.element.const != null) d.element.const.checkLocalDefinitionsComeFirstOrder(params) } } private def checkLocalDefinitionsComeFirstOther(EObject parent) { val configuredOrder = localDefOrderClasses val List<EObject> foundChilds = newArrayList for (t : configuredOrder) { // TODO: find a way to get the Class<EObject> to fix the hack if (t.instanceClassName.contains("VarInstance")) { foundChilds.addAll(parent.getAllContentsOfType(VarInstance)) } else if (t.instanceClassName.contains("ConstDef")) { foundChilds.addAll(parent.getAllContentsOfType(ConstDef)) } else if (t.instanceClassName.contains("TimerInstance")) { foundChilds.addAll(parent.getAllContentsOfType(TimerInstance)) } else if (t.instanceClassName.contains("PortInstance")) { foundChilds.addAll(parent.getAllContentsOfType(PortInstance)) } } for (c : foundChilds) { val message = "Local definition is not at the beginning!" val INode node = NodeModelUtils.getNode(c) warning( message, null, //TODO: struct feature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.8, " + "checkLocalDefinitionsComeFirst" ); } } private def checkLocalDefinitionsComeFirstOrder(EObject o, CheckDefinitionComeFirstParameter params) { val configuredOrder = localDefOrderClasses val int currentLocalDefinitionTypeOrderLevel = configuredOrder.indexOf(o.eClass); val INode node = NodeModelUtils.getNode(o) if (configuredOrder.contains(o.eClass)) { if (params.hasOtherDefinitions) { val message = "Local definition is not at the beginning!" warning( message, null, //TODO: struct feature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.8, " + "checkLocalDefinitionsComeFirst" ); } else { if ((currentLocalDefinitionTypeOrderLevel < params.previousLocalDefinitionsOrderLevel)) { val message = "Local definition order is not maintained as configured (" + configuredOrder.eClassesToString + ")!" warning( message, null, //TODO: struct feature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.8, " + "checkLocalDefinitionsComeFirst" ); } else { params.previousLocalDefinitionsOrderLevel = currentLocalDefinitionTypeOrderLevel } } } else { params.hasOtherDefinitions = true } } private def String eClassesToString(List<EClass> order) { var String res = " " for (c : order) { res += c.name + " " } res } private def List<EClass> localDefOrderClasses() { val defs = activeProfile.localDefinitionTypes.toList val res = newArrayList for (d : defs) { if (d == "VarInstance") { res.add(TTCN3Package.eINSTANCE.varInstance) } else if (d == "ConstDef") { res.add(TTCN3Package.eINSTANCE.constDef) } else if (d == "TimerInstance") { res.add(TTCN3Package.eINSTANCE.timerInstance) } else if (d == "PortInstance") { res.add(TTCN3Package.eINSTANCE.portInstance) } } return res } @Check def checkImportsComeFirst(TTCN3Module module) { if (!activeProfile.checkImportsComeFirst) return; if (module.defs == null) return; var hasOtherDefs = false for (d : module.defs.definitions) { if (d.def instanceof ImportDef) { if (hasOtherDefs) { val message = "Import statement is not at the beginning!" val INode node = NodeModelUtils.getNode(d) warning( message, null, //TODO: EStructuralFeature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.9, " + MiscTools.getMethodName() ); } } else { hasOtherDefs = true } } } @Check def checkNoDuplicatedModuleDefinitionIdentifiers(ModuleDefinition definition) { if (!activeProfile.checkNoDuplicatedModuleDefinitionIdentifiers) return; val parentModule = definition.findDesiredParent(TTCN3Module) var ArrayList<String> identifiers = newArrayList var idExists = false var TTCN3Reference detailDef = null if (moduleLevelIdentifiersMap.containsKey(parentModule.name)) { identifiers = moduleLevelIdentifiersMap.get(parentModule.name) } else { moduleLevelIdentifiersMap.put(parentModule.name, identifiers) } if (definition.def instanceof ConstDef) { val constDefList = (definition.def as ConstDef).defs as ConstList for (SingleConstDef d : constDefList.list) { idExists = d.name.checkIdentifier(identifiers) detailDef = d } } else if (definition.def instanceof ModuleParDef) { if ((definition.def as ModuleParDef).param != null) { for (ModuleParameter p : (definition.def as ModuleParDef).param.list.params) { idExists = p.name.checkIdentifier(identifiers) detailDef = p } } else if ((definition.def as ModuleParDef).multitypeParam != null) { for (ModulePar p : (definition.def as ModuleParDef).multitypeParam.params) { for (ModuleParameter pa : p.list.params) { idExists = pa.name.checkIdentifier(identifiers) detailDef = pa } } } } else if (definition.def instanceof FunctionDef) { idExists = (definition.def as FunctionDef).name.checkIdentifier(identifiers) detailDef = definition.def as FunctionDef } else if (definition.def instanceof TemplateDef) { idExists = (definition.def as TemplateDef).base.name.checkIdentifier(identifiers) detailDef = (definition.def as TemplateDef).base } else if (definition.def instanceof SignatureDef) { idExists = (definition.def as SignatureDef).name.checkIdentifier(identifiers) detailDef = definition.def as SignatureDef } else if (definition.def instanceof TestcaseDef) { idExists = (definition.def as TestcaseDef).name.checkIdentifier(identifiers) detailDef = definition.def as TestcaseDef } else if (definition.def instanceof AltstepDef) { idExists = (definition.def as AltstepDef).name.checkIdentifier(identifiers) detailDef = definition.def as AltstepDef } else if (definition.def instanceof GroupDef) { idExists = (definition.def as GroupDef).name.checkIdentifier(identifiers) detailDef = definition.def as GroupDef } if (idExists) { val message = "Identifier \"" + detailDef.name + "\" on the module level has already been used in " + parentModule.name + "!" val INode node = NodeModelUtils.getNode(detailDef) warning( message, null, //TODO: EStructuralFeature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.10, " + MiscTools.getMethodName() ); } } private def boolean checkIdentifier(String name, ArrayList<String> ids) { var res = false if (ids.contains(name)) { res = true } else { ids.add(name) } res } // TODO: create own check method for every type??? @Check def checkZeroReferencedModuleDefinitions(ModuleDefinition definition) { if (!activeProfile.checkZeroReferencedModuleDefinitions) return; // do not consider declarations groups? //val parentGroup = definition.findDesiredParent(GroupDef) //if (parentGroup != null) // return; val parentModule = definition.findDesiredParent(TTCN3Module) val Pattern zeroReferencedModuleDefinitionsExcludedPattern = Pattern.compile( activeProfile.getZeroReferencedModuleDefinitionsExcludedRegExp()) val Matcher zeroReferencedModuleDefinitionsExcludedMatcher = zeroReferencedModuleDefinitionsExcludedPattern. matcher(parentModule.name) if (zeroReferencedModuleDefinitionsExcludedMatcher.matches()) return; var TTCN3Reference detailDef = null var notReferenced = false //TODO: maybe use another type of cross referencer // TODO: find global cross references if (definition.def instanceof ConstDef) { val constDefList = (definition.def as ConstDef).defs as ConstList for (SingleConstDef d : constDefList.list) { notReferenced = d.isUnreferenced(parentModule) detailDef = d } } else if (definition.def instanceof ModuleParDef) { if ((definition.def as ModuleParDef).param != null) { for (ModuleParameter p : (definition.def as ModuleParDef).param.list.params) { notReferenced = p.isUnreferenced(parentModule) detailDef = p } } else if ((definition.def as ModuleParDef).multitypeParam != null) { for (ModulePar p : (definition.def as ModuleParDef).multitypeParam.params) { for (ModuleParameter pa : p.list.params) { notReferenced = pa.isUnreferenced(parentModule) detailDef = pa } } } } else if (definition.def instanceof FunctionDef) { notReferenced = definition.def.isUnreferenced(parentModule) detailDef = definition.def as FunctionDef } else if (definition.def instanceof TemplateDef) { notReferenced = (definition.def as TemplateDef).base.isUnreferenced(parentModule) detailDef = (definition.def as TemplateDef).base } else if (definition.def instanceof SignatureDef) { notReferenced = definition.def.isUnreferenced(parentModule) detailDef = definition.def as SignatureDef } else if (definition.def instanceof TestcaseDef) { notReferenced = definition.def.isUnreferenced(parentModule) detailDef = definition.def as TestcaseDef } else if (definition.def instanceof AltstepDef) { notReferenced = definition.def.isUnreferenced(parentModule) detailDef = definition.def as AltstepDef } else if (definition.def instanceof TypeDef) { val body = (definition.def as TypeDef).body if (body.structured != null) { if (body.structured.recordOf != null && body.structured.recordOf instanceof RecordOfDefNamed) { notReferenced = body.structured.recordOf.isUnreferenced(parentModule) detailDef = body.structured.recordOf as RecordOfDefNamed } if (body.structured.setOf != null && body.structured.setOf instanceof SetOfDefNamed) { notReferenced = body.structured.setOf.isUnreferenced(parentModule) detailDef = body.structured.setOf as SetOfDefNamed } if (body.structured.record != null && body.structured.record instanceof RecordDefNamed) { notReferenced = body.structured.record.isUnreferenced(parentModule) detailDef = body.structured.record as RecordDefNamed } if (body.structured.union != null && body.structured.union instanceof UnionDefNamed) { notReferenced = body.structured.union.isUnreferenced(parentModule) detailDef = body.structured.union as UnionDefNamed } if (body.structured.set != null && body.structured.set instanceof SetDefNamed) { notReferenced = body.structured.set.isUnreferenced(parentModule) detailDef = body.structured.set as SetDefNamed } if (body.structured.port != null && body.structured.port instanceof PortDef) { notReferenced = body.structured.port.isUnreferenced(parentModule) detailDef = body.structured.port as PortDef } if (body.structured.component != null && body.structured.component instanceof ComponentDef) { notReferenced = body.structured.component.isUnreferenced(parentModule) detailDef = body.structured.component as ComponentDef } } else if (body.sub != null) { if (body.sub instanceof SubTypeDefNamed) { notReferenced = body.sub.isUnreferenced(parentModule) detailDef = body.sub as SubTypeDefNamed } } } if (notReferenced) { val message = "Definition for \"" + detailDef.name + "\" is never referenced!" val INode node = NodeModelUtils.getNode(detailDef) warning( message, null, //TODO: EStructuralFeature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.17, " + MiscTools.getMethodName() ); } } private def boolean isUnreferenced(EObject type, EObject parent) { val result = UsageCrossReferencer.find(type, parent) result.size == 0 } @Check def checkNoInlineTemplates(InLineTemplate template) { if (!activeProfile.checkNoInlineTemplates) return; val message = "Inline Template is used!" val INode node = NodeModelUtils.getNode(template) warning( message, null, //TODO: EStructuralFeature MessageClass.STYLE.toString, node.startLine.toString, node.endLine.toString, "6.13, " + MiscTools.getMethodName() ); } /** * END: Code Style ------------------------------------------------------------------------------ */ //TODO: update error parameters /* @Check def checkUniqueNameNestedVariable(RefValue variable) { variable.isNameClashInHierarchy Loading Loading @@ -1214,4 +1636,5 @@ class TTCN3Validator extends AbstractTTCN3Validator { } return false; } */ }