Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2018-08-26 08:29:44 +0000
committerStephan Herrmann2018-08-26 08:29:44 +0000
commitb8c129fe8b89a7c02820ac64e0611d79ef5804f3 (patch)
tree82b02bf38bab878a8543a8b4f22ce8a547314d68
parent9a1b554e53fec4ddb69125715d153336f5eb7e0f (diff)
downloadorg.eclipse.objectteams-b8c129fe8b89a7c02820ac64e0611d79ef5804f3.tar.gz
org.eclipse.objectteams-b8c129fe8b89a7c02820ac64e0611d79ef5804f3.tar.xz
org.eclipse.objectteams-b8c129fe8b89a7c02820ac64e0611d79ef5804f3.zip
Bug 528057 - [9] Need to signal when tsuper() ctor call is needed to
initialize fields
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java1
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java29
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java7
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/core/compiler/IOTConstants.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lifting/Lifting.java11
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/RoleModel.java12
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/CopyInheritance.java10
-rw-r--r--testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/callinbinding/CallinMethodBinding.java2
-rw-r--r--testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/regression/DevelopmentExamples.java6
-rw-r--r--testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/rolesandteams/ImplicitInheritance.java263
12 files changed, 338 insertions, 16 deletions
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
index 1183ecda5..0c8fd21a8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -2179,6 +2179,7 @@ void setSourceStart(int sourceStart);
int FieldInRoleWithInstantiationPolicy = ROLE_RELATED + 3105; // 2.3.1(d)
/** @since 3.7 (OT 2.0) */
int MissingEqualsHashCodeWithInstantation = ROLE_RELATED + 3106; // 2.3.1(d)
+ int RoleConstructorNeedingTSuperCall = ROLE_RELATED + 3107; // FIXME
int DeclaredLiftingInStaticMethod = ROLE_RELATED + 3201; // 2.3.2(a)
int QualifiedLiftingType = ROLE_RELATED + 3202; // 2.3.2(a)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
index 3a048cf14..58f54af34 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
@@ -160,7 +160,7 @@ public void analyseCode(ClassScope classScope, InitializationFlowContext initial
if (calledHere || calledIndirectly)
this.scope.problemReporter().baseConstructorCallInLiftingConstructor(this);
} else {
- if (!calledHere && !calledIndirectly) {
+ if (!calledHere && !calledIndirectly && !Lifting.isLiftingCtor(selfCall)) {
if (!(isDefaultConstructor() && roleType.roleModel != null && roleType.roleModel.hasBaseclassProblem())) // ignore if wrong def.ctor was created
this.scope.problemReporter().missingCallToBaseConstructor(
this, this.binding.declaringClass);
@@ -349,6 +349,19 @@ public void analyseCode(ClassScope classScope, InitializationFlowContext initial
}
}
}
+//{ObjectTeams: mandatory tsuper() call?
+ if (roleType.isRole()
+ && !TSuperHelper.isTSuper(this.binding)
+ && this.constructorCall.accessMode != ExplicitConstructorCall.Tsuper) {
+ for (ReferenceBinding tsuperRole : roleType.roleModel.getTSuperRoleBindings()) {
+ RoleModel tsuperModel = tsuperRole.roleModel;
+ if (tsuperModel != null && tsuperModel.hasFieldInit()) {
+ classScope.problemReporter().needToCallTSuper(this.constructorCall, tsuperRole);
+ break;
+ }
+ }
+ }
+// SH}
}
// check unreachable catch blocks
constructorContext.complainIfUnusedExceptionHandlers(this);
@@ -488,12 +501,14 @@ public void generateCode(ClassScope classScope, ClassFile classFile) {
public void generateSyntheticFieldInitializationsIfNecessary(MethodScope methodScope, CodeStream codeStream, ReferenceBinding declaringClass) {
//{ObjectTeams: new kind of synthetics, may occur in non-nested types, too:
SyntheticArgumentBinding[] syntheticArgs = declaringClass.valueParamSynthArgs();
- for (int i = 0, max = syntheticArgs == null ? 0 : syntheticArgs.length; i < max; i++) {
- SyntheticArgumentBinding syntheticArg;
- if ((syntheticArg = syntheticArgs[i]).matchingField != null) {
- codeStream.aload_0();
- codeStream.load(syntheticArg);
- codeStream.fieldAccess(Opcodes.OPC_putfield, syntheticArg.matchingField, declaringClass);
+ if (syntheticArgs != null) {
+ for (int i = 0, max = syntheticArgs.length; i < max; i++) {
+ SyntheticArgumentBinding syntheticArg;
+ if ((syntheticArg = syntheticArgs[i]).matchingField != null) {
+ codeStream.aload_0();
+ codeStream.load(syntheticArg);
+ codeStream.fieldAccess(Opcodes.OPC_putfield, syntheticArg.matchingField, declaringClass);
+ }
}
}
// SH}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index 9614a2e62..9d6ee320b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -43,6 +43,7 @@ import org.eclipse.objectteams.otdt.internal.core.compiler.ast.TypeValueParamete
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.BytecodeTransformer;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.CallinPrecedenceAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.InlineAttribute;
+import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.WordValueAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.Config;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.Dependencies;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
@@ -1860,6 +1861,7 @@ public void resolve() {
//{ObjectTeams: should we work at all?
Config config = Config.getConfig();
boolean fieldsAndMethods = config != null && config.verifyMethods;
+ boolean hasFieldInit = false;
if (fieldsAndMethods) {
// SH}
if (this.fields != null) {
@@ -1890,6 +1892,10 @@ public void resolve() {
}
localMaxFieldCount++;
lastVisibleFieldID = field.binding.id;
+//{ObjectTeams: has init?
+ if (field.initialization != null)
+ hasFieldInit = true;
+// SH}
break;
case AbstractVariableDeclaration.INITIALIZER:
@@ -1902,6 +1908,8 @@ public void resolve() {
//{ObjectTeams: also count type value parameters into maxFieldCount
if (this.typeParameters != null)
TypeValueParameter.updateMaxFieldCount(this);
+ if (hasFieldInit && isRole())
+ WordValueAttribute.addClassFlags(getRoleModel(), IOTConstants.OT_CLASS_HAS_FIELD_INITS);
}
// SH}
if (this.maxFieldCount < localMaxFieldCount) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index bd3949f84..5e98ec6a1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -11458,6 +11458,13 @@ public void explicitSuperInLiftConstructor(
constructor.constructorCall.sourceStart,
constructor.constructorCall.sourceEnd);
}
+public void needToCallTSuper(ASTNode location, ReferenceBinding tsuperRole) {
+ handle(IProblem.RoleConstructorNeedingTSuperCall,
+ new String[] { String.valueOf(tsuperRole.readableName()) },
+ new String[] { String.valueOf(tsuperRole.shortReadableName()) },
+ location.sourceStart,
+ location.sourceEnd);
+}
public void instantiationAnnotationInNonRole(TypeDeclaration typeDecl) {
int start=0, end=0;
String[] args = {new String(IOTConstants.INSTANTIATION)};
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index a47d8a9e2..5614c23e1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -1097,7 +1097,7 @@
1203104 = Annotation '@{0}' can only be applied to role classes (OTJLD 2.3.1(d)).
1203105 = Fields are discouraged in roles with InstantiationPolicy '{0}' (OTJLD 2.3.1(d)).
1203106 = Roles with InstantiationPolicy '{0}' should define equals() and hashCode() methods (OTJLD 2.3.1(d)).
-
+1203107 = Need to invoke a tsuper constructor because tsuper role ''{0}'' has field initializations.
1203201 = Illegal type for argument {0}: declared lifting not allowed in static methods (OTJLD 2.3.2(a)).
1203202 = Qualified type name not allowed here. Type after keyword "as" must be a role of the enclosing team {0} (OTJLD 2.3.2(a)).
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/core/compiler/IOTConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/core/compiler/IOTConstants.java
index bbd3fefec..63448bd8e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/core/compiler/IOTConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/core/compiler/IOTConstants.java
@@ -1,7 +1,7 @@
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
- * Copyright 2003, 2014 Fraunhofer Gesellschaft, Munich, Germany,
+ * Copyright 2003, 2018 Fraunhofer Gesellschaft, Munich, Germany,
* for its Fraunhofer Institute for Computer Architecture and Software
* Technology (FIRST), Berlin, Germany and Technical University Berlin,
* Germany.
@@ -127,6 +127,7 @@ public interface IOTConstants
public static final int OT_CLASS_ROLE_FILE = 16;
public static final int OT_CLASS_FLAG_HAS_TSUPER = 32;
public static final int OT_CLASS_CONFINED = 64; // means: superclass Object should be removed on loading
+ public static final int OT_CLASS_HAS_FIELD_INITS = 128;
public static final char[] CALLIN_FLAGS = "CallinFlags".toCharArray();
// possible values for CALLIN_FLAGS:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lifting/Lifting.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lifting/Lifting.java
index c2a1bb11e..c03a08580 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lifting/Lifting.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lifting/Lifting.java
@@ -1,7 +1,7 @@
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
- * Copyright 2003, 2013 Fraunhofer Gesellschaft, Munich, Germany,
+ * Copyright 2003, 2018 Fraunhofer Gesellschaft, Munich, Germany,
* for its Fraunhofer Institute for Computer Architecture and Software
* Technology (FIRST), Berlin, Germany and Technical University Berlin,
* Germany.
@@ -56,6 +56,7 @@ import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transfor
import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstConverter;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstEdit;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstGenerator;
+import org.eclipse.objectteams.otdt.internal.core.compiler.util.TSuperHelper;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.TypeAnalyzer;
@@ -291,6 +292,8 @@ public class Lifting extends SwitchOnBaseTypeGenerator
if (needMethodBodies) {
boolean shouldCallTSuper = implicitSuperRole != null && implicitSuperRole.isBound() && !roleModel._refinesExtends;
+ if (existingConstructor != null)
+ shouldCallTSuper &= existingConstructor.constructorCall.isImplicitSuper();
if (instantiableBoundRootRoleNode == roleNode)
genLiftToConstructorStatements(
baseClassBinding,
@@ -387,9 +390,10 @@ public class Lifting extends SwitchOnBaseTypeGenerator
/**
* @param baseClassBinding
+ * @param roleType type to generate into
* @param liftToConstructorDeclaration generated constructor
* @param baseArgName name of the base argument, either generated or from source
- * @param hasBoundTSuper
+ * @param shouldCallTSuper signals whether a tsuper() call should be generated
* @param gen for generating AST nodes
*/
private static void genLiftToConstructorSuperCall(
@@ -516,7 +520,8 @@ public class Lifting extends SwitchOnBaseTypeGenerator
public static boolean isLiftingCtor(MethodBinding binding) {
if (!binding.isConstructor())
return false;
- if (binding.parameters.length != 1)
+ int expectedParams = TSuperHelper.isTSuper(binding) ? 2 : 1;
+ if (binding.parameters.length != expectedParams)
return false;
return TypeBinding.equalsEquals(binding.parameters[0], binding.declaringClass.baseclass());
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/RoleModel.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/RoleModel.java
index 1b4ca3485..a5bbb76a3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/RoleModel.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/model/RoleModel.java
@@ -1,7 +1,7 @@
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
- * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany,
+ * Copyright 2004, 2018 Fraunhofer Gesellschaft, Munich, Germany,
* for its Fraunhofer Institute for Computer Architecture and Software
* Technology (FIRST), Berlin, Germany and Technical University Berlin,
* Germany.
@@ -1138,7 +1138,15 @@ public class RoleModel extends TypeModel
this._state.inititalize(ITranslationStates.STATE_ROLES_SPLIT);
}
- @Override
+ public boolean hasFieldInit() {
+ AbstractAttribute attribute = getAttribute(IOTConstants.OT_CLASS_FLAGS);
+ if (attribute instanceof WordValueAttribute) {
+ return (((WordValueAttribute) attribute).getValue() & IOTConstants.OT_CLASS_HAS_FIELD_INITS) != 0;
+ }
+ return false;
+ }
+
+ @Override
protected String getKindString() {
return "Role"; //$NON-NLS-1$
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/CopyInheritance.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/CopyInheritance.java
index 8d7fad2d4..a1046f89c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/CopyInheritance.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/copyinheritance/CopyInheritance.java
@@ -1,7 +1,7 @@
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
- * Copyright 2003, 2014 Fraunhofer Gesellschaft, Munich, Germany,
+ * Copyright 2003, 2018 Fraunhofer Gesellschaft, Munich, Germany,
* for its Fraunhofer Institute for Computer Architecture and Software
* Technology (FIRST), Berlin, Germany and Technical University Berlin,
* Germany.
@@ -2343,4 +2343,12 @@ public class CopyInheritance implements IOTConstants, ClassFileConstants, ExtraC
return CharOperation.prefixEquals(CREATOR_PREFIX_NAME, selector);
}
+ public static boolean needsSuperCtorCall(RoleModel role) {
+ for (ReferenceBinding tsuperRole : role.getTSuperRoleBindings()) {
+ RoleModel tsuperModel = tsuperRole.roleModel;
+ if (tsuperModel != null && tsuperModel.hasFieldInit())
+ return true;
+ }
+ return false;
+ }
}
diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/callinbinding/CallinMethodBinding.java b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/callinbinding/CallinMethodBinding.java
index 42e3b17c1..45639c96b 100644
--- a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/callinbinding/CallinMethodBinding.java
+++ b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/callinbinding/CallinMethodBinding.java
@@ -2363,7 +2363,7 @@ public class CallinMethodBinding extends AbstractOTJLDTest {
"Team4112cbmbm2_1.java",
"\n" +
"public team class Team4112cbmbm2_1 {\n" +
- " public class Role4112cbmbm2 {\n" +
+ " public class Role4112cbmbm2 playedBy T4112cbmbm2_4 {\n" +
" private int counter = 0;\n" +
" Object test(String arg) {\n" +
" T4112cbmbm2_1.addValue(String.valueOf(++counter)+\":\"+arg);\n" +
diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/regression/DevelopmentExamples.java b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/regression/DevelopmentExamples.java
index a1ce8c483..b92f03f59 100644
--- a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/regression/DevelopmentExamples.java
+++ b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/regression/DevelopmentExamples.java
@@ -5761,6 +5761,9 @@ public class DevelopmentExamples extends AbstractOTJLDTest {
" {\n" +
" buy <- replace book;\n" +
" String getName() -> String getName();\n" +
+ " public Subscriber(flightbooking.model.Passenger p) {\n" +
+ " tsuper();\n" +
+ " }\n" +
" };\n" +
" @Override\n" +
" public class Item playedBy flightbooking.model.Segment {\n" +
@@ -5964,6 +5967,9 @@ public class DevelopmentExamples extends AbstractOTJLDTest {
" {\n" +
" buy <- replace book;\n" +
" String getName() -> String getName();\n" +
+ " public Subscriber(Passenger p) {\n" +
+ " tsuper();\n" +
+ " }\n" +
" };\n" +
" @Override\n" +
" public class Item playedBy Segment {\n" +
diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/rolesandteams/ImplicitInheritance.java b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/rolesandteams/ImplicitInheritance.java
index c531ec679..6cf8e5e38 100644
--- a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/rolesandteams/ImplicitInheritance.java
+++ b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/rolesandteams/ImplicitInheritance.java
@@ -1428,4 +1428,267 @@ public class ImplicitInheritance extends AbstractOTJLDTest {
},
"M");
}
+
+ public void testMissingExplicitConstructor() throws Exception {
+ runNegativeTest(
+ new String[] {
+ "SubTeam.java",
+ "public team class SubTeam extends SuperTeamFI4 {\n" +
+ " @Override\n" +
+ " protected class R1 {\n" +
+ " protected R1() {\n" +
+ " tsuper();\n" +
+ " }\n" +
+ " }\n" +
+ "}\n",
+ "SuperTeamFI4.java",
+ "public team class SuperTeamFI4 {\n" +
+ " protected class R1 {\n" +
+ " protected String s1 = \"s1\";\n" +
+ " protected R1(int i) {}\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in SubTeam.java (at line 5)\n" +
+ " tsuper();\n" +
+ " ^^^^^^^^^\n" +
+ "The constructor SuperTeamFI4.R1() is undefined\n" +
+ "----------\n");
+ }
+
+ public void testFieldInitialization1_OK() throws Exception {
+ runConformTest(
+ new String[] {
+ "SubTeamFI1.java",
+ "public team class SubTeamFI1 extends SuperTeamFI4FI1 {\n" +
+ " @Override\n" +
+ " protected class R1 {\n" +
+ " protected R1() {\n" +
+ " tsuper();\n" +
+ " }\n" +
+ " }\n" +
+ " @Override\n" +
+ " protected class R3 {\n" +
+ " }\n" +
+ " public static void main(String... args) {\n" +
+ " new SubTeamFI1().test();\n" +
+ " }\n" +
+ " void test() {\n" +
+ " System.out.print(new R1().s1);\n" + // OK: has explicit tsuper() call
+ " System.out.print(new R2().s2);\n" + // OK: fully inherited, all members are copied
+ " System.out.print(new R3().s3);\n" + // OK: constructor is copied
+ " }\n" +
+ "}\n",
+ "SuperTeamFI4FI1.java",
+ "public team class SuperTeamFI4FI1 {\n" +
+ " protected class R1 {\n" +
+ " protected String s1 = \"s1\";\n" +
+ " }\n" +
+ " protected class R2 {\n" +
+ " protected String s2 = \"s2\";\n" +
+ " }\n" +
+ " protected class R3 {\n" +
+ " protected String s3 = \"s3\";\n" +
+ " }\n" +
+ "}\n",
+ },
+ "s1s2s3");
+ }
+
+ public void testFieldInitialization2_bound_OK() throws Exception {
+ runConformTest(
+ new String[] {
+ "SubTeamFI2.java",
+ "public team class SubTeamFI2 extends SuperTeamFI4FI2 {\n" +
+ " @Override\n" +
+ " protected class R1 {\n" +
+ " protected R1(Base1 b) {\n" +
+ " tsuper(b);\n" +
+ " }\n" +
+ " }\n" +
+ " @Override\n" +
+ " protected class R2 {\n" +
+ " }\n" +
+ " @Override\n" +
+ " protected class R3 {\n" +
+ " protected R3() {\n" +
+ " tsuper(base());\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String... args) {\n" +
+ " new SubTeamFI2().test();\n" +
+ " }\n" +
+ " void test() {\n" +
+ " System.out.print(new R1(new Base1()).s1);\n" + // OK: explicit tsuper() call (delegating lifting constructor)
+ " System.out.print(new R2(new Base2()).s2);\n" + // OK: copied lifting constructor
+ " System.out.print(new R3(new Base3()).s3);\n" + // OK: explicit tsuper() call (delegation from creating to lifting constructor)
+ " }\n" +
+ "}\n",
+ "SuperTeamFI4FI2.java",
+ "public team class SuperTeamFI4FI2 {\n" +
+ " protected class R1 playedBy Base1 {\n" +
+ " protected String s1 = \"s1\";\n" +
+ " }\n" +
+ " protected class R2 playedBy Base2 {\n" +
+ " protected String s2 = \"s2\";\n" +
+ " }\n" +
+ " protected class R3 playedBy Base3 {\n" +
+ " protected String s3 = \"s3\";\n" +
+ " }\n" +
+ "}\n",
+ "Base1.java",
+ "public class Base1 {}\n",
+ "Base2.java",
+ "public class Base2 {}\n",
+ "Base3.java",
+ "public class Base3 {}\n",
+ },
+ "s1s2s3");
+ }
+
+ public void testFieldInitialization3_NOK() throws Exception {
+ runNegativeTest(
+ new String[] {
+ "SubTeamFI3a.java",
+ "public team class SubTeamFI3a extends SuperTeamFI4FI3 {\n" +
+ " @Override\n" +
+ " protected class R1 {\n" +
+ " protected R1() {\n" +
+ " super();\n" +
+ " }\n" +
+ " }\n" +
+ " @Override\n" +
+ " protected class R2 {\n" +
+ " protected R2() {\n" +
+ " super();\n" +
+ " }\n" +
+ " protected R2(int i) {\n" + // implicit super() is not acceptable
+ " }\n" +
+ " }\n" +
+ "}\n",
+ "SuperTeamFI4FI3.java",
+ "public team class SuperTeamFI4FI3 {\n" +
+ " protected class R1 {\n" +
+ " String s1 = \"s1\";\n" +
+ " }\n" +
+ " protected class R2 extends R1 {\n" +
+ " String s2 = \"s2\";\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in SubTeamFI3a.java (at line 5)\n" +
+ " super();\n" +
+ " ^^^^^^^^\n" +
+ "Need to invoke a tsuper constructor because tsuper role \'SuperTeamFI4FI3.R1\' has field initializations.\n" +
+ "----------\n" +
+ "2. ERROR in SubTeamFI3a.java (at line 11)\n" +
+ " super();\n" +
+ " ^^^^^^^^\n" +
+ "Need to invoke a tsuper constructor because tsuper role \'SuperTeamFI4FI3.R2\' has field initializations.\n" +
+ "----------\n" +
+ "3. ERROR in SubTeamFI3a.java (at line 13)\n" +
+ " protected R2(int i) {\n" +
+ " ^^^^^^^^^\n" +
+ "Need to invoke a tsuper constructor because tsuper role \'SuperTeamFI4FI3.R2\' has field initializations.\n" +
+ "----------\n");
+ }
+
+ public void testFieldInitialization4_bound_NOK() throws Exception {
+ // variants with regular constructors
+ runNegativeTest(
+ new String[] {
+ "SubTeamFI4.java",
+ "public team class SubTeamFI4 extends SuperTeamFI4 {\n" +
+ " @Override\n" +
+ " protected class R1 {\n" +
+ " protected R1() {\n" +
+ " tsuper();\n" +
+ " }\n" +
+ " }\n" +
+ " @Override\n" +
+ " protected class R2 {\n" +
+ " protected R2() {\n" +
+ " base();\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String... args) {\n" +
+ " new SubTeamFI4().test();\n" +
+ " }\n" +
+ " void test() {\n" +
+ " System.out.print(new R1().s1);\n" +
+ " System.out.print(new R2().s2);\n" +
+ " }\n" +
+ "}\n",
+ "SuperTeamFI4.java",
+ "public team class SuperTeamFI4 {\n" +
+ " protected class R1 playedBy Base1 {\n" +
+ " protected String s1 = \"s1\";\n" +
+ " }\n" +
+ " protected class R2 playedBy Base2 {\n" +
+ " protected String s2 = \"s2\";\n" +
+ " }\n" +
+ "}\n",
+ "Base1.java",
+ "public class Base1 {}\n",
+ "Base2.java",
+ "public class Base2 {}\n",
+ },
+ "----------\n" +
+ "1. ERROR in SubTeamFI4.java (at line 5)\n" +
+ " tsuper();\n" +
+ " ^^^^^^^^^\n" +
+ "The constructor SuperTeamFI4.R1() is undefined\n" +
+ "----------\n" +
+ "2. ERROR in SubTeamFI4.java (at line 10)\n" +
+ " protected R2() {\n" +
+ " ^^^^\n" +
+ "Need to invoke a tsuper constructor because tsuper role \'SuperTeamFI4.R2\' has field initializations.\n" +
+ "----------\n");
+ }
+
+ public void testFieldInitialization5_bound_NOK() throws Exception {
+ // variants with lifting constructors
+ runNegativeTest(
+ new String[] {
+ "SubTeamFI5.java",
+ "public team class SubTeamFI5 extends SuperTeamFI5 {\n" +
+ " @Override\n" +
+ " protected class R1 {\n" +
+ " protected R1(Base1 b) {\n" +
+ " super();\n" +
+ " }\n" +
+ " }\n" +
+ " @Override\n" +
+ " protected class R2 {\n" +
+ " protected R2(Base1 b) {\n" +
+ " super(b);\n" +
+ " }\n" +
+ " }\n" +
+ "}\n",
+ "SuperTeamFI5.java",
+ "public team class SuperTeamFI5 {\n" +
+ " protected class R1 playedBy Base1 {\n" +
+ " String s1 = \"s1\";\n" +
+ " }\n" +
+ " protected class R2 extends R1 {\n" +
+ " String s2 = \"s2\";\n" +
+ " }\n" +
+ "}\n",
+ "Base1.java",
+ "public class Base1 {}\n",
+ },
+ "----------\n" +
+ "1. ERROR in SubTeamFI5.java (at line 5)\n" +
+ " super();\n" +
+ " ^^^^^^^^\n" +
+ "Need to invoke a tsuper constructor because tsuper role \'SuperTeamFI5.R1\' has field initializations.\n" +
+ "----------\n" +
+ "2. ERROR in SubTeamFI5.java (at line 11)\n" +
+ " super(b);\n" +
+ " ^^^^^^^^^\n" +
+ "Need to invoke a tsuper constructor because tsuper role \'SuperTeamFI5.R2\' has field initializations.\n" +
+ "----------\n");
+ }
}

Back to the top