diff --git a/Semantic_Analizer_Tests/src/Basic_tests/OopNegativeSemanticTest.ttcn b/Semantic_Analizer_Tests/src/Basic_tests/OopNegativeSemanticTest.ttcn index 1d0bb8fe6111ac83a521388db6669ddbcebc6db1..3aee4bc6e5f9c9c6a114e61a9b0e4cdc7edd0dc2 100755 --- a/Semantic_Analizer_Tests/src/Basic_tests/OopNegativeSemanticTest.ttcn +++ b/Semantic_Analizer_Tests/src/Basic_tests/OopNegativeSemanticTest.ttcn @@ -62,6 +62,16 @@ type class OuterClass { class InnerClass { private template MyUnion t_union; public var integer badInteger := "xyz"; + + public class EvenDeeper { + public const charstring chr := "abc"; + + public class Core { + public function f_inside(in integer pl_int) return charstring { + return this.chr; + } + } + } } } } @@ -163,6 +173,9 @@ testcase tc_basicSyntax() runs on CT { var integer vl_integer := vl_outer of OuterClass; // type mismatch var boolean vl_boolean := vl_outer of BaseFunctionClass; // semanticall correct + + // nested class member reference + var octetstring vl_octet := vl_outer.NestedClass.InnerClass.EvenDeeper.Core.f_inside(1) } } \ No newline at end of file diff --git a/Semantic_Analizer_Tests/src/Basic_tests/OopPositiveBasicSyntax.ttcn b/Semantic_Analizer_Tests/src/Basic_tests/OopPositiveBasicSyntax.ttcn index dc2f7367dce94d1ce7cfdc599ba8d556ba2e4e3b..9a922691c5f51b2e1d5e91490271b435bc8451cc 100644 --- a/Semantic_Analizer_Tests/src/Basic_tests/OopPositiveBasicSyntax.ttcn +++ b/Semantic_Analizer_Tests/src/Basic_tests/OopPositiveBasicSyntax.ttcn @@ -113,6 +113,14 @@ type class OuterClass { class DeeplyNested { const integer m_const := 0; + class EvenDeeper { + const charstring m_str := "abc"; + public class Core { + function f_inside(in integer pl_int) return float { + return 0.1; + } + } + } } } } @@ -230,6 +238,9 @@ testcase tc_basicSyntax() runs on CT { if (vl_outerClass of OuterClass) { vl_outerClass.m_string := "xyz"; } + +// nested class member reference + var float vl_float := vl_outerClass.NestedClass.DeeplyNested.EvenDeeper.Core.f_inside(1); } control { diff --git a/org.eclipse.titan.designer/src/org/eclipse/titan/designer/AST/TTCN3/statements/Unknown_Instance_Statement.java b/org.eclipse.titan.designer/src/org/eclipse/titan/designer/AST/TTCN3/statements/Unknown_Instance_Statement.java index 3a986acf1a2fc4fd718791d57c4f2460aca5a4f3..a17e6b9c8a2869f97f7b32d95aae88974977d06f 100644 --- a/org.eclipse.titan.designer/src/org/eclipse/titan/designer/AST/TTCN3/statements/Unknown_Instance_Statement.java +++ b/org.eclipse.titan.designer/src/org/eclipse/titan/designer/AST/TTCN3/statements/Unknown_Instance_Statement.java @@ -153,6 +153,7 @@ public final class Unknown_Instance_Statement extends Statement { realStatement.check(timestamp); break; case A_VAR: + case A_PAR_VAL: Assignment refdAssignment = reference.getRefdAssignment(timestamp, false); IType assignmentType = refdAssignment.getType(timestamp); IType refdType = assignmentType.getTypeRefdLast(timestamp); diff --git a/org.eclipse.titan.designer/src/org/eclipse/titan/designer/AST/TTCN3/types/Class_Type.java b/org.eclipse.titan.designer/src/org/eclipse/titan/designer/AST/TTCN3/types/Class_Type.java index 732503652e1977223708897f77a3c9ead98b329c..d82b1e7006f1f5f10f93e4b18c8a6add6a745a68 100755 --- a/org.eclipse.titan.designer/src/org/eclipse/titan/designer/AST/TTCN3/types/Class_Type.java +++ b/org.eclipse.titan.designer/src/org/eclipse/titan/designer/AST/TTCN3/types/Class_Type.java @@ -55,6 +55,7 @@ public final class Class_Type extends Type implements ITypeWithComponents { private static final String TRAITCANNOTBEFINAL = "A trait class cannot be final"; private static final String ABSTRACTCANNOTBETRAIT = "A class cannot be both abstract and trait"; private static final String TRAITWITHFINALLY = "A trait class should not define a finally block"; + private static final String UNKNOWNFIELD = "Unknown field reference"; private final ClassTypeBody classBody; @@ -141,10 +142,12 @@ public final class Class_Type extends Type implements ITypeWithComponents { } Assignment assignment = classBody.getAssByIdentifier(timestamp, subreference.getId()); - if (assignment == null) + if (assignment == null) { + subreference.getLocation().reportSemanticError(UNKNOWNFIELD); return null; + } - if (subreferences.size() < 3) { + if (subreferences.size() == actualSubReference + 1) { return assignment.getType(timestamp); } diff --git a/org.eclipse.titan.designer/src/org/eclipse/titan/designer/parsers/ttcn3parser/Ttcn3Parser.g4 b/org.eclipse.titan.designer/src/org/eclipse/titan/designer/parsers/ttcn3parser/Ttcn3Parser.g4 index ff1971d7e989cc2aa30657b61227d8f0fb4e5e8d..e67fdfaca9a6a936025a79c5486b0586fd931eda 100644 --- a/org.eclipse.titan.designer/src/org/eclipse/titan/designer/parsers/ttcn3parser/Ttcn3Parser.g4 +++ b/org.eclipse.titan.designer/src/org/eclipse/titan/designer/parsers/ttcn3parser/Ttcn3Parser.g4 @@ -7900,9 +7900,22 @@ pr_Primary returns[Value value] pr_ExtendedFieldReference returns[List subReferences] @init { $subReferences = new ArrayList(); + ParsedActualParameters parameters = null; }: ( a = pr_Dot - ( structFieldId = pr_Identifier + ( funcid = pr_Identifier + LPAREN + ( par = pr_FunctionActualParList { + parameters = $par.parsedParameters; + parameters.setLocation( getLocation( $par.start, $par.stop ) ); + } )? + RPAREN + { + ParameterisedSubReference funcReference = new ParameterisedSubReference($funcid.identifier, parameters); + funcReference.setLocation( getLocation( $funcid.start, $par.stop ) ); + $subReferences.add(funcReference); + } + | structFieldId = pr_Identifier { FieldSubReference tempReference = new FieldSubReference($structFieldId.identifier); tempReference.setLocation(getLocation( $structFieldId.start, $structFieldId.stop)); $subReferences.add(tempReference); @@ -9189,7 +9202,7 @@ pr_ClassFunctionDef returns[Def_Function def_func] ( sb=pr_StatementBlock { statementBlock = $sb.statementblock; })? ) { - if($id.identifier != null && statementBlock != null) { + if($id.identifier != null) { if(parameters == null) { parameters = new FormalParameterList(new ArrayList()); } 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); diff --git a/org.eclipse.titan.regressiontests/src/org/eclipse/titan/regressiontests/designer/statictests/Basic_tests/OOP_Semantic_tests.java b/org.eclipse.titan.regressiontests/src/org/eclipse/titan/regressiontests/designer/statictests/Basic_tests/OOP_Semantic_tests.java index 20c2a98b0f50fbd22e859a048f4963298b46b452..56be6306be4b0c8094ecee5da9c7182b7c912b98 100755 --- a/org.eclipse.titan.regressiontests/src/org/eclipse/titan/regressiontests/designer/statictests/Basic_tests/OOP_Semantic_tests.java +++ b/org.eclipse.titan.regressiontests/src/org/eclipse/titan/regressiontests/designer/statictests/Basic_tests/OOP_Semantic_tests.java @@ -45,7 +45,7 @@ public class OOP_Semantic_tests { private ArrayList oopNegative_ttcn_initializer() { //oopNegativeSemanticTest.ttcn - ArrayList markersToCheck = new ArrayList(16); + ArrayList markersToCheck = new ArrayList(18); int lineNum = 28; markersToCheck.add(new MarkerToCheck("class type expected", lineNum, IMarker.SEVERITY_ERROR)); lineNum += 15; @@ -54,7 +54,7 @@ public class OOP_Semantic_tests { markersToCheck.add(new MarkerToCheck("Local Definiton `vl_b' collides with definition inherited from class type `@classesNegativeSemantic.SubClass'", lineNum, IMarker.SEVERITY_ERROR)); lineNum += 17; markersToCheck.add(new MarkerToCheck("integer value was expected", lineNum, IMarker.SEVERITY_ERROR)); - lineNum += 11; + lineNum += 21; markersToCheck.add(new MarkerToCheck("integer value was expected", lineNum, IMarker.SEVERITY_ERROR)); lineNum += 4; markersToCheck.add(new MarkerToCheck("Constant must be initialized", lineNum, IMarker.SEVERITY_ERROR)); @@ -71,10 +71,13 @@ public class OOP_Semantic_tests { lineNum += 10; markersToCheck.add(new MarkerToCheck("Type mismatch: a value of type `integer' was expected instead of `charstring'", 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 += 12; - markersToCheck.add(new MarkerToCheck("Type mismatch: a value of type `charstring' was expected instead of `integer'", lineNum, IMarker.SEVERITY_ERROR)); + lineNum += 11; + 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; markersToCheck.add(new MarkerToCheck("integer value was expected", lineNum, IMarker.SEVERITY_ERROR)); + lineNum += 4; + markersToCheck.add(new MarkerToCheck("Type mismatch: a value of type `octetstring' was expected instead of `charstring'", lineNum, IMarker.SEVERITY_ERROR)); return markersToCheck;