Commit 946bb665 authored by Miklos Magyari's avatar Miklos Magyari
Browse files

OOP: semantic check - external classes (issue #427)


Signed-off-by: Miklos Magyari's avatarMiklos Magyari <miklos.magyari@sigmatechnology.se>
parent 9560a988
......@@ -55,6 +55,13 @@ type class RepeatedExtends extends MinimalClass, BaseClass, MinimalClass {
}
// external classes cannot be extended by normal classes
type external class ExtClass {
}
type class ExtendExternal extends ExtClass { }
// runs on compatibility
type class RunsonClass1 runs on CT { }
type class RunsonClass2 extends RunsonClass1 runs on CT { }
......
......@@ -37,6 +37,7 @@ public final class ClassTypeReferenceList extends ASTNode implements ILocateable
private final String ONLYONNONTRAIT = "A class can only extend one non-trait class";
private final String TRAITEXTENDSTRAIT = "A trait class can only extend trait classes";
private final String FINALCANNOTBEEXTENDED = "A final class cannot be extended";
private final String EXTERNALEXTEND = "An external class cannot be extended by a non-external class";
private final String DUPLICATECOMPONENTREFERENCEFIRST = "Duplicate reference to class `{0}'' was first declared here";
private final String DUPLICATECOMPONENTREFERENCEREPEATED = "Duplicate reference to class `{0}'' was declared here again";
private final String CLASSCANNOTEXTENDITSELF = "A class cannot extend itself neither directly nor indirectly";
......@@ -142,6 +143,9 @@ public final class ClassTypeReferenceList extends ASTNode implements ILocateable
}
}
}
if (extClass.isExternal() && ! myClass.isExternal()) {
classRef.getLocation().reportSemanticError(EXTERNALEXTEND);
}
checkAbstractOverride(timestamp, extClass, myClass);
}
}
......
......@@ -62,6 +62,7 @@ public final class Class_Type extends Type implements ITypeWithComponents {
private final boolean isAbstract;
private final boolean isFinal;
private final boolean isTrait;
private final boolean isExternal;
private final Location modifierLocation;
private final StatementBlock finallyBlock;
private final Reference runsOnRef;
......@@ -72,13 +73,15 @@ public final class Class_Type extends Type implements ITypeWithComponents {
private Component_Type mtcType;
private Component_Type systemType;
public Class_Type(ClassTypeBody classBody, boolean isAbstract, boolean isFinal, boolean isTrait, Location modifierLocation,
final Reference runsOnRef, final Reference mtcRef, final Reference systemRef, StatementBlock finallyBlock) {
public Class_Type(ClassTypeBody classBody, boolean isAbstract, boolean isFinal, boolean isTrait, boolean isExternal,
Location modifierLocation, final Reference runsOnRef, final Reference mtcRef, final Reference systemRef,
StatementBlock finallyBlock) {
this.classBody = classBody;
this.isAbstract = isAbstract;
this.isFinal = isFinal;
this.isTrait = isTrait;
this.isExternal = isExternal;
this.modifierLocation = modifierLocation;
this.finallyBlock = finallyBlock;
this.runsOnRef = runsOnRef;
......@@ -105,7 +108,7 @@ public final class Class_Type extends Type implements ITypeWithComponents {
}
public Class_Type() {
this(null, true, false, false, null, null, null, null, null);
this(null, true, false, false, false, null, null, null, null, null);
}
@Override
......@@ -291,6 +294,14 @@ public final class Class_Type extends Type implements ITypeWithComponents {
return classBody.hasExtendsReferences();
}
/**
* Checks if the class is declared as external
* @return
*/
public boolean isExternal() {
return isExternal;
}
/**
* Checks if the class is declared using the '@trait' modifier
* @return
......
......@@ -9006,9 +9006,10 @@ pr_ClassTypeDef returns[Def_Type def_type]
boolean isAbstract = false;
boolean isFinal = false;
boolean isTrait = false;
boolean isExternal = false;
StatementBlock finallyBlock = null;
}:
( ( ext = pr_ExtKeyword )?
( ( ext = pr_ExtKeyword { isExternal = true; } )?
kw = pr_ClassKeyword
( fm = pr_FinalModifier { isFinal = $fm.isFinal; } )?
( am = pr_AbstractModifier { isAbstract = $am.isAbstract; } )?
......@@ -9042,7 +9043,7 @@ pr_ClassTypeDef returns[Def_Type def_type]
if (body == null) {
body = new ClassTypeBody($i.identifier, refs);
}
Class_Type type = new Class_Type(body, isAbstract, isFinal, isTrait, getLocation($kw.stop, $i.start), runsonHelper.runsonReference, mtcHelper.mtcReference, systemspecHelper.systemReference, finallyBlock);
Class_Type type = new Class_Type(body, isAbstract, isFinal, isTrait, isExternal, getLocation($kw.stop, $i.start), runsonHelper.runsonReference, mtcHelper.mtcReference, systemspecHelper.systemReference, finallyBlock);
type.setLocation(getLocation($start, getLastVisibleToken()));
$def_type = new Def_Type($i.identifier, type);
$def_type.setLocation(getLocation($kw.start, $i.stop));
......
......@@ -164,7 +164,7 @@ public class OOP_Semantic_tests {
private ArrayList<MarkerToCheck> oopNegative_ttcn_initializer() {
//oopNegativeSemanticTest.ttcn
ArrayList<MarkerToCheck> markersToCheck = new ArrayList<MarkerToCheck>(81);
ArrayList<MarkerToCheck> markersToCheck = new ArrayList<MarkerToCheck>(82);
int lineNum = 32;
markersToCheck.add(new MarkerToCheck("class type expected", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 10;
......@@ -181,7 +181,9 @@ public class OOP_Semantic_tests {
markersToCheck.add(new MarkerToCheck("A class can only extend one non-trait class", lineNum, IMarker.SEVERITY_ERROR));
markersToCheck.add(new MarkerToCheck("Duplicate reference to class `MinimalClass' was declared here again", lineNum, IMarker.SEVERITY_ERROR));
markersToCheck.add(new MarkerToCheck("Duplicate reference to class `MinimalClass' was first declared here", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 7;
lineNum += 9;
markersToCheck.add(new MarkerToCheck("An external class cannot be extended by a non-external class", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 5;
markersToCheck.add(new MarkerToCheck("Class `@classesNegativeSemantic.RunsonClass3' is not runs on compatible with parent `@classesNegativeSemantic.RunsonClass1'", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 5;
markersToCheck.add(new MarkerToCheck("Class `@classesNegativeSemantic.MtcClass3' is not mtc compatible with parent `@classesNegativeSemantic.MtcClass1'", lineNum, IMarker.SEVERITY_ERROR));
......
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