Commit d83be96f authored by Miklos Magyari's avatar Miklos Magyari
Browse files

OOP: semantic check - mtc and system compatibility (issue #427)


Signed-off-by: Miklos Magyari's avatarMiklos Magyari <miklos.magyari@sigmatechnology.se>
parent e2f49d74
......@@ -60,6 +60,16 @@ type class RunsonClass1 runs on CT { }
type class RunsonClass2 extends RunsonClass1 runs on CT { }
type class RunsonClass3 extends RunsonClass1 runs on CT2 { }
// mtc compatibility
type class MtcClass1 mtc CT { }
type class MtcClass2 extends MtcClass1 mtc CT { }
type class MtcClass3 extends MtcClass1 mtc CT2 { }
// system compatibility
type class SystemClass1 system CT { }
type class SystemClass2 extends SystemClass1 system CT2 { }
type class SystemClass3 extends SystemClass1 system CT { }
// self extend
type class @trait TC {}
type class AA extends DD, TC, DD { }
......
......@@ -140,6 +140,14 @@ type class ConstructorOverrideSub {
type class RunsonClass1 runs on CT { }
type class RunsonClass2 extends RunsonClass1 runs on CT { }
// mtc compatibility
type class MtcClass1 mtc CT { }
type class MtcClass2 extends MtcClass1 mtc CT { }
// system compatibility
type class SystemClass1 system CT { }
type class SystemClass2 extends SystemClass1 system CT { }
// nested classes
type class OuterClass {
private var integer m_int := 0;
......
/*****************************************************************
** @author STF 572
** @version 0.0.1
** @purpose 5.1.1.0, Ensure that The mtc and system type of a class shall be mtc and system compatible with the mtc and system types of the superclass, respectively.
** @verdict pass reject
**
** modified by Miklos Magyari
*****************************************************************/
module NegSem_50101_top_level_011 "TTCN-3:2018 Object-Oriented" {
type component GeneralComp {
}
type port Myport message {
inout octetstring;
}
type component MessageComp {
port Myport p1_PT;
}
public type class t_superclass_with_incompatible_system system GeneralComp {
var hexstring v_h := '1100FAD'H;
}
public type class t_subclass_system extends t_superclass_with_incompatible_system system MessageComp { // not allowed
}
public type class t_superclass_with_incompatible_mtc mtc GeneralComp {
var integer v_i := 9919;
}
public type class t_subclass_mtc extends t_superclass_with_incompatible_mtc mtc MessageComp { // not allowed
}
testcase tc_NegSem_50101_top_level_011_01() runs on MessageComp system GeneralComp {
var t_subclass_system vl_a := t_subclass_system.create(); // not allowed
if (vl_a.v_h == '1100FAD'H) {
setverdict(pass);
} else {
setverdict(fail);
}
}
testcase tc_NegSem_50101_top_level_011_02() runs on MessageComp {
var t_subclass_mtc vl_a := t_subclass_mtc.create(); // not allowed
if (vl_a.v_i == 9919) {
setverdict(pass);
} else {
setverdict(fail);
}
}
control {
execute(tc_NegSem_50101_top_level_011_01());
execute(tc_NegSem_50101_top_level_011_02());
}
}
\ No newline at end of file
......@@ -26,7 +26,6 @@ import org.eclipse.titan.designer.AST.TTCN3.IIncrementallyUpdateable;
import org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Function;
import org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Type;
import org.eclipse.titan.designer.AST.TTCN3.definitions.Definition;
import org.eclipse.titan.designer.AST.TTCN3.definitions.RunsOnScope;
import org.eclipse.titan.designer.parsers.CompilationTimeStamp;
import org.eclipse.titan.designer.parsers.ttcn3parser.ReParseException;
import org.eclipse.titan.designer.parsers.ttcn3parser.TTCN3ReparseUpdater;
......@@ -43,6 +42,8 @@ public final class ClassTypeReferenceList extends ASTNode implements ILocateable
private final String CLASSCANNOTEXTENDITSELF = "A class cannot extend itself neither directly nor indirectly";
private final String ABSTRACTMETHODUNIMPLEMENTED = "Class must implement abstract method `{0}'' inherited from class `{1}''";
private final String INCOMPATIBLERUNSON = "Class `{0}'' is not 'runs on' compatible with parent `{1}''";
private final String INCOMPATIBLEMTC= "Class `{0}'' is not 'mtc' compatible with parent `{1}''";
private final String INCOMPATIBLESYSTEM = "Class `{0}'' is not 'system' compatible with parent `{1}''";
private Class_Type myClass;
......@@ -103,11 +104,25 @@ public final class ClassTypeReferenceList extends ASTNode implements ILocateable
final Component_Type extRunsOnType = extClass.getRunsOnType(timestamp);
final Component_Type myRunsOnType = myClass.getRunsOnType(timestamp);
if (myRunsOnType != null && !extRunsOnType.isCompatible(timestamp, myRunsOnType, null, null, null)) {
if (myRunsOnType != null && !myRunsOnType.isCompatible(timestamp, extRunsOnType, null, null, null)) {
myClass.getRunsOnRef().getLocation().reportSemanticError(
MessageFormat.format(INCOMPATIBLERUNSON, myClass.getFullName(), extClass.getFullName()));
}
final Component_Type extMtcType = extClass.getMtcType(timestamp);
final Component_Type myMtcType = myClass.getMtcType(timestamp);
if (myMtcType != null && !myMtcType.isCompatible(timestamp, extMtcType, null, null, null)) {
myClass.getMtcRef().getLocation().reportSemanticError(
MessageFormat.format(INCOMPATIBLEMTC, myClass.getFullName(), extClass.getFullName()));
}
final Component_Type extSystemType = extClass.getSystemType(timestamp);
final Component_Type mySystemType = myClass.getSystemType(timestamp);
if (mySystemType != null && !mySystemType.isCompatible(timestamp, extSystemType, null, null, null)) {
myClass.getSystemRef().getLocation().reportSemanticError(
MessageFormat.format(INCOMPATIBLESYSTEM, myClass.getFullName(), extClass.getFullName()));
}
if (extClass == myClass) {
classRef.getLocation().reportSemanticError(CLASSCANNOTEXTENDITSELF);
}
......
......@@ -69,6 +69,8 @@ public final class Class_Type extends Type implements ITypeWithComponents {
private final Reference systemRef;
private Component_Type runsOnType;
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) {
......@@ -90,6 +92,12 @@ public final class Class_Type extends Type implements ITypeWithComponents {
if (runsOnRef != null) {
runsOnRef.setFullNameParent(this);
}
if (mtcRef != null) {
mtcRef.setFullNameParent(this);
}
if (systemRef != null) {
systemRef.setFullNameParent(this);
}
if (finallyBlock != null) {
finallyBlock.setFullNameParent(this);
finallyBlock.setOwnerIsDestructor();
......@@ -131,6 +139,12 @@ public final class Class_Type extends Type implements ITypeWithComponents {
if (runsOnRef != null) {
runsOnRef.setMyScope(scope);
}
if (mtcRef != null) {
mtcRef.setMyScope(scope);
}
if (systemRef != null) {
systemRef.setMyScope(scope);
}
}
@Override
......@@ -192,6 +206,14 @@ public final class Class_Type extends Type implements ITypeWithComponents {
return runsOnRef;
}
public Reference getMtcRef() {
return mtcRef;
}
public Reference getSystemRef() {
return systemRef;
}
@Override
/** {@inheritDoc} */
public void check(final CompilationTimeStamp timestamp) {
......@@ -200,9 +222,17 @@ public final class Class_Type extends Type implements ITypeWithComponents {
}
runsOnType = null;
mtcType = null;
systemType = null;
if (runsOnRef != null) {
runsOnType = runsOnRef.chkComponentypeReference(timestamp);
}
if (mtcRef != null) {
mtcType = mtcRef.chkComponentypeReference(timestamp);
}
if (systemRef != null) {
systemType = systemRef.chkComponentypeReference(timestamp);
}
if (isAbstract && isFinal) {
modifierLocation.reportSemanticError(ABSTRACTCANNOTBEFINAL);
......@@ -290,6 +320,16 @@ public final class Class_Type extends Type implements ITypeWithComponents {
return runsOnType;
}
public Component_Type getMtcType(final CompilationTimeStamp timestamp) {
check(timestamp);
return mtcType;
}
public Component_Type getSystemType(final CompilationTimeStamp timestamp) {
check(timestamp);
return systemType;
}
@Override
public Identifier getComponentIdentifierByName(Identifier identifier) {
// TODO Auto-generated method stub
......
......@@ -56,6 +56,9 @@ public class OOP_Semantic_tests {
Designer_plugin_tests.checkSemanticMarkersOnFile(NegSem_50101_top_level_010_ttcn_initializer(),
OOP_Syntax_tests.OOP_DIR_PATH + "negative/NegSem_50101_top_level_010.ttcn");
Designer_plugin_tests.checkSemanticMarkersOnFile(NegSem_50101_top_level_011_ttcn_initializer(),
OOP_Syntax_tests.OOP_DIR_PATH + "negative/NegSem_50101_top_level_011.ttcn");
Designer_plugin_tests.checkSemanticMarkersOnFile(NegSem_5010102_abstractClasses_001_ttcn_initializer(),
OOP_Syntax_tests.OOP_DIR_PATH + "negative/NegSem_5010102_abstractClasses_001.ttcn");
......@@ -109,6 +112,17 @@ public class OOP_Semantic_tests {
return markersToCheck;
}
private ArrayList<MarkerToCheck> NegSem_50101_top_level_011_ttcn_initializer() {
//NegSem_50101_top_level_011.ttcn
ArrayList<MarkerToCheck> markersToCheck = new ArrayList<MarkerToCheck>(2);
int lineNum = 26;
markersToCheck.add(new MarkerToCheck("Class `@NegSem_50101_top_level_011.t_subclass_system' is not system compatible with parent `@NegSem_50101_top_level_011.t_superclass_with_incompatible_system'", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 8;
markersToCheck.add(new MarkerToCheck("Class `@NegSem_50101_top_level_011.t_subclass_mtc' is not mtc compatible with parent `@NegSem_50101_top_level_011.t_superclass_with_incompatible_mtc'", lineNum, IMarker.SEVERITY_ERROR));
return markersToCheck;
}
private ArrayList<MarkerToCheck> NegSem_5010102_abstractClasses_001_ttcn_initializer() {
//NegSem_5010102_abstractClasses_001.ttcn
ArrayList<MarkerToCheck> markersToCheck = new ArrayList<MarkerToCheck>(1);
......@@ -138,7 +152,7 @@ public class OOP_Semantic_tests {
private ArrayList<MarkerToCheck> oopNegative_ttcn_initializer() {
//oopNegativeSemanticTest.ttcn
ArrayList<MarkerToCheck> markersToCheck = new ArrayList<MarkerToCheck>(75);
ArrayList<MarkerToCheck> markersToCheck = new ArrayList<MarkerToCheck>(77);
int lineNum = 32;
markersToCheck.add(new MarkerToCheck("class type expected", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 10;
......@@ -157,7 +171,11 @@ public class OOP_Semantic_tests {
markersToCheck.add(new MarkerToCheck("Duplicate reference to class `MinimalClass' was first declared here", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 7;
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));
lineNum += 4;
markersToCheck.add(new MarkerToCheck("Class `@classesNegativeSemantic.SystemClass2' is not system compatible with parent `@classesNegativeSemantic.SystemClass1'", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 5;
markersToCheck.add(new MarkerToCheck("A class cannot extend itself neither directly nor indirectly", lineNum, IMarker.SEVERITY_ERROR));
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 `DD' was declared here again", lineNum, IMarker.SEVERITY_ERROR));
......
......@@ -45,6 +45,7 @@ public class OOP_Syntax_tests {
"NegSem_50101_top_level_007.ttcn",
"NegSem_50101_top_level_008.ttcn",
"NegSem_50101_top_level_010.ttcn",
"NegSem_50101_top_level_011.ttcn",
"NegSem_5010102_abstractClasses_001.ttcn",
"NegSem_5010109_Visibility_001.ttcn",
"NegSem_5010109_Visibility_004.ttcn"
......
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