Commit 5a37ec92 authored by Miklos Magyari's avatar Miklos Magyari
Browse files

OOP: semantic check - class functions cannot have `runs on`, `mtc` or `system` clause (issue #427)


Signed-off-by: Miklos Magyari's avatarMiklos Magyari <miklos.magyari@sigmatechnology.se>
parent 35234188
......@@ -227,6 +227,25 @@ function f_class_param(FuncClass pl_fun) {
var charstring vl_chr := pl_fun.f_get_one(); // correct
}
// class function with `runs on`, `mtc` and `system` clause
type class BadClauses {
public function f_with_runson() runs on CT {
}
public function f_with_mtc() mtc CT return integer {
return 1;
}
public function f_with_system() system CT {
}
public function f_with_more() runs on CT mtc CT system CT {
}
}
testcase tc_basicSyntax() runs on CT {
var GrandSubClass vl_gsc := GrandSubClass.create;
......
......@@ -112,6 +112,10 @@ public final class Def_Function extends Definition implements IParameterisedAssi
private static final String DASHALLOWEDONLYFORTEMPLATES = "Using not used symbol (`-') as the default parameter"
+ " is allowed only for modified templates";
private static final String CLASSNORUNSON = "Class functions cannot have a `runs on` clause";
private static final String CLASSNOMTC = "Class functions cannot have an `mtc` clause";
private static final String CLASSNOSYSTEM = "Class functions cannot have a `system` clause";
private static final String KIND = "function";
private final Assignment_type assignmentType;
......@@ -131,6 +135,7 @@ public final class Def_Function extends Definition implements IParameterisedAssi
private EncodingPrototype_type prototype;
private Type inputType;
private Type outputType;
private final boolean isClassFunction;
// stores whether this function can be started or not
private boolean isStartable;
......@@ -139,7 +144,7 @@ public final class Def_Function extends Definition implements IParameterisedAssi
public Def_Function(final Identifier identifier, final FormalParameterList formalParameters, final Reference runsOnRef,
final Reference mtcReference, final Reference systemReference, final Reference portReference,
final Type returnType, final boolean returnsTemplate, final TemplateRestriction.Restriction_type templateRestriction,
final StatementBlock block) {
final StatementBlock block, boolean isClassFunction) {
super(identifier);
assignmentType = (returnType == null) ? Assignment_type.A_FUNCTION : (returnsTemplate ? Assignment_type.A_FUNCTION_RTEMP
: Assignment_type.A_FUNCTION_RVAL);
......@@ -156,6 +161,7 @@ public final class Def_Function extends Definition implements IParameterisedAssi
this.returnsTemplate = returnsTemplate;
this.templateRestriction = templateRestriction;
this.block = block;
this.isClassFunction = isClassFunction;
this.prototype = EncodingPrototype_type.NONE;
inputType = null;
......@@ -183,6 +189,14 @@ public final class Def_Function extends Definition implements IParameterisedAssi
}
}
public Def_Function(final Identifier identifier, final FormalParameterList formalParameters, final Reference runsOnRef,
final Reference mtcReference, final Reference systemReference, final Reference portReference,
final Type returnType, final boolean returnsTemplate, final TemplateRestriction.Restriction_type templateRestriction,
final StatementBlock block) {
this(identifier, formalParameters, runsOnRef, mtcReference, systemReference, portReference, returnType,
returnsTemplate, templateRestriction, block, false);
}
/**
* Constructor for functions defined by 'object'
* @param identifier
......@@ -383,30 +397,42 @@ public final class Def_Function extends Definition implements IParameterisedAssi
portType = null;
isStartable = false;
if (runsOnRef != null && portReference != null) {
runsOnRef.getLocation().reportSemanticError("A `runs on' and a `port' clause cannot be present at the same time.");
}
if (runsOnRef != null) {
runsOnType = runsOnRef.chkComponentypeReference(timestamp);
if (runsOnType != null) {
final Scope formalParlistPreviosScope = formalParList.getParentScope();
if (formalParlistPreviosScope instanceof RunsOnScope
&& ((RunsOnScope) formalParlistPreviosScope).getParentScope() == myScope) {
((RunsOnScope) formalParlistPreviosScope).setComponentType(runsOnType);
} else {
final Scope tempScope = new RunsOnScope(runsOnType, myScope);
formalParList.setMyScope(tempScope);
if (isClassFunction) {
if (runsOnRef != null) {
runsOnRef.getLocation().reportSemanticError(CLASSNORUNSON);
}
if (mtcReference != null) {
mtcReference.getLocation().reportSemanticError(CLASSNOMTC);
}
if (systemReference!= null) {
systemReference.getLocation().reportSemanticError(CLASSNOSYSTEM);
}
} else {
if (runsOnRef != null && portReference != null) {
runsOnRef.getLocation().reportSemanticError("A `runs on' and a `port' clause cannot be present at the same time.");
}
if (runsOnRef != null) {
runsOnType = runsOnRef.chkComponentypeReference(timestamp);
if (runsOnType != null) {
final Scope formalParlistPreviosScope = formalParList.getParentScope();
if (formalParlistPreviosScope instanceof RunsOnScope
&& ((RunsOnScope) formalParlistPreviosScope).getParentScope() == myScope) {
((RunsOnScope) formalParlistPreviosScope).setComponentType(runsOnType);
} else {
final Scope tempScope = new RunsOnScope(runsOnType, myScope);
formalParList.setMyScope(tempScope);
}
}
}
}
if (mtcReference != null) {
mtcType = mtcReference.chkComponentypeReference(timestamp);
}
if (systemReference != null) {
systemType = systemReference.chkComponentypeReference(timestamp);
if (mtcReference != null) {
mtcType = mtcReference.chkComponentypeReference(timestamp);
}
if (systemReference != null) {
systemType = systemReference.chkComponentypeReference(timestamp);
}
}
boolean canSkip = false;
......
......@@ -9202,6 +9202,11 @@ pr_ClassFunctionDef returns[Def_Function def_func]
start1 = pr_LParen
(pl = pr_FunctionFormalParList { parameters = $pl.parList; } )?
end = pr_RParen
( runs = pr_RunsOnSpec[runsonHelper] { runsonHelper.runsonReference.setLocation(getLocation($runs.start, $runs.stop)); })?
mtc = pr_AltOrTcConfigSpec[ runsonHelper ] {
if (runsonHelper.mtcReference != null) runsonHelper.mtcReference.setLocation(getLocation($mtc.start, $mtc.stop));
if (runsonHelper.systemReference != null) runsonHelper.systemReference.setLocation(getLocation($mtc.start, $mtc.stop));
}
( rh = pr_ReturnType
{ returnHelper = $rh.helper;
if(returnHelper != null) {
......@@ -9217,7 +9222,7 @@ pr_ClassFunctionDef returns[Def_Function def_func]
if($id.identifier != null) {
if(parameters == null) { parameters = new FormalParameterList(new ArrayList<FormalParameter>()); }
parameters.setLocation(getLocation( $start1.start, $end.stop));
$def_func = new Def_Function($id.identifier, parameters, runsonHelper.runsonReference, runsonHelper.mtcReference, runsonHelper.systemReference, portReference, returnType, returnsTemplate, templateRestriction, statementBlock);
$def_func = new Def_Function($id.identifier, parameters, runsonHelper.runsonReference, runsonHelper.mtcReference, runsonHelper.systemReference, portReference, returnType, returnsTemplate, templateRestriction, statementBlock, true);
$def_func.setLocation(getLocation( $col.start, $sb.stop));
$def_func.setCommentLocation( getLastCommentLocation( $start ) );
}
......@@ -9229,11 +9234,11 @@ pr_ClassConstructorDef returns[Def_Function def_func]
StatementBlock statementBlock = null;
}:
( id = pr_CreateKeyword
pstart = pl_LParen
pstart = pr_LParen
( pl = pr_FunctionFormalParList {
parameters = $pl.parList;
})?
pstop = pl_RParen
pstop = pr_RParen
(
pr_ExtKeyword LPAREN
pr_FunctionFormalParList
......@@ -9255,7 +9260,7 @@ pr_ClassConstructorDef returns[Def_Function def_func]
if(parameters == null) { parameters = new FormalParameterList(new ArrayList<FormalParameter>()); }
parameters.setLocation(getLocation( $pstart.start, $pstop.stop));
Identifier id = new Identifier( Identifier_type.ID_TTCN, "create", getLocation($id.start, $id.stop ) );
$def_func = new Def_Function(id, parameters, null, null, null, null, null, false, null, statementBlock);
$def_func = new Def_Function(id, parameters, null, null, null, null, null, false, null, statementBlock, true);
$def_func.setLocation(getLocation( $id.start, $sb.stop));
$def_func.setCommentLocation( getLastCommentLocation( $start ) );
};
......
......@@ -45,7 +45,7 @@ public class OOP_Semantic_tests {
private ArrayList<MarkerToCheck> oopNegative_ttcn_initializer() {
//oopNegativeSemanticTest.ttcn
ArrayList<MarkerToCheck> markersToCheck = new ArrayList<MarkerToCheck>(33);
ArrayList<MarkerToCheck> markersToCheck = new ArrayList<MarkerToCheck>(39);
int lineNum = 28;
markersToCheck.add(new MarkerToCheck("class type expected", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 9;
......@@ -100,7 +100,17 @@ public class OOP_Semantic_tests {
markersToCheck.add(new MarkerToCheck("Formal parameter list differs from previous definition", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 7;
markersToCheck.add(new MarkerToCheck("Type mismatch: a value of type `integer' was expected instead of `float'", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 11;
lineNum += 6;
markersToCheck.add(new MarkerToCheck("Class functions cannot have a `runs on` clause", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 4;
markersToCheck.add(new MarkerToCheck("Class functions cannot have an `mtc` clause", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 4;
markersToCheck.add(new MarkerToCheck("Class functions cannot have a `system` clause", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 4;
markersToCheck.add(new MarkerToCheck("Class functions cannot have a `runs on` clause", lineNum, IMarker.SEVERITY_ERROR));
markersToCheck.add(new MarkerToCheck("Class functions cannot have a `system` clause", lineNum, IMarker.SEVERITY_ERROR));
markersToCheck.add(new MarkerToCheck("Class functions cannot have an `mtc` clause", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 12;
markersToCheck.add(new MarkerToCheck("Unknown field reference", lineNum, IMarker.SEVERITY_ERROR));
markersToCheck.add(new MarkerToCheck("Type mismatch: a value of type `charstring' was expected instead of `integer'", ++lineNum, IMarker.SEVERITY_ERROR));
lineNum += 8;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment