Loading de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/TTCN3.xtext +10 −13 Original line number Diff line number Diff line Loading @@ -174,14 +174,11 @@ AltstepLocalDef: VarInstance | TimerInstance | ConstDef | TemplateDef; TestcaseDef: TESTCASEKEYWORD name=IDENTIFIER LPAREN params=TemplateOrValueFormalParList? RPAREN speck=ConfigSpec TESTCASEKEYWORD name=IDENTIFIER LPAREN parList=TemplateOrValueFormalParList? RPAREN spec=ConfigSpec statement=StatementBlock; TestcaseRef: name=[TestcaseDef|IDENTIFIER]; TemplateOrValueFormalParList: par+=TemplateOrValueFormalPar (COMMA par+=TemplateOrValueFormalPar); params+=TemplateOrValueFormalPar (COMMA params+=TemplateOrValueFormalPar)*; TemplateOrValueFormalPar: value=FormalValuePar | template=FormalTemplatePar; Loading Loading @@ -433,8 +430,8 @@ ComponentOrDefaultReference: variable=VariableRef | function=FunctionInstance; TestcaseInstance: EXECUTEKEYWORD LPAREN TestcaseRef LPAREN tcParams=TestcaseActualParList? RPAREN (COMMA (expr=Expression | MINUS) (COMMA sexpr=SingleExpression)?)? RPAREN; EXECUTEKEYWORD LPAREN ref=[TestcaseDef|IDENTIFIER] LPAREN tcParams=TestcaseActualParList? RPAREN (COMMA (expr=Expression | MINUS) (COMMA sexpr=SingleExpression)?)? RPAREN; TestcaseActualParList: (templParam+=TemplateInstanceActualPar (COMMA templParam+=TemplateInstanceActualPar)*) | Loading Loading @@ -653,7 +650,7 @@ StructuredTypeDef: RecordDef: RECORDKEYWORD ADDRESSKEYWORD StructDefBody | RecordDefNamed; RecordDefNamed returns RecordDef: RecordDefNamed: RECORDKEYWORD name=IDENTIFIER body=StructDefBody; RecordOfDef: Loading Loading @@ -720,7 +717,6 @@ ProcedureAttribs: PROCEDUREKEYWORD LBRACKET ((addresses+=AddressDecl | procs+=ProcedureList | configs+=ConfigParamDef) SEMICOLON?)+ RBRACKET; // TODO: restrict extends type scope (do not allow self referencing) ComponentDef: COMPONENTKEYWORD name=IDENTIFIER (EXTENDSKEYWORD extends+=[ComponentDef|IDENTIFIER] (COMMA extends+=[ComponentDef|IDENTIFIER])*)? LBRACKET defs+=ComponentDefList* RBRACKET; Loading Loading @@ -835,7 +831,7 @@ PatternParticle: {PatternParticle} CSTRING | ReferencedValue; TemplateDef: TEMPLATEKEYWORD res=TemplateRestriction? base=BaseTemplate derived=DerivedDef? ac=ASSIGNMENTCHAR body=TemplateBody; TEMPLATEKEYWORD res=TemplateRestriction? base=BaseTemplate derived=DerivedDef? ASSIGNMENTCHAR body=TemplateBody; DerivedDef: MODIFIESKEYWORD name=ExtendedIdentifier; Loading Loading @@ -868,7 +864,7 @@ FieldSpecList: LBRACKET spec+=FieldSpec (COMMA spec+=FieldSpec)* RBRACKET; FieldSpec: ref=FieldReference ASSIGNMENTCHAR (body=TemplateBody | MINUS); ref=[StructFieldDef|IDENTIFIER] ASSIGNMENTCHAR (body=TemplateBody | MINUS); SimpleSpec: expr=SingleExpression (STRINGOP spec=SimpleTemplateSpec)? | spec=SimpleTemplateSpec; Loading @@ -877,7 +873,7 @@ SimpleTemplateSpec: expr=SingleTemplateExpression (STRINGOP spec=SimpleSpec)?; SingleTemplateExpression: symbol=MatchingSymbol | list=TemplateRefWithParList ref+=ExtendedFieldReference*; symbol=MatchingSymbol | list=TemplateRefWithParList ref+=ExtendedFieldReference; TemplateRefWithParList: name=ExtendedIdentifier list=TemplateActualParList?; Loading Loading @@ -1045,7 +1041,8 @@ ReferencedValue: ref=[RefValue|IDENTIFIER] ext+=ExtendedFieldReference*; RefValue: SingleConstDef | ModuleParameter | SingleVarInstance | RecordOfDefNamed | SetOfDefNamed | FormalValuePar; SingleConstDef | ModuleParameter | SingleVarInstance | RecordOfDefNamed | SetOfDefNamed | FormalValuePar | FormalTemplatePar; // IDENTIFIER omitted PredefinedValue: Loading de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/scoping/TTCN3ScopeProvider.xtend +15 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,9 @@ import de.ugoe.cs.swe.tTCN3.ComponentDef import de.ugoe.cs.swe.tTCN3.ModuleDefinitionsList import de.ugoe.cs.swe.tTCN3.TypeDef 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 class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider { Loading @@ -34,4 +37,16 @@ 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 val inner = newArrayList if (type != null && type.ref != null && typeof(RecordDefNamed).isAssignableFrom(type.ref.class)) { inner.addAll((type.ref as RecordDefNamed).body.defs) } scopeFor(inner) } } de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/validation/TTCN3Validator.xtend +47 −11 Original line number Diff line number Diff line Loading @@ -24,6 +24,10 @@ import de.ugoe.cs.swe.tTCN3.ModuleControlPart import de.ugoe.cs.swe.tTCN3.ControlStatementOrDefList import de.ugoe.cs.swe.tTCN3.ComponentDef import de.ugoe.cs.swe.tTCN3.ComponentDefList 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 class TTCN3Validator extends AbstractTTCN3Validator { Loading Loading @@ -60,48 +64,67 @@ 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. 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!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof StatementBlock) { if (parent.checkNameClasStatementBlock(variable)) { error('Name clash with another variable definition in this scope!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof Initial) { if (parent.checkNameClashInitial(variable)) { error('Name clash with another variable definition in this scope!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof ForStatement) { if (parent.init.checkNameClashInitial(variable)) { error('Name clash with another variable definition in this scope!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof FunctionDef) { if (parent.parameterList != null && parent.parameterList.checkNameClashFunctionParameterValue(variable)) { error('Name clash with another variable definition in this scope!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof FunctionFormalParList) { if (parent.checkNameClashFunctionParameterValue(variable)) { error('Name clash with another variable definition in this scope!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof ModuleControlPart) { if (parent.checkNameClashModuleControlPart(variable)) { error('Name clash with another variable definition in this scope!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof ComponentDef) { if (!parent.checkNameClashComponentDefHierarchy(variable)) { error('Name clash with another variable definition in this scope!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof TestcaseDef) { if (parent.parList.checkNameClashTemplateOrValueFormalParList(variable)) { error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof TemplateOrValueFormalParList) { if (parent.checkNameClashTemplateOrValueFormalParList(variable)) { error('Name clash with another variable definition in this scope!', feature); return; } } Loading Loading @@ -225,14 +248,27 @@ class TTCN3Validator extends AbstractTTCN3Validator { return res; } def private boolean checkNameClashTemplateOrValueFormalParList(TemplateOrValueFormalParList list, RefValue variable) { var RefValue value; for (TemplateOrValueFormalPar p: list.params) { if (p.value != null) value = p.value as RefValue else if (p.template != null) value = p.template as RefValue; if (value != null && value != variable && value.name == variable.name) return true; } return false; } @Check def checkModuleStartsWithM(TTCN3Module module) { val char pattern = 'M'; if (module.name.charAt(0) != pattern) { //TODO: TTCN3Package$Literals::TTCN3_MODULE__NAME or get EStructuralFeature from somewhere else warning('Module names should start with M!', null, TTCN3Package.TTCN3_MODULE__NAME); warning('Module names should start with M!', TTCN3Package.eINSTANCE.TTCN3Module_Name); } } Loading Loading
de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/TTCN3.xtext +10 −13 Original line number Diff line number Diff line Loading @@ -174,14 +174,11 @@ AltstepLocalDef: VarInstance | TimerInstance | ConstDef | TemplateDef; TestcaseDef: TESTCASEKEYWORD name=IDENTIFIER LPAREN params=TemplateOrValueFormalParList? RPAREN speck=ConfigSpec TESTCASEKEYWORD name=IDENTIFIER LPAREN parList=TemplateOrValueFormalParList? RPAREN spec=ConfigSpec statement=StatementBlock; TestcaseRef: name=[TestcaseDef|IDENTIFIER]; TemplateOrValueFormalParList: par+=TemplateOrValueFormalPar (COMMA par+=TemplateOrValueFormalPar); params+=TemplateOrValueFormalPar (COMMA params+=TemplateOrValueFormalPar)*; TemplateOrValueFormalPar: value=FormalValuePar | template=FormalTemplatePar; Loading Loading @@ -433,8 +430,8 @@ ComponentOrDefaultReference: variable=VariableRef | function=FunctionInstance; TestcaseInstance: EXECUTEKEYWORD LPAREN TestcaseRef LPAREN tcParams=TestcaseActualParList? RPAREN (COMMA (expr=Expression | MINUS) (COMMA sexpr=SingleExpression)?)? RPAREN; EXECUTEKEYWORD LPAREN ref=[TestcaseDef|IDENTIFIER] LPAREN tcParams=TestcaseActualParList? RPAREN (COMMA (expr=Expression | MINUS) (COMMA sexpr=SingleExpression)?)? RPAREN; TestcaseActualParList: (templParam+=TemplateInstanceActualPar (COMMA templParam+=TemplateInstanceActualPar)*) | Loading Loading @@ -653,7 +650,7 @@ StructuredTypeDef: RecordDef: RECORDKEYWORD ADDRESSKEYWORD StructDefBody | RecordDefNamed; RecordDefNamed returns RecordDef: RecordDefNamed: RECORDKEYWORD name=IDENTIFIER body=StructDefBody; RecordOfDef: Loading Loading @@ -720,7 +717,6 @@ ProcedureAttribs: PROCEDUREKEYWORD LBRACKET ((addresses+=AddressDecl | procs+=ProcedureList | configs+=ConfigParamDef) SEMICOLON?)+ RBRACKET; // TODO: restrict extends type scope (do not allow self referencing) ComponentDef: COMPONENTKEYWORD name=IDENTIFIER (EXTENDSKEYWORD extends+=[ComponentDef|IDENTIFIER] (COMMA extends+=[ComponentDef|IDENTIFIER])*)? LBRACKET defs+=ComponentDefList* RBRACKET; Loading Loading @@ -835,7 +831,7 @@ PatternParticle: {PatternParticle} CSTRING | ReferencedValue; TemplateDef: TEMPLATEKEYWORD res=TemplateRestriction? base=BaseTemplate derived=DerivedDef? ac=ASSIGNMENTCHAR body=TemplateBody; TEMPLATEKEYWORD res=TemplateRestriction? base=BaseTemplate derived=DerivedDef? ASSIGNMENTCHAR body=TemplateBody; DerivedDef: MODIFIESKEYWORD name=ExtendedIdentifier; Loading Loading @@ -868,7 +864,7 @@ FieldSpecList: LBRACKET spec+=FieldSpec (COMMA spec+=FieldSpec)* RBRACKET; FieldSpec: ref=FieldReference ASSIGNMENTCHAR (body=TemplateBody | MINUS); ref=[StructFieldDef|IDENTIFIER] ASSIGNMENTCHAR (body=TemplateBody | MINUS); SimpleSpec: expr=SingleExpression (STRINGOP spec=SimpleTemplateSpec)? | spec=SimpleTemplateSpec; Loading @@ -877,7 +873,7 @@ SimpleTemplateSpec: expr=SingleTemplateExpression (STRINGOP spec=SimpleSpec)?; SingleTemplateExpression: symbol=MatchingSymbol | list=TemplateRefWithParList ref+=ExtendedFieldReference*; symbol=MatchingSymbol | list=TemplateRefWithParList ref+=ExtendedFieldReference; TemplateRefWithParList: name=ExtendedIdentifier list=TemplateActualParList?; Loading Loading @@ -1045,7 +1041,8 @@ ReferencedValue: ref=[RefValue|IDENTIFIER] ext+=ExtendedFieldReference*; RefValue: SingleConstDef | ModuleParameter | SingleVarInstance | RecordOfDefNamed | SetOfDefNamed | FormalValuePar; SingleConstDef | ModuleParameter | SingleVarInstance | RecordOfDefNamed | SetOfDefNamed | FormalValuePar | FormalTemplatePar; // IDENTIFIER omitted PredefinedValue: Loading
de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/scoping/TTCN3ScopeProvider.xtend +15 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,9 @@ import de.ugoe.cs.swe.tTCN3.ComponentDef import de.ugoe.cs.swe.tTCN3.ModuleDefinitionsList import de.ugoe.cs.swe.tTCN3.TypeDef 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 class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider { Loading @@ -34,4 +37,16 @@ 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 val inner = newArrayList if (type != null && type.ref != null && typeof(RecordDefNamed).isAssignableFrom(type.ref.class)) { inner.addAll((type.ref as RecordDefNamed).body.defs) } scopeFor(inner) } }
de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/validation/TTCN3Validator.xtend +47 −11 Original line number Diff line number Diff line Loading @@ -24,6 +24,10 @@ import de.ugoe.cs.swe.tTCN3.ModuleControlPart import de.ugoe.cs.swe.tTCN3.ControlStatementOrDefList import de.ugoe.cs.swe.tTCN3.ComponentDef import de.ugoe.cs.swe.tTCN3.ComponentDefList 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 class TTCN3Validator extends AbstractTTCN3Validator { Loading Loading @@ -60,48 +64,67 @@ 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. 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!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof StatementBlock) { if (parent.checkNameClasStatementBlock(variable)) { error('Name clash with another variable definition in this scope!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof Initial) { if (parent.checkNameClashInitial(variable)) { error('Name clash with another variable definition in this scope!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof ForStatement) { if (parent.init.checkNameClashInitial(variable)) { error('Name clash with another variable definition in this scope!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof FunctionDef) { if (parent.parameterList != null && parent.parameterList.checkNameClashFunctionParameterValue(variable)) { error('Name clash with another variable definition in this scope!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof FunctionFormalParList) { if (parent.checkNameClashFunctionParameterValue(variable)) { error('Name clash with another variable definition in this scope!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof ModuleControlPart) { if (parent.checkNameClashModuleControlPart(variable)) { error('Name clash with another variable definition in this scope!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof ComponentDef) { if (!parent.checkNameClashComponentDefHierarchy(variable)) { error('Name clash with another variable definition in this scope!', null, -1); error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof TestcaseDef) { if (parent.parList.checkNameClashTemplateOrValueFormalParList(variable)) { error('Name clash with another variable definition in this scope!', feature); return; } } else if (parent instanceof TemplateOrValueFormalParList) { if (parent.checkNameClashTemplateOrValueFormalParList(variable)) { error('Name clash with another variable definition in this scope!', feature); return; } } Loading Loading @@ -225,14 +248,27 @@ class TTCN3Validator extends AbstractTTCN3Validator { return res; } def private boolean checkNameClashTemplateOrValueFormalParList(TemplateOrValueFormalParList list, RefValue variable) { var RefValue value; for (TemplateOrValueFormalPar p: list.params) { if (p.value != null) value = p.value as RefValue else if (p.template != null) value = p.template as RefValue; if (value != null && value != variable && value.name == variable.name) return true; } return false; } @Check def checkModuleStartsWithM(TTCN3Module module) { val char pattern = 'M'; if (module.name.charAt(0) != pattern) { //TODO: TTCN3Package$Literals::TTCN3_MODULE__NAME or get EStructuralFeature from somewhere else warning('Module names should start with M!', null, TTCN3Package.TTCN3_MODULE__NAME); warning('Module names should start with M!', TTCN3Package.eINSTANCE.TTCN3Module_Name); } } Loading