Bug 576367 - IllegalAccessError caused by unnecessary cast to
inaccessible type in callout-to-field
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CalloutImplementor.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CalloutImplementor.java
index a7d8cd3..44353dc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CalloutImplementor.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CalloutImplementor.java
@@ -614,7 +614,7 @@
baseAccess = baseSend;
break;
case DYN_ACCESS:
- baseAccess = CalloutImplementorDyn.baseAccessExpression(calloutDecl.scope, this._role, baseType, receiver, calloutDecl.baseMethodSpec, arguments, gen);
+ baseAccess = CalloutImplementorDyn.baseAccessExpression(calloutDecl.scope, this._role, baseType, receiver, calloutDecl, arguments, gen);
break;
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CalloutImplementorDyn.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CalloutImplementorDyn.java
index 6933f18..b36aa4d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CalloutImplementorDyn.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CalloutImplementorDyn.java
@@ -28,6 +28,7 @@
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.objectteams.otdt.internal.core.compiler.ast.CalloutMappingDeclaration;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.FieldAccessSpec;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.MethodSpec;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.PotentialLowerExpression;
@@ -49,9 +50,10 @@
public static Expression baseAccessExpression(Scope scope, RoleModel roleModel, ReferenceBinding baseType,
- Expression receiver, MethodSpec baseSpec, Expression[] arguments,
+ Expression receiver, CalloutMappingDeclaration calloutDecl, Expression[] arguments,
AstGenerator gen)
{
+ MethodSpec baseSpec = calloutDecl.baseMethodSpec;
char[] selector = ensureAccessor(scope, baseType, baseSpec.isStatic()).selector;
TeamModel teamModel = roleModel.getTeamModel();
TeamModel.UpdatableIntLiteral accessIdArg = gen.updatableIntLiteral(baseSpec.accessId);
@@ -74,8 +76,10 @@
MessageSend messageSend = gen.messageSend(receiver, selector, new Expression[] {accessIdArg, opKindArg, packagedArgs, callerArg});
if (baseSpec.resolvedType() == TypeBinding.VOID || opKind == 1)
return messageSend;
- else
- return gen.createCastOrUnboxing(messageSend, baseSpec.resolvedType(), true/*baseAccess*/);
+ TypeBinding expectedType = calloutDecl.mappings != null || calloutDecl.roleMethodSpec.returnNeedsTranslation
+ ? baseSpec.resolvedType()
+ : calloutDecl.roleMethodSpec.resolvedType(); // shortcut to avoid casting to an intermediate base type
+ return gen.createCastOrUnboxing(messageSend, expectedType, true/*baseAccess*/);
}
public static MethodBinding ensureAccessor(Scope scope, ReferenceBinding baseType, boolean isStatic) {
diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/roleplaying/BaseClassVisibility.java b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/roleplaying/BaseClassVisibility.java
index 8f025e5..40bd1e4 100644
--- a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/roleplaying/BaseClassVisibility.java
+++ b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/roleplaying/BaseClassVisibility.java
@@ -2232,4 +2232,36 @@
},
"Base");
}
+
+ public void testBug576367() {
+ runConformTest(new String[] {
+ "p2/Team576367.java",
+ "package p2;\n" +
+ "import java.util.Arrays;\n" +
+ "import base p1.Base576367;\n" +
+ "import base p1.Base576367.Inner;\n" +
+ "public team class Team576367 {\n" +
+ " @SuppressWarnings(\"decapsulation\")\n" +
+ " protected class R playedBy Base576367 {\n" +
+ " public R() { base(); }\n" +
+ " public Object[] getInners() -> get Inner[] inners;\n" +
+ " }\n" +
+ " public static void main(String... args) {\n" +
+ " new Team576367().test();\n" +
+ " }\n" +
+ " void test() {\n" +
+ " Object[] os = new R().getInners();\n" +
+ " System.out.print(Arrays.toString(os));\n" +
+ " }\n" +
+ "}\n",
+ "p1/Base576367.java",
+ "package p1;\n" +
+ "public class Base576367 {\n" +
+ " private Inner[] inners = { new Inner() };\n" +
+ " static class Inner {\n" +
+ " @Override public String toString() { return \"inner\"; }\n" +
+ " }\n" +
+ "}\n"},
+ "[inner]");
+ }
}