Fix for Bug 304346 - Overriding of role ctor does not prevent generation of default ctor
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 f65d078..7617bc8 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
@@ -154,8 +154,9 @@
this.scope.problemReporter().baseConstructorCallInLiftingConstructor(this);
} else {
if (!calledHere && !calledIndirectly) {
- this.scope.problemReporter().missingCallToBaseConstructor(
- this, this.binding.declaringClass);
+ if (!(isDefaultConstructor() && roleType.roleModel != null && roleType.roleModel.hasBaseclassProblem())) // ignore if wrong def.ctor was created
+ this.scope.problemReporter().missingCallToBaseConstructor(
+ this, this.binding.declaringClass);
} else if (calledHere && calledIndirectly) {
this.scope.problemReporter().
tooManyCallsToBaseConstructor(this.statements[0], this.constructorCall);
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 ee7cc34..44fa603 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
@@ -653,8 +653,12 @@
//the default int instead of just null (consistency purpose)
//{ObjectTeams: no default constructor for bound roles
-// (cf. also StandardElementGenerator.removeDefaultConstructor())
- if (this.baseclass != null)
+// (cf. also AstEdit.removeDefaultConstructor())
+// also unbound roles defer constructor creation to Dependencies.establishMethodsCreated(RoleModel)
+ // if roleModel != null assume were called later than during parsing:
+ // - from CopyInheritance.copyMethod(OTConfined)
+ // - crom Dependencies.establishMethodsCreated(RoleModel)
+ if (this.isDirectRole() && this.roleModel == null)
return null;
// SH}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index cdfb75a..d7859ee 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -3152,6 +3152,9 @@
// two-way-link type declarations:
AstEdit.addMemberTypeDeclaration(this.currentTeam, typeDecl); // also sets enclosingType.
}
+ } else {
+ if (findEnclosingTeam()) // FIXME(SH): skip role local types
+ typeDecl.modifiers |= ExtraCompilerModifiers.AccRole;
}
}
private boolean findEnclosingTeam() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/control/Dependencies.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/control/Dependencies.java
index 58f3e61..4156011 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/control/Dependencies.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/control/Dependencies.java
@@ -68,8 +68,10 @@
import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.StandardElementGenerator;
import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.TeamMethodGenerator;
import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.TransformStatementsVisitor;
+import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstEdit;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleFileHelper;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator;
+import org.eclipse.objectteams.otdt.internal.core.compiler.util.TSuperHelper;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.TypeAnalyzer;
/**
@@ -1612,6 +1614,21 @@
{ // interfaces have not constructores, don't bother.
boolean needMethodBodies = needMethodBodies(subRoleDecl);
AbstractMethodDeclaration[] methodDeclarations = subRoleDecl.methods;
+ // may need to create default constructor first:
+ boolean hasConstructor = false;
+ if (methodDeclarations != null)
+ for (int i=0; i<methodDeclarations.length; i++)
+ if (methodDeclarations[i].isConstructor() && !TSuperHelper.isTSuper(methodDeclarations[i].binding)) {
+ hasConstructor = true;
+ break;
+ }
+ if (!hasConstructor) {
+ ConstructorDeclaration defCtor = subRoleDecl.createDefaultConstructor(needMethodBodies, false);
+ AstEdit.addMethod(subRoleDecl, defCtor);
+ CopyInheritance.connectDefaultCtor(clazz, defCtor.binding);
+ methodDeclarations = subRoleDecl.methods;
+ }
+ // now the creation methods for all constructors:
if (methodDeclarations != null)
{
for (int i=0; i<methodDeclarations.length; i++)
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 b2a3a66..3ead6d8 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
@@ -618,6 +618,8 @@
* Then from there on inwards only role names are compared.
*/
public boolean hasTSuperRole(ReferenceBinding role) {
+ if (!role.isRole())
+ return false;
ReferenceBinding otherClass = null, otherIfc = null;
if(role.isInterface()) {
otherIfc = role;
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 f7eb245..db9d0ed 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
@@ -1257,6 +1257,30 @@
}
return dstMethod;
}
+
+ /**
+ * Default role constructors are not copied but created anew for each role
+ * (see the caller of this method).
+ * This method records the new ctor as overriding all its tsuper versions (if any).
+ */
+ public static void connectDefaultCtor(RoleModel clazz, MethodBinding binding) {
+ ReferenceBinding[] tsupers = clazz.getTSuperRoleBindings();
+ if (tsupers.length == 0) return;
+ MethodBinding[] tsuperCtors = new MethodBinding[tsupers.length];
+ int j=0;
+ for (int i=0; i<tsupers.length; i++) {
+ MethodBinding tsuperCtor = tsupers[i].getExactConstructor(Binding.NO_PARAMETERS);
+ if (tsuperCtor != null)
+ tsuperCtors[j++] = tsuperCtor;
+ }
+ if (j>0) {
+ if (j == tsupers.length)
+ binding.overriddenTSupers = tsuperCtors;
+ else
+ System.arraycopy(tsuperCtors, 0, binding.overriddenTSupers=new MethodBinding[j], 0, j);
+ }
+ }
+
/**
* Nothing exciting here, just create a new field declaration.
* @param field
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstEdit.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstEdit.java
index 5b469e5..f0be3c8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstEdit.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstEdit.java
@@ -273,6 +273,7 @@
* After we found a bound role (binding might be inherited through some
* dimension), we have to ensure, that it has no default constructor,
* because those are superceded by lifting constructors.
+ * Similar for roles with implicitly inherited explicit constructors.
* @param roleType
*/
public static void removeDefaultConstructor(TypeDeclaration roleType) {