diff options
| author | Stephan Herrmann | 2018-08-26 08:29:44 +0000 |
|---|---|---|
| committer | Stephan Herrmann | 2018-08-26 08:29:44 +0000 |
| commit | b8c129fe8b89a7c02820ac64e0611d79ef5804f3 (patch) | |
| tree | 82b02bf38bab878a8543a8b4f22ce8a547314d68 | |
| parent | 9a1b554e53fec4ddb69125715d153336f5eb7e0f (diff) | |
| download | org.eclipse.objectteams-b8c129fe8b89a7c02820ac64e0611d79ef5804f3.tar.gz org.eclipse.objectteams-b8c129fe8b89a7c02820ac64e0611d79ef5804f3.tar.xz org.eclipse.objectteams-b8c129fe8b89a7c02820ac64e0611d79ef5804f3.zip | |
initialize fields
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"); + } } |
