Follow-up fix for Bug 316148 - [otjld] [compiler] Merging of class-based and binding-based precedences is underspecified
(see comment 4).
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 7b3dbc8..03dcd82 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
@@ -1646,8 +1646,9 @@
int NonAfterCallinInAfterPrecedence = CALLIN_RELATED + 8004; // 4.8(a)
int CallinBindingNotFound = CALLIN_RELATED + 8005; // 4.8(b)
int IllegalEnclosingForCallinName = CALLIN_RELATED + 8006; // 4.8(b)
- int IncompatiblePrecedenceLists = CALLIN_RELATED + 8007; // 4.8(d)
- int PrecedenceForOverriding = CALLIN_RELATED + 8008; // 4.8(e)
+ int IncompatiblePrecedenceListsOther = CALLIN_RELATED + 8007; // 4.8(d)
+ int IncompatiblePrecedenceListsSymmetric = CALLIN_RELATED + 8008; // 4.8(d)
+ int PrecedenceForOverriding = CALLIN_RELATED + 8009; // 4.8(e)
int CovariantReturnRequiresTypeParameter = CALLIN_RELATED + 9001; // 4.9.3(c)
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 09dad1e..48e55d6 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
@@ -1986,57 +1986,24 @@
// SH}
//{ObjectTeams: push precedence declaration out to the team:
-public void addResolvedPrecedenceDeclaration(
- char[] roleName, PrecedenceDeclaration decl)
+public void addResolvedPrecedence(char[] roleName, PrecedenceBinding precBinding)
{
- char[][] prefix = new char[][]{roleName}; // for easier arrayConcat.
- for (int i = 0; i < decl.bindingNames.length; i++) {
- NameReference bindingName = decl.bindingNames[i];
- QualifiedNameReference newRef;
- char[][] tokens;
- long[] poss;
- if (bindingName instanceof SingleNameReference) {
- SingleNameReference sref = (SingleNameReference)bindingName;
- tokens = CharOperation.arrayConcat(prefix, sref.token);
- long pos = ((long)sref.sourceStart<<32)+sref.sourceEnd;
- poss = new long[]{pos, pos};
- } else {
- assert bindingName instanceof QualifiedNameReference;
- QualifiedNameReference qref = (QualifiedNameReference)bindingName;
- int oldLen = qref.tokens.length;
- tokens = CharOperation.arrayConcat(prefix, qref.tokens);
- poss = new long[oldLen+1];
- poss[0] = qref.sourcePositions[0];
- System.arraycopy(qref.sourcePositions, 0, poss, 1, oldLen);
- }
- newRef = new QualifiedNameReference(tokens, poss,
- bindingName.sourceStart, bindingName.sourceEnd);
- newRef.binding = bindingName.binding;
- decl.bindingNames[i] = newRef;
- }
if (this.enclosingType != null) {
- this.enclosingType.addResolvedPrecedenceDeclaration(this.name, decl);
+ this.enclosingType.addResolvedPrecedence(this.name, precBinding);
return;
}
- if (this.precedences == null) {
- this.precedences = new PrecedenceDeclaration[] { decl };
- this.binding.precedences = new PrecedenceBinding[] { decl.binding };
+ if (this.binding.precedences == PrecedenceBinding.NoPrecedences) {
+ this.binding.precedences = new PrecedenceBinding[] { precBinding };
} else {
// insert at front to account for ordering according to 4.8(d):
// - inner before outer
// - textual order (same nesting level)
- int len = this.precedences.length;
- assert len == this.binding.precedences.length;
- System.arraycopy(
- this.precedences, 0,
- this.precedences = new PrecedenceDeclaration[len+1], 1,
- len);
- this.precedences[0] = decl;
+ int len = this.binding.precedences.length;
System.arraycopy(
this.binding.precedences, 0,
this.binding.precedences = new PrecedenceBinding[len+1], 1,
len);
- this.binding.precedences[0] = decl.binding;
+ this.binding.precedences[0] = precBinding;
}
}
// SH}
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 4f43b30..c6eea26 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
@@ -60,6 +60,7 @@
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.CallinCalloutBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.DependentTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.ITeamAnchor;
+import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.PrecedenceBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.MethodModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.RoleModel;
@@ -10845,16 +10846,31 @@
precDecl.sourceStart,
precDecl.sourceEnd);
}
-public void incompatiblePrecedenceLists(NameReference reference, TypeDeclaration declaration) {
- String[] args = new String[] {
- new String(declaration.name)
- };
+public void incompatiblePrecedenceLists(ASTNode location, TypeDeclaration declaration, PrecedenceBinding prec1, PrecedenceBinding prec2) {
+ String[] args;
+ int problemId;
+ if (location instanceof PrecedenceDeclaration) {
+ problemId = IProblem.IncompatiblePrecedenceListsOther;
+ args = new String[] {
+ new String(declaration.name),
+ (((PrecedenceDeclaration)location).binding == prec1
+ ? prec2.toString()
+ : prec1.toString())
+ };
+ } else { // prec decl not found, report both bindings in the details
+ problemId = IProblem.IncompatiblePrecedenceListsSymmetric;
+ args = new String[] {
+ new String(declaration.name),
+ prec1.toString(),
+ prec2.toString()
+ };
+ }
this.handle(
- IProblem.IncompatiblePrecedenceLists,
+ problemId,
args,
args,
- reference.sourceStart,
- reference.sourceEnd);
+ location.sourceStart,
+ location.sourceEnd);
}
public void precedenceForOverriding(NameReference ref_i, NameReference ref_j) {
String[] args = new String[] {
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 bab7289..d570355 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
@@ -914,8 +914,9 @@
1408004 = 'precedence after' declaration cannot refer to '{0}' bindings (OTJLD 4.8(a)).
1408005 = Callin binding {0} not found in type {1} (OTJLD 4.8(b)).
1408006 = Type {0} is not a legal prefix for callin {1}; Need a role or team type (OTJLD 4.8(b)).
-1408007 = Contradictory precedence lists for type {0} cannot be combined (OTJLD 4.8(d)).
-1408008 = Cannot define precedence for '{0}' and '{1}', because the former overrides the latter (OTJLD 4.8(e)).
+1408007 = Contradictory precedence lists for type {0} cannot be combined (conflicts with ''{1}'') (OTJLD 4.8(d)).
+1408008 = Contradictory precedence lists for type {0} cannot be combined (''{1}'' vs. ''{2}'') (OTJLD 4.8(d)).
+1408009 = Cannot define precedence for '{0}' and '{1}', because the former overrides the latter (OTJLD 4.8(e)).
1409001 = This callin binding admits covariant base method return types, must use a fresh type variable like "<E extends {0}> E" as the role side return type (OTJLD 4.9.3(c)).
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/PrecedenceDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/PrecedenceDeclaration.java
index 4eb9871..be23320 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/PrecedenceDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/PrecedenceDeclaration.java
@@ -117,9 +117,9 @@
if ( type.enclosingType != null
&& type.enclosingType.isTeam())
{
- type.enclosingType.addResolvedPrecedenceDeclaration(
+ type.enclosingType.addResolvedPrecedence(
type.binding.sourceName(),
- this);
+ this.binding);
}
return this.binding;
}
@@ -231,7 +231,7 @@
*/
public static PrecedenceBinding[] mergePrecedences(TypeDeclaration type)
{
- int len = (type.precedences != null) ? type.precedences.length : 0;
+ int len = (type.binding.precedences != null) ? type.binding.precedences.length : 0;
// TODO (SH): tsuper teams!
ReferenceBinding superTeam = type.binding.superclass();
int lenSuper = (superTeam != null) ? superTeam.precedences.length : 0;
@@ -240,7 +240,7 @@
PrecedenceBinding[] precedences = new PrecedenceBinding[len + lenSuper];
for (int i = 0; i < len; i++) {
- precedences[i] = type.precedences[i].binding;
+ precedences[i] = type.binding.precedences[i];
}
for (int i = 0; i < lenSuper; i++) {
precedences[len+i] = strengthenPrecendence(type, superTeam.precedences[i]);
@@ -268,7 +268,8 @@
count--;
} else {
if (i < len)
- type.scope.problemReporter().incompatiblePrecedenceLists(type.precedences[i].bindingNames[i], type);
+ type.scope.problemReporter().incompatiblePrecedenceLists(findPrecedenceSource(precedences[i], precedences[j], type),
+ type, precedences[i], precedences[j]);
else
throw new InternalCompilerError("Incompatible inherited precedence lists"); //$NON-NLS-1$
}
@@ -285,6 +286,14 @@
}
return precedences;
}
+
+ private static ASTNode findPrecedenceSource(PrecedenceBinding prec1, PrecedenceBinding prec2, TypeDeclaration type) {
+ if (type.precedences != null)
+ for (int i = 0; i < type.precedences.length; i++)
+ if (type.precedences[i].binding == prec1 || type.precedences[i].binding == prec2)
+ return type.precedences[i];
+ return type;
+ }
/**
* Update all callin bindings from super team to current team