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

OOP: sematic check - overridden method return type


Signed-off-by: Miklos Magyari's avatarMiklos Magyari <miklos.magyari@sigmatechnology.se>
parent 2329d438
......@@ -304,8 +304,8 @@ type class ClassWithPrivate {
return 1;
}
function f_override2(in float pl_float) return integer {
return 1;
function f_override2(in float pl_float) return charstring {
return "xyz";
}
public function f_override3(in float pl_float) return integer {
......@@ -319,6 +319,10 @@ type class ClassWithPrivate {
function f_override5() {
}
function f_override6(in float pl_float) return octetstring {
return 'AB'O;
}
}
type class ClassOverride1 {
......@@ -340,13 +344,17 @@ type class ClassWithPrivateExt extends ClassWithPrivate {
return pl_float;
}
public function f_override3(charstring pl_float) return charstring {
return pl_float;
public function f_override3(charstring pl_float) return integer {
return 42;
}
function f_override4() { }
private function f_override5() { }
public function f_override6(in float pl_float) return hexstring {
return 'AB'H;
}
}
// function with class parameter
......
......@@ -272,14 +272,14 @@ type class BaseFunctionClass {
}
type class FuncClass extends BaseFunctionClass {
public function f_get_one() return charstring {
return "xyz";
public function f_get_one() return integer {
return 2;
}
private function f_test_super() {
// type mismatches
var integer vl_int := super.f_get_one();
var charstring vl_cs:= f_get_one();
var integer vl_int2:= f_get_one();
}
// class as a function parameter
......@@ -430,7 +430,7 @@ testcase tc_basicSyntax() runs on CT {
// constructor call without parameters
var MinimalClass vl_minimalClass := MinimalClass.create;
// constructor call with empty parameter list
var MinimalClass vl_minimalClass2 := MinimalClass.create();
var MinimalClass vl_minimalClass2 := MinimalClass.create();
var ClassWithThis vl_thisClass := ClassWithThis.create(12, 13.0);
var VariousMembers vl_various := VariousMembers.create("abc", "def");
......
......@@ -28,6 +28,8 @@ import org.eclipse.titan.designer.AST.Location;
import org.eclipse.titan.designer.AST.Reference;
import org.eclipse.titan.designer.AST.ReferenceFinder;
import org.eclipse.titan.designer.AST.Scope;
import org.eclipse.titan.designer.AST.IType;
import org.eclipse.titan.designer.AST.IType.Type_type;
import org.eclipse.titan.designer.AST.ReferenceFinder.Hit;
import org.eclipse.titan.designer.AST.TTCN3.IIncrementallyUpdateable;
import org.eclipse.titan.designer.AST.TTCN3.TTCN3Scope;
......@@ -57,6 +59,8 @@ public final class ClassTypeBody extends TTCN3Scope implements IReferenceChainEl
public static final String OVERRIDDENFORMALPARAM = "Definition is overridden with different formal parameters";
public static final String PUBLICOVERRIDEPUBLIC = "Public method can only be overriden by a public method";
public static final String PROTECTEDOVERRIDE = "Protected method can only be overriden by a public or protected method";
public static final String RETURNTYPEMISMATCH = "Return type differs from the overridden method's return type";
public static final String OVERRIDDENRETURNTYPE = "Method is overridden with a different return type";
public static final String VISIBILITYPRIVATEPROTECTED = "Class field visibility must be private or protected";
public static final String TRAITMETHODSONLY = "Trait classes can only declare methods";
public static final String TRAITMETHODHASBODY = "Trait method cannot have a function body";
......@@ -269,6 +273,14 @@ public final class ClassTypeBody extends TTCN3Scope implements IReferenceChainEl
if (modifier == VisibilityModifier.Public || modifier == VisibilityModifier.Protected) {
if (definition instanceof Def_Function && localDefinition instanceof Def_Function ) {
if (! isConstructor(definition)) {
final IType returnType = definition.getType(timestamp);
final IType localReturnType = localDefinition.getType(timestamp);
final Type_type type = returnType != null ? returnType.getTypetypeTtcn3() : null;
final Type_type localType = localReturnType != null ? localReturnType.getTypetypeTtcn3() : null;
if (type != localType) {
localDefinition.getType(timestamp).getLocation().reportSemanticError(RETURNTYPEMISMATCH);
definition.getType(timestamp).getLocation().reportSemanticError(OVERRIDDENRETURNTYPE);
}
if (! ((Def_Function)definition).getFormalParameterList().isSame(timestamp, ((Def_Function)localDefinition).getFormalParameterList())) {
localDefinition.getIdentifier().getLocation().reportSemanticError(FORMALPARAMSDIFFER);
definition.getIdentifier().getLocation().reportSemanticError(OVERRIDDENFORMALPARAM);
......
......@@ -64,6 +64,10 @@ public final class Class_Type extends Type implements ITypeWithComponents {
private static final String UNKNOWNFIELD = "Unknown field reference";
private static final String PRIVATEINACCESSIBLE = "Private member is inaccessible due to its protection level";
/**
* The superclass of this class
* (the only non-trait class that this class extends)
**/
private Class_Type superClass = null;
private final ClassTypeBody classBody;
......@@ -243,12 +247,14 @@ public final class Class_Type extends Type implements ITypeWithComponents {
if (refs != null) {
for (Reference ref : refs.getReferenceList()) {
final Assignment ass = ref.getRefdAssignment(timestamp, false);
final IType type = ass.getType(timestamp);
if (type instanceof Class_Type) {
Class_Type parent = (Class_Type)type;
if (parent.isTrait == false) {
superClass = parent;
final Assignment assignment = ref.getRefdAssignment(timestamp, false);
if (assignment != null) {
final IType type = assignment.getType(timestamp);
if (type instanceof Class_Type) {
final Class_Type parent = (Class_Type)type;
if (parent.isTrait == false) {
superClass = parent;
}
}
}
}
......@@ -344,19 +350,19 @@ public final class Class_Type extends Type implements ITypeWithComponents {
(Type)def.getType(timestamp), new Identifier(Identifier_type.ID_TTCN, name),
instance, null);
fpList.add(fp);
Reference refLeft = new Reference(new Identifier(Identifier_type.ID_TTCN, def.getIdentifier().getName()), Ref_Type.REF_THIS);
FieldSubReference subref = new FieldSubReference(def.getIdentifier());
final Reference refLeft = new Reference(new Identifier(Identifier_type.ID_TTCN, def.getIdentifier().getName()), Ref_Type.REF_THIS);
final FieldSubReference subref = new FieldSubReference(def.getIdentifier());
refLeft.addSubReference(subref);
Reference refRight = new Reference(new Identifier(Identifier_type.ID_TTCN, def.getIdentifier().getName()));
Referenced_Value refdVal = new Referenced_Value(refRight);
SpecificValue_Template valTemplate = new SpecificValue_Template(refdVal);
Assignment_Statement assignment = new Assignment_Statement(refLeft, valTemplate);
final Reference refRight = new Reference(new Identifier(Identifier_type.ID_TTCN, def.getIdentifier().getName()));
final Referenced_Value refdVal = new Referenced_Value(refRight);
final SpecificValue_Template valTemplate = new SpecificValue_Template(refdVal);
final Assignment_Statement assignment = new Assignment_Statement(refLeft, valTemplate);
sb.addStatement(assignment);
}
}
FormalParameterList pl = null;
if (superClass != null) {
FormalParameterList parentFpList = superClass.getConstructorFormalParameterList();
final FormalParameterList parentFpList = superClass.getConstructorFormalParameterList();
if (parentFpList != null) {
pl = new FormalParameterList(parentFpList);
pl.addFormalParameterList(new FormalParameterList(fpList));
......@@ -365,7 +371,7 @@ public final class Class_Type extends Type implements ITypeWithComponents {
if (pl == null) {
pl = new FormalParameterList(fpList);
}
Def_Function constructor = new Def_Function(new Identifier(Identifier_type.ID_TTCN, "create"), pl, null);
final Def_Function constructor = new Def_Function(new Identifier(Identifier_type.ID_TTCN, "create"), pl, null);
constructor.setLocation(NULL_Location.INSTANCE);
classBody.addDefinition(constructor);
}
......
......@@ -179,7 +179,7 @@ public class OOP_Semantic_tests {
private ArrayList<MarkerToCheck> oopNegative_ttcn_initializer() {
//oopNegativeSemanticTest.ttcn
ArrayList<MarkerToCheck> markersToCheck = new ArrayList<MarkerToCheck>(96);
ArrayList<MarkerToCheck> markersToCheck = new ArrayList<MarkerToCheck>(100);
int lineNum = 33;
markersToCheck.add(new MarkerToCheck("class type expected", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 10;
......@@ -236,7 +236,9 @@ public class OOP_Semantic_tests {
markersToCheck.add(new MarkerToCheck("Reference to non-existent field `nonexist' in union template for type `@classesNegativeSemantic.MyUnion'", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 4;
markersToCheck.add(new MarkerToCheck("A field of any visibility cannot be overriden by a subclass", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 11;
lineNum += 4;
markersToCheck.add(new MarkerToCheck("Method is overridden with a different return type", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 7;
for (i = 0; i < 2; i++) {
markersToCheck.add(new MarkerToCheck("All formal parameters of a constructor shall be `in` parameters", lineNum, IMarker.SEVERITY_ERROR));
}
......@@ -280,13 +282,17 @@ public class OOP_Semantic_tests {
markersToCheck.add(new MarkerToCheck("A class can only be cast to a superclass or subclass", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 5;
markersToCheck.add(new MarkerToCheck("`super' reference is only valid inside class bodies", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 10;
lineNum += 4;
markersToCheck.add(new MarkerToCheck("Return type differs from the overridden method's return type", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 6;
markersToCheck.add(new MarkerToCheck("Type mismatch: a value of type `integer' was expected instead of `charstring'", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 2;
markersToCheck.add(new MarkerToCheck("Type mismatch: a value of type `charstring' was expected instead of `integer'", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 19;
markersToCheck.add(new MarkerToCheck("Definition is overridden with different formal parameters", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 19;
lineNum += 12;
markersToCheck.add(new MarkerToCheck("Method is overridden with a different return type", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 11;
for (i = 0; i < 2; i++) {
markersToCheck.add(new MarkerToCheck("A field of any visibility cannot be overriden by a subclass", lineNum++, IMarker.SEVERITY_ERROR));
}
......@@ -298,7 +304,9 @@ public class OOP_Semantic_tests {
markersToCheck.add(new MarkerToCheck("Public method can only be overriden by a public method", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 2;
markersToCheck.add(new MarkerToCheck("Protected method can only be overriden by a public or protected method", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 5;
lineNum += 2;
markersToCheck.add(new MarkerToCheck("Return type differs from the overridden method's return type", 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 += 6;
markersToCheck.add(new MarkerToCheck("Class functions cannot have a `runs on` clause", 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