Loading de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/TTCN3.xtext +6 −5 Original line number Diff line number Diff line Loading @@ -171,7 +171,7 @@ AltstepLocalDefList: {AltstepLocalDefList} (local+=AltstepLocalDef withstm+=WithStatement? sc+=SEMICOLON?)*; AltstepLocalDef: VarInstance | TimerInstance | ConstDef | TemplateDef; variable=VarInstance | timer=TimerInstance | const=ConstDef | template=TemplateDef; TestcaseDef: TESTCASEKEYWORD name=IDENTIFIER LPAREN parList=TemplateOrValueFormalParList? RPAREN spec=ConfigSpec Loading Loading @@ -256,7 +256,7 @@ AltConstruct: ALTKEYWORD LBRACKET AltGuardList RBRACKET; AltGuardList: {AltGuardList} (st+=GuardStatement | else+=ElseStatement SEMICOLON?)*; {AltGuardList} (guardList+=GuardStatement | elseList+=ElseStatement SEMICOLON?)*; ElseStatement: SQUAREOPEN ELSEKEYWORD SQUARECLOSE StatementBlock; Loading Loading @@ -361,8 +361,9 @@ PortTriggerOp: ReceiveStatement: any=PortOrAny DOT receive=PortReceiveOp; // TODO: extend with other possible references PortOrAny: ArrayIdentifierRef | {PortOrAny} ANYKEYWORD PORTKEYWORD; ref=[PortElement|IDENTIFIER] | {PortOrAny} ANYKEYWORD PORTKEYWORD; PortReceiveOp: {PortReceiveOp} RECEIVEOPKEYWORD (LPAREN template=InLineTemplate RPAREN)? from=FromClause? redirect=PortRedirect?; Loading Loading @@ -640,7 +641,7 @@ TypeDefBody: SubTypeDef: type=Type ADDRESSKEYWORD array=ArrayDef? spec=SubTypeSpec? | SubTypeDefNamed; SubTypeDefNamed returns SubTypeDef: SubTypeDefNamed: type=Type name=IDENTIFIER array=ArrayDef? spec=SubTypeSpec?; StructuredTypeDef: Loading Loading @@ -725,7 +726,7 @@ ComponentDefList: element=ComponentElementDef wst=WithStatement? sc=SEMICOLON?; PortInstance: PORTKEYWORD name=ExtendedIdentifier element+=PortElement (COMMA element+=PortElement)*; PORTKEYWORD ref=[PortDef|IDENTIFIER] instances+=PortElement (COMMA instances+=PortElement)*; PortElement: name=IDENTIFIER array=ArrayDef?; Loading de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/scoping/TTCN3ScopeProvider.xtend +28 −2 Original line number Diff line number Diff line Loading @@ -14,6 +14,12 @@ import de.ugoe.cs.swe.tTCN3.ModuleDefinition import de.ugoe.cs.swe.tTCN3.FieldSpec import de.ugoe.cs.swe.tTCN3.TemplateDef import de.ugoe.cs.swe.tTCN3.RecordDefNamed import de.ugoe.cs.swe.tTCN3.PortOrAny import de.ugoe.cs.swe.tTCN3.AltstepDef import java.util.ArrayList import org.eclipse.emf.ecore.EObject import de.ugoe.cs.swe.tTCN3.ComponentDefList import de.ugoe.cs.swe.tTCN3.PortElement class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider { Loading @@ -37,7 +43,6 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider { scopeFor(inner) } def IScope scope_FieldSpec_ref(FieldSpec spec, EReference ref) { val template = spec.findDesiredParent(typeof(TemplateDef)) as TemplateDef val type = template.base.type Loading @@ -49,4 +54,25 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider { scopeFor(inner) } def IScope scope_PortOrAny_ref(PortOrAny spec, EReference ref) { val altstep = spec.findDesiredParent(typeof(AltstepDef)) as AltstepDef val inner = newArrayList if (altstep.spec != null) { componentScopePorts(altstep.spec.component, inner) } scopeFor(inner) } // TODO: use this for other types (constDef, singleVar, template) // TODO: treat extended components def private void componentScopePorts(ComponentDef component, ArrayList<EObject> list) { for (ComponentDefList l: component.defs.filter[it.element.port != null]) { for (PortElement e: l.element.port.instances) { list.add(e) } } } } de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/validation/TTCN3Validator.xtend +85 −24 Original line number Diff line number Diff line Loading @@ -28,6 +28,14 @@ import de.ugoe.cs.swe.tTCN3.TemplateOrValueFormalParList import de.ugoe.cs.swe.tTCN3.TemplateOrValueFormalPar import de.ugoe.cs.swe.tTCN3.TestcaseDef import org.eclipse.emf.ecore.EStructuralFeature import de.ugoe.cs.swe.tTCN3.StructFieldDef import static extension de.ugoe.cs.swe.common.TTCN3ScopeHelper.* import de.ugoe.cs.swe.tTCN3.impl.SingleConstDefImpl import de.ugoe.cs.swe.tTCN3.impl.RefValueImpl import de.ugoe.cs.swe.tTCN3.StructDefBody import de.ugoe.cs.swe.tTCN3.AltstepDef import de.ugoe.cs.swe.tTCN3.AltstepLocalDef import de.ugoe.cs.swe.tTCN3.AltstepLocalDefList class TTCN3Validator extends AbstractTTCN3Validator { Loading @@ -46,6 +54,42 @@ class TTCN3Validator extends AbstractTTCN3Validator { variable.isNameClashInHierarchy } @Check def checkUniqueNameStructFieldDef(StructFieldDef field) { // find name clashes with module variables val container = field.findDesiredParent(typeof(ModuleDefinitionsList)) as ModuleDefinitionsList val defs = container.definitions.filter[it.def instanceof ConstDef] // TODO: || it.def instanceof ModuleParDef for (EObject v : defs) { val constDefList = ((v as ModuleDefinition).def as ConstDef).defs as ConstList for (SingleConstDef d : constDefList.list) { if (field.name.equals(d.name)) { error('Name clash with another variable definition in this scope!', TTCN3Package.eINSTANCE.structFieldRef_Name); return; } } } // find name clashes with variables in parent body val body = field.findDesiredParent(typeof(StructDefBody)) as StructDefBody for (StructFieldDef f: body.defs) { if (f != field && f.name.equals(field.name)) { error('Name clash with another variable definition in this scope!', TTCN3Package.eINSTANCE.structFieldRef_Name); return; } } } @Check def checkModuleStartsWithM(TTCN3Module module) { val char pattern = 'M'; if (module.name.charAt(0) != pattern) { warning('Module names should start with M!', TTCN3Package.eINSTANCE.TTCN3Module_Name); } } // TODO: adapt auto-completion (remove extended types) // TODO: treat cyclic dependencies?? @Check Loading @@ -64,21 +108,12 @@ class TTCN3Validator extends AbstractTTCN3Validator { def private isNameClashInHierarchy(RefValue variable) { var parent = variable.eContainer var EStructuralFeature feature = null; // if (variable instanceof SingleConstDef) // feature = null // else if (variable instanceof SingleVarInstance) // feature = null // else if (variable instanceof FormalValuePar) // feature = TTCN3Package.eINSTANCE. val EStructuralFeature feature = TTCN3Package.eINSTANCE.refValue_Name; while (parent != null) { if (parent instanceof TTCN3Module) { if (parent.defs != null && parent.defs.checkNameClashModuleDefinitionsList(variable)) { // TODO: TTCN3Package$Literals::SINGLE_CONST_DEF__NAME error('Name clash with another variable definition in this scope!', feature); return; } Loading Loading @@ -127,7 +162,18 @@ class TTCN3Validator extends AbstractTTCN3Validator { error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof AltstepDef) { if (parent.params != null && parent.params.checkNameClashFunctionParameterValue(variable)) { error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof AltstepLocalDefList) { if (parent.checkNameClasAltstepLocalDefList(variable)) { error('Name clash with another variable definition in this scope!', feature); return; } } // TODO: other references in scope parent = parent.eContainer Loading Loading @@ -263,13 +309,28 @@ class TTCN3Validator extends AbstractTTCN3Validator { return false; } @Check def checkModuleStartsWithM(TTCN3Module module) { val char pattern = 'M'; def private boolean checkNameClasAltstepLocalDefList(AltstepLocalDefList list, RefValue variable) { for (AltstepLocalDef a : list.local.filter[it != null]) { if (module.name.charAt(0) != pattern) { warning('Module names should start with M!', TTCN3Package.eINSTANCE.TTCN3Module_Name); if (a.const != null) { val constDefList = a.const.defs as ConstList for (SingleConstDef d : constDefList.list) { if (d != variable && d.name == variable.name) { return true; } } } if (a.variable != null) { val varList = a.variable.list as VarList for (SingleVarInstance d : varList.variables) { if (d != variable && d.name == variable.name) { return true; } } } } return false; } } Loading
de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/TTCN3.xtext +6 −5 Original line number Diff line number Diff line Loading @@ -171,7 +171,7 @@ AltstepLocalDefList: {AltstepLocalDefList} (local+=AltstepLocalDef withstm+=WithStatement? sc+=SEMICOLON?)*; AltstepLocalDef: VarInstance | TimerInstance | ConstDef | TemplateDef; variable=VarInstance | timer=TimerInstance | const=ConstDef | template=TemplateDef; TestcaseDef: TESTCASEKEYWORD name=IDENTIFIER LPAREN parList=TemplateOrValueFormalParList? RPAREN spec=ConfigSpec Loading Loading @@ -256,7 +256,7 @@ AltConstruct: ALTKEYWORD LBRACKET AltGuardList RBRACKET; AltGuardList: {AltGuardList} (st+=GuardStatement | else+=ElseStatement SEMICOLON?)*; {AltGuardList} (guardList+=GuardStatement | elseList+=ElseStatement SEMICOLON?)*; ElseStatement: SQUAREOPEN ELSEKEYWORD SQUARECLOSE StatementBlock; Loading Loading @@ -361,8 +361,9 @@ PortTriggerOp: ReceiveStatement: any=PortOrAny DOT receive=PortReceiveOp; // TODO: extend with other possible references PortOrAny: ArrayIdentifierRef | {PortOrAny} ANYKEYWORD PORTKEYWORD; ref=[PortElement|IDENTIFIER] | {PortOrAny} ANYKEYWORD PORTKEYWORD; PortReceiveOp: {PortReceiveOp} RECEIVEOPKEYWORD (LPAREN template=InLineTemplate RPAREN)? from=FromClause? redirect=PortRedirect?; Loading Loading @@ -640,7 +641,7 @@ TypeDefBody: SubTypeDef: type=Type ADDRESSKEYWORD array=ArrayDef? spec=SubTypeSpec? | SubTypeDefNamed; SubTypeDefNamed returns SubTypeDef: SubTypeDefNamed: type=Type name=IDENTIFIER array=ArrayDef? spec=SubTypeSpec?; StructuredTypeDef: Loading Loading @@ -725,7 +726,7 @@ ComponentDefList: element=ComponentElementDef wst=WithStatement? sc=SEMICOLON?; PortInstance: PORTKEYWORD name=ExtendedIdentifier element+=PortElement (COMMA element+=PortElement)*; PORTKEYWORD ref=[PortDef|IDENTIFIER] instances+=PortElement (COMMA instances+=PortElement)*; PortElement: name=IDENTIFIER array=ArrayDef?; Loading
de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/scoping/TTCN3ScopeProvider.xtend +28 −2 Original line number Diff line number Diff line Loading @@ -14,6 +14,12 @@ import de.ugoe.cs.swe.tTCN3.ModuleDefinition import de.ugoe.cs.swe.tTCN3.FieldSpec import de.ugoe.cs.swe.tTCN3.TemplateDef import de.ugoe.cs.swe.tTCN3.RecordDefNamed import de.ugoe.cs.swe.tTCN3.PortOrAny import de.ugoe.cs.swe.tTCN3.AltstepDef import java.util.ArrayList import org.eclipse.emf.ecore.EObject import de.ugoe.cs.swe.tTCN3.ComponentDefList import de.ugoe.cs.swe.tTCN3.PortElement class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider { Loading @@ -37,7 +43,6 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider { scopeFor(inner) } def IScope scope_FieldSpec_ref(FieldSpec spec, EReference ref) { val template = spec.findDesiredParent(typeof(TemplateDef)) as TemplateDef val type = template.base.type Loading @@ -49,4 +54,25 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider { scopeFor(inner) } def IScope scope_PortOrAny_ref(PortOrAny spec, EReference ref) { val altstep = spec.findDesiredParent(typeof(AltstepDef)) as AltstepDef val inner = newArrayList if (altstep.spec != null) { componentScopePorts(altstep.spec.component, inner) } scopeFor(inner) } // TODO: use this for other types (constDef, singleVar, template) // TODO: treat extended components def private void componentScopePorts(ComponentDef component, ArrayList<EObject> list) { for (ComponentDefList l: component.defs.filter[it.element.port != null]) { for (PortElement e: l.element.port.instances) { list.add(e) } } } }
de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/validation/TTCN3Validator.xtend +85 −24 Original line number Diff line number Diff line Loading @@ -28,6 +28,14 @@ import de.ugoe.cs.swe.tTCN3.TemplateOrValueFormalParList import de.ugoe.cs.swe.tTCN3.TemplateOrValueFormalPar import de.ugoe.cs.swe.tTCN3.TestcaseDef import org.eclipse.emf.ecore.EStructuralFeature import de.ugoe.cs.swe.tTCN3.StructFieldDef import static extension de.ugoe.cs.swe.common.TTCN3ScopeHelper.* import de.ugoe.cs.swe.tTCN3.impl.SingleConstDefImpl import de.ugoe.cs.swe.tTCN3.impl.RefValueImpl import de.ugoe.cs.swe.tTCN3.StructDefBody import de.ugoe.cs.swe.tTCN3.AltstepDef import de.ugoe.cs.swe.tTCN3.AltstepLocalDef import de.ugoe.cs.swe.tTCN3.AltstepLocalDefList class TTCN3Validator extends AbstractTTCN3Validator { Loading @@ -46,6 +54,42 @@ class TTCN3Validator extends AbstractTTCN3Validator { variable.isNameClashInHierarchy } @Check def checkUniqueNameStructFieldDef(StructFieldDef field) { // find name clashes with module variables val container = field.findDesiredParent(typeof(ModuleDefinitionsList)) as ModuleDefinitionsList val defs = container.definitions.filter[it.def instanceof ConstDef] // TODO: || it.def instanceof ModuleParDef for (EObject v : defs) { val constDefList = ((v as ModuleDefinition).def as ConstDef).defs as ConstList for (SingleConstDef d : constDefList.list) { if (field.name.equals(d.name)) { error('Name clash with another variable definition in this scope!', TTCN3Package.eINSTANCE.structFieldRef_Name); return; } } } // find name clashes with variables in parent body val body = field.findDesiredParent(typeof(StructDefBody)) as StructDefBody for (StructFieldDef f: body.defs) { if (f != field && f.name.equals(field.name)) { error('Name clash with another variable definition in this scope!', TTCN3Package.eINSTANCE.structFieldRef_Name); return; } } } @Check def checkModuleStartsWithM(TTCN3Module module) { val char pattern = 'M'; if (module.name.charAt(0) != pattern) { warning('Module names should start with M!', TTCN3Package.eINSTANCE.TTCN3Module_Name); } } // TODO: adapt auto-completion (remove extended types) // TODO: treat cyclic dependencies?? @Check Loading @@ -64,21 +108,12 @@ class TTCN3Validator extends AbstractTTCN3Validator { def private isNameClashInHierarchy(RefValue variable) { var parent = variable.eContainer var EStructuralFeature feature = null; // if (variable instanceof SingleConstDef) // feature = null // else if (variable instanceof SingleVarInstance) // feature = null // else if (variable instanceof FormalValuePar) // feature = TTCN3Package.eINSTANCE. val EStructuralFeature feature = TTCN3Package.eINSTANCE.refValue_Name; while (parent != null) { if (parent instanceof TTCN3Module) { if (parent.defs != null && parent.defs.checkNameClashModuleDefinitionsList(variable)) { // TODO: TTCN3Package$Literals::SINGLE_CONST_DEF__NAME error('Name clash with another variable definition in this scope!', feature); return; } Loading Loading @@ -127,7 +162,18 @@ class TTCN3Validator extends AbstractTTCN3Validator { error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof AltstepDef) { if (parent.params != null && parent.params.checkNameClashFunctionParameterValue(variable)) { error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof AltstepLocalDefList) { if (parent.checkNameClasAltstepLocalDefList(variable)) { error('Name clash with another variable definition in this scope!', feature); return; } } // TODO: other references in scope parent = parent.eContainer Loading Loading @@ -263,13 +309,28 @@ class TTCN3Validator extends AbstractTTCN3Validator { return false; } @Check def checkModuleStartsWithM(TTCN3Module module) { val char pattern = 'M'; def private boolean checkNameClasAltstepLocalDefList(AltstepLocalDefList list, RefValue variable) { for (AltstepLocalDef a : list.local.filter[it != null]) { if (module.name.charAt(0) != pattern) { warning('Module names should start with M!', TTCN3Package.eINSTANCE.TTCN3Module_Name); if (a.const != null) { val constDefList = a.const.defs as ConstList for (SingleConstDef d : constDefList.list) { if (d != variable && d.name == variable.name) { return true; } } } if (a.variable != null) { val varList = a.variable.list as VarList for (SingleVarInstance d : varList.variables) { if (d != variable && d.name == variable.name) { return true; } } } } return false; } }