Final fix for Bug 318084 - [compiler] cannot callin-bind a callout-defined method
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 bae7ee5..f90165a 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
@@ -1644,8 +1644,10 @@
StandardElementGenerator.createGetBaseForUnboundLowerable(clazz);
// 6. resolve method mappings and create callout methods:
- resolveMethodMappings(clazz);
+ MethodMappingResolver resolver = resolveCalloutMappings(clazz);
CalloutImplementor.transformCallouts(clazz);
+ if (resolver != null)
+ resolver.resolve(false/*doCallout*/); // callins last so all methods incl. callout are already in place
clazz.setState(STATE_METHODS_CREATED);
return true;
@@ -1730,7 +1732,7 @@
}
// detail of STATE_METHODS_CREATED:
- private static void resolveMethodMappings(RoleModel role)
+ private static MethodMappingResolver resolveCalloutMappings(RoleModel role)
{
ReferenceBinding roleBinding = role.getBinding();
@@ -1761,9 +1763,11 @@
// actually need to proceed even with no base class, because
// method mappings without baseclass are reported within resolve() below:
- MethodMappingResolver resolver = new MethodMappingResolver(role);
- resolver.resolve(!hasBaseclassProblem && needMethodBodies(roleDecl));
+ MethodMappingResolver resolver = new MethodMappingResolver(role, !hasBaseclassProblem && needMethodBodies(roleDecl));
+ resolver.resolve(true/*doCallout*/);
+ return resolver; // pass this resolver so establishMethodsCreated can continue with resolving callins
}
+ return null;
}
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 211f6e2..e174c7d 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
@@ -374,7 +374,7 @@
if (calloutBindingDeclaration.binding.inferred == InferenceKind.NONE) { // don't advertise inferred callout via the interface.
if (templateBinding.isStatic()) // no real ifc part for static method, fake it!
createInterfaceFakeStatic(templateBinding, calloutBindingDeclaration);
- else if (!overridesExplicitNonRole) // also no ifc part for method from explicit non-role super
+ else if (((modifiers & AccPrivate) == 0) && !overridesExplicitNonRole) // also no ifc part for privates and methods from explicit non-role super
createAbstractRoleMethodDeclarationPart(templateBinding,
calloutBindingDeclaration,
modifiers,
@@ -458,10 +458,13 @@
}
else // == CLASS
{
- if (calloutBindingDeclaration.binding.inferred == InferenceKind.NONE) { // only if actually advertised in the ifc-part
+ if ((modifiers & AccPrivate) != 0) { // don't advertize in ifc
+ // FIXME(SH): need to generate bridge methdods?
+ } else if (calloutBindingDeclaration.binding.inferred == InferenceKind.NONE) { // only if actually advertised in the ifc-part
// generated callout method must be public in the classPart.
// access control is done only via the interface part.
- newMethod.modifiers &= ~(AccProtected | AccPrivate);
+ MethodModel.getModel(newMethod).storeModifiers(newMethod.modifiers);
+ newMethod.modifiers &= ~(AccProtected);
newMethod.modifiers |= AccPublic;
}
// abstract will be cleared once we are done.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/MethodMappingResolver.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/MethodMappingResolver.java
index deb2227..3f340eb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/MethodMappingResolver.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/MethodMappingResolver.java
@@ -53,21 +53,22 @@
/** Index is the methods name+signature */
private Map<String, List<CalloutMappingDeclaration>> _foundRoleMethods
= new HashMap<String, List<CalloutMappingDeclaration>>();
-
+ boolean resolveBaseMethods;
/**
* @param role
*/
- public MethodMappingResolver(RoleModel role)
+ public MethodMappingResolver(RoleModel role, boolean resolveBaseMethods)
{
this._role = role;
this._roleScope = role.getAst().scope; // we definitely have an AST here
+ this.resolveBaseMethods = resolveBaseMethods;
}
/**
* Main entry for STATE_MAPPINGS_RESOLVED
*/
- public boolean resolve(boolean resolveBaseMethods)
+ public boolean resolve(boolean doCallout)
{
AbstractMethodMappingDeclaration[] methodMappings =
this._role.getAst().callinCallouts;
@@ -81,10 +82,12 @@
for (int idx = 0; idx < methodMappings.length; idx++)
{
AbstractMethodMappingDeclaration methodMapping = methodMappings[idx];
+ if (methodMapping.isCallout() != doCallout)
+ continue;
if (this._role.getBinding().baseclass() == null && !this._role.hasBaseclassProblem()) {
this._roleScope.problemReporter().methodMappingNotInBoundRole(methodMapping, this._role.getAst());
methodMapping.tagAsHavingErrors();
- resolveBaseMethods = false;
+ this.resolveBaseMethods = false;
}
methodMapping.resolveAnnotations();
@@ -95,12 +98,12 @@
this._roleScope.problemReporter().calloutToEnclosing((CalloutMappingDeclaration)methodMapping, this._role);
result = false;
} else {
- result &= resolveCalloutMapping((CalloutMappingDeclaration) methodMapping, resolveBaseMethods);
+ result &= resolveCalloutMapping((CalloutMappingDeclaration) methodMapping);
}
}
else // callin:
{
- result &= resolveCallinMapping((CallinMappingDeclaration) methodMapping, resolveBaseMethods);
+ result &= resolveCallinMapping((CallinMappingDeclaration) methodMapping);
}
}
@@ -119,11 +122,10 @@
* Reports as many errors as can be found.
* @return true if no error occurred
*/
- private boolean resolveCallinMapping(CallinMappingDeclaration callinMappingDeclaration,
- boolean resolveBaseMethods)
+ private boolean resolveCallinMapping(CallinMappingDeclaration callinMappingDeclaration)
{
// main resolving task:
- callinMappingDeclaration.resolveMethodSpecs(this._role, this._role.getBaseTypeBinding(), resolveBaseMethods);
+ callinMappingDeclaration.resolveMethodSpecs(this._role, this._role.getBaseTypeBinding(), this.resolveBaseMethods);
callinMappingDeclaration.binding._roleMethodBinding = callinMappingDeclaration.getRoleMethod();
@@ -135,7 +137,7 @@
* Reports as many errors as can be found.
* @return true if no error occurred
*/
- private boolean resolveCalloutMapping(CalloutMappingDeclaration calloutMappingDeclaration, boolean resolveBaseMethod)
+ private boolean resolveCalloutMapping(CalloutMappingDeclaration calloutMappingDeclaration)
{
if (calloutMappingDeclaration.scope == null) { // severe error
assert calloutMappingDeclaration.hasErrors();
@@ -146,13 +148,13 @@
// A callout-with-signatures should always resolve its base method,
// because that base method could determine the static flag.
calloutMappingDeclaration.resolveMethodSpecs(this._role,this._role.getBaseTypeBinding(),
- resolveBaseMethod||calloutMappingDeclaration.hasSignature);
+ this.resolveBaseMethods||calloutMappingDeclaration.hasSignature);
// This binding is part of the interface part of a role:
MethodBinding roleMethodBinding = calloutMappingDeclaration.roleMethodSpec.resolvedMethod;
calloutMappingDeclaration.binding._roleMethodBinding = roleMethodBinding;
- if (resolveBaseMethod) {
+ if (this.resolveBaseMethods) {
if ( calloutMappingDeclaration.baseMethodSpec != null
&& calloutMappingDeclaration.baseMethodSpec.resolvedMethod != null)
{