FIr part 1 for Bug 323327 - [compiler] accessing a protected inner role from a private method of a nested team
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index 15304c6..5695680 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -1169,6 +1169,10 @@
case SyntheticMethodBinding.MethodAccess :
case SyntheticMethodBinding.SuperMethodAccess :
case SyntheticMethodBinding.BridgeMethod :
+//{ObjectTeams: more kinds:
+ case SyntheticMethodBinding.RoleMethodBridgeInner :
+ case SyntheticMethodBinding.RoleMethodBridgeOuter :
+// SH}
// generate a method info to emulate an access to a non-accessible method / super-method or bridge method
addSyntheticMethodAccessMethod(syntheticMethod);
break;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
index 8f4797a..c4e2d31 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
@@ -135,8 +135,8 @@
//{ObjectTeams:
private boolean isDecapsulation = false;
- // special case: the role method call in a callin wrapper needs special resolving
- public boolean isCallinRoleMethodCall = false;
+ // special case: the role method call in a method pushed out to the enclosing team needs special resolving
+ public boolean isPushedOutRoleMethodCall = false;
// SH}
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
@@ -601,7 +601,7 @@
this.actualReceiverType = ((WeakenedTypeBinding)this.actualReceiverType).getStrongType();
this.bits |= NeedReceiverGenericCast; // addes a cast to this.actualReceiverType;
}
- if (this.receiver.isThis() && !isQualifiedThis(this.receiver) && this.actualReceiverType.isRole()) {
+ if (this.receiver.isThis() && !receiverIsQualifiedThis() && this.actualReceiverType.isRole()) {
this.actualReceiverType = ((ReferenceBinding)this.actualReceiverType).getRealClass();
if (this.actualReceiverType == null) // happens with true role ifc
this.actualReceiverType = ((ReferenceBinding)this.receiver.resolvedType).getRealType();
@@ -624,7 +624,7 @@
// SH}
//{ObjectTeams: for calls to lower() resolve using internal selector _OT$getBase:
char[] realSelector = this.selector;
- if ( CharOperation.equals(selector, IOTConstants.LOWER)
+ if ( CharOperation.equals(this.selector, IOTConstants.LOWER)
&& this.actualReceiverType.isRole()
&& this.arguments == null
&& this.actualReceiverType.isCompatibleWith(scope.getType(
@@ -864,7 +864,7 @@
} else {
// signature weakening might have produced the wrong returnType.
// check if we must cast this expression to the strengthened version:
- returnType = checkStrengthenReturnType((ReferenceBinding)returnType, scope);
+ returnType = checkStrengthenReturnType(returnType, scope);
}
}
// orig:
@@ -897,14 +897,14 @@
}
//{ObjectTeams: utils:
-private boolean isQualifiedThis(Expression receiver) {
- if (receiver instanceof QualifiedThisReference)
+private boolean receiverIsQualifiedThis() {
+ if (this.receiver instanceof QualifiedThisReference)
return true;
- if (receiver instanceof BaseReference)
- return (((BaseReference)receiver).isQualified());
+ if (this.receiver instanceof BaseReference)
+ return (((BaseReference)this.receiver).isQualified());
return false;
}
-protected boolean isDecapsulationAllowed(Scope scope) {
+public boolean isDecapsulationAllowed(Scope scope) {
// Note: methodScope() may return initializerScope, which has no Method, but the Type as refcontext.
if (scope.methodScope().referenceContext instanceof AbstractMethodDeclaration) {
AbstractMethodDeclaration method = (AbstractMethodDeclaration) scope.methodScope().referenceContext;
@@ -934,7 +934,7 @@
*/
private Expression receiverForAnchorMapping(Scope scope) {
MethodScope methodScope = scope.methodScope();
- if (methodScope != null && methodScope.isCallinWrapper() && this.isCallinRoleMethodCall)
+ if (methodScope != null && methodScope.isCallinWrapper() && this.isPushedOutRoleMethodCall)
return null; // pretend the call target is already "this" = the role.
return this.receiver;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
index 95f96b6..06aaf48 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
@@ -33,7 +33,7 @@
import org.eclipse.objectteams.otdt.core.compiler.ISMAPConstants;
import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBinding;
-import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticBaseCallSurrogate;
+import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticOTMethodBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticRoleFieldAccess;
/**
@@ -2581,8 +2581,8 @@
public void generateSyntheticBodyForMethodAccess(SyntheticMethodBinding accessMethod) {
initializeMaxLocals(accessMethod);
//{ObjectTeams: special treatment for this kind of access method:
- if (accessMethod instanceof SyntheticBaseCallSurrogate) {
- ((SyntheticBaseCallSurrogate)accessMethod).generateInstructions(this);
+ if (accessMethod instanceof SyntheticOTMethodBinding) {
+ ((SyntheticOTMethodBinding)accessMethod).generateInstructions(this);
return;
}
//SH}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
index ca1b422..a88fbe7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
@@ -27,6 +27,7 @@
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.AnchorListAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
+import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticRoleBridgeMethodBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.MethodModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.TeamModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.copyinheritance.CopyInheritance;
@@ -201,6 +202,8 @@
return false;
if (CharOperation.prefixEquals(IOTConstants.OT_SETFIELD, selector))
return false;
+ if (SyntheticRoleBridgeMethodBinding.isPrivateBridgeSelector(selector))
+ return false;
return declaringClass.isRole();
}
/** Implement {@link IProtectable#getDeclaringClass} */
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index 94b96fb..2dfdbb8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -2543,6 +2543,17 @@
if (methodBinding != null) return methodBinding;
methodBinding = findMethod(currentType, selector, argumentTypes, invocationSite);
+//{ObjectTeams: callout to private role method goes through the role class-part:
+ // (will later be replaced by synthetic accessor)
+ if ( methodBinding == null
+ && invocationSite instanceof MessageSend
+ && ((MessageSend)invocationSite).isDecapsulationAllowed(this)
+ && currentType.isRole())
+ {
+ currentType = currentType.getRealClass();
+ methodBinding = findMethod(currentType, selector, argumentTypes, invocationSite);
+ }
+// SH}
if (methodBinding == null)
return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound);
if (!methodBinding.isValidBinding())
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index 23d5e2c..b1b21a4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -46,6 +46,7 @@
import org.eclipse.objectteams.otdt.internal.core.compiler.control.*;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.AnchorMapping;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticBaseCallSurrogate;
+import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticRoleBridgeMethodBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticRoleFieldAccess;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.*;
import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.copyinheritance.CopyInheritance;
@@ -103,8 +104,14 @@
private final static int METHOD_EMUL = 0;
private final static int FIELD_EMUL = 1;
private final static int CLASS_LITERAL_EMUL = 2;
-
+//{ObjectTeams: these bridges are not to be found by addSyntheticMethod(MethodBinding,boolean), use only from callout:
+ private final static int ROLE_BRIDGE = 3;
+
+ private final static int MAX_SYNTHETICS = 4;
+/* orig:
private final static int MAX_SYNTHETICS = 3;
+ :giro */
+// SH}
HashMap[] synthetics;
char[] genericReferenceTypeSignature;
@@ -718,7 +725,8 @@
}
return accessMethod;
}
-//{ObjectTeams: add synthetic (mostly empty) basecall surrogate
+//{ObjectTeams: add OT-specific synthetic bridges:
+// (mostly empty) basecall surrogate
public SyntheticMethodBinding addSyntheticBaseCallSurrogate(MethodBinding callinMethod) {
if (this.synthetics == null)
this.synthetics = new HashMap[MAX_SYNTHETICS];
@@ -739,6 +747,34 @@
}
return accessMethod;
}
+// bridges towards a private role method
+public SyntheticMethodBinding addSyntheticRoleMethodBridge(SourceTypeBinding declaringRole, MethodBinding targetMethod, int bridgeKind) {
+ if (this.synthetics == null)
+ this.synthetics = new HashMap[MAX_SYNTHETICS];
+ if (this.synthetics[SourceTypeBinding.ROLE_BRIDGE] == null)
+ this.synthetics[SourceTypeBinding.ROLE_BRIDGE] = new HashMap(5);
+
+ SyntheticMethodBinding accessMethod = (SyntheticMethodBinding) this.synthetics[SourceTypeBinding.ROLE_BRIDGE].get(targetMethod);
+ if (accessMethod == null) {
+ accessMethod = new SyntheticRoleBridgeMethodBinding(declaringRole, targetMethod, bridgeKind);
+ this.synthetics[SourceTypeBinding.ROLE_BRIDGE].put(targetMethod, accessMethod);
+ }
+ return accessMethod;
+}
+// and retrieve an existing accessor:
+public SyntheticMethodBinding findOuterRoleMethodSyntheticAccessor(MethodBinding targetMethod) {
+ SyntheticMethodBinding accessor;
+ if (this.synthetics != null) {
+ accessor = (SyntheticMethodBinding) this.synthetics[ROLE_BRIDGE].get(targetMethod);
+ if (accessor != null) {
+ if (accessor.isStatic())
+ return ((SourceTypeBinding)enclosingType()).findOuterRoleMethodSyntheticAccessor(accessor);
+ else
+ return accessor;
+ }
+ }
+ return null;
+}
// SH}
/*
* Record the fact that bridge methods need to be generated to override certain inherited methods
@@ -2064,6 +2100,16 @@
return method; // but its still unresolved with a null return type & is still connected to its method declaration
method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
+//{ObjectTeams: need role method bridges?
+ if ( isRole()
+ && ((method.modifiers & ClassFileConstants.AccPrivate) != 0)
+ && !CharOperation.prefixEquals(IOTConstants.OT_DOLLAR_NAME, method.selector)
+ && !methodDecl.isConstructor())
+ {
+ MethodBinding inner = addSyntheticRoleMethodBridge(this, method, SyntheticMethodBinding.RoleMethodBridgeInner);
+ ((SourceTypeBinding) enclosingType()).addSyntheticRoleMethodBridge(this, inner, SyntheticMethodBinding.RoleMethodBridgeOuter);
+ }
+// SH}
return method;
}
//{ObjectTeams: helper to find args allowing baseclass decapsulation:
@@ -2317,6 +2363,8 @@
}
public SyntheticMethodBinding[] syntheticMethods() {
+//{ObjectTeams: two different kinds of synthetics:
+/* orig:
if (this.synthetics == null
|| this.synthetics[SourceTypeBinding.METHOD_EMUL] == null
|| this.synthetics[SourceTypeBinding.METHOD_EMUL].size() == 0) {
@@ -2325,6 +2373,13 @@
// difficult to compute size up front because of the embedded arrays so assume there is only 1
int index = 0;
SyntheticMethodBinding[] bindings = new SyntheticMethodBinding[1];
+ :giro */
+ if (this.synthetics == null) return null;
+ int index = 0;
+ SyntheticMethodBinding[] bindings = new SyntheticMethodBinding[1];
+ if (this.synthetics[SourceTypeBinding.METHOD_EMUL] != null && this.synthetics[METHOD_EMUL].size() > 0)
+ {
+//orig:
Iterator methodArrayIterator = this.synthetics[SourceTypeBinding.METHOD_EMUL].values().iterator();
while (methodArrayIterator.hasNext()) {
SyntheticMethodBinding[] methodAccessors = (SyntheticMethodBinding[]) methodArrayIterator.next();
@@ -2337,6 +2392,25 @@
}
}
}
+ }
+// :giro
+// more synthetics to generate:
+ if (this.synthetics[SourceTypeBinding.ROLE_BRIDGE] != null && this.synthetics[SourceTypeBinding.ROLE_BRIDGE].size() > 0)
+ {
+ Iterator methodArrayIterator = this.synthetics[SourceTypeBinding.ROLE_BRIDGE].values().iterator();
+ while (methodArrayIterator.hasNext()) {
+ SyntheticMethodBinding methodAccessor = (SyntheticMethodBinding) methodArrayIterator.next();
+ if (methodAccessor != null) {
+ if (index+1 > bindings.length) {
+ System.arraycopy(bindings, 0, (bindings = new SyntheticMethodBinding[index + 1]), 0, index);
+ }
+ bindings[index++] = methodAccessor;
+ }
+ }
+ }
+ if (index == 0)
+ return null; // nothing found
+// SH}
// sort them in according to their own indexes
int length;
SyntheticMethodBinding[] sortedBindings = new SyntheticMethodBinding[length = bindings.length];
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
index e20c982..52e1ecf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
@@ -49,8 +49,10 @@
public final static int EnumValues = 9; // enum #values()
public final static int EnumValueOf = 10; // enum #valueOf(String)
public final static int SwitchTable = 11; // switch table method
-//{ObjectTeams: another purpose:
+//{ObjectTeams: other purposes:
public final static int InferredCalloutToField = 12; // calling an inferred callout-to-field
+ public final static int RoleMethodBridgeOuter = 13; // a team-level bridge method towards a private role method (for callout)
+ public final static int RoleMethodBridgeInner = 14; // a role-level bridge method towards a private role method (for callout)
// SH}
public int sourceStart = 0; // start position of the matching declaration
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/BaseAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/BaseAllocationExpression.java
index edc12fc..bfd9cbf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/BaseAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/BaseAllocationExpression.java
@@ -159,7 +159,7 @@
MessageSend allocSend = new MessageSend() {
@Override
- protected boolean isDecapsulationAllowed(Scope scope2) {
+ public boolean isDecapsulationAllowed(Scope scope2) {
// this message send can decapsulate independent of scope
return true;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lookup/SyntheticBaseCallSurrogate.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lookup/SyntheticBaseCallSurrogate.java
index 9fe2bba..7f9b664 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lookup/SyntheticBaseCallSurrogate.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lookup/SyntheticBaseCallSurrogate.java
@@ -47,7 +47,7 @@
* @author stephan
* @since 1.3.0
*/
-public class SyntheticBaseCallSurrogate extends SyntheticMethodBinding
+public class SyntheticBaseCallSurrogate extends SyntheticOTMethodBinding
{
// this corresponds to IOTConstants.OT_DOLLAR_NAME without the trailing '$':
private static final char[] _OT = "_OT".toCharArray(); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lookup/SyntheticOTMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lookup/SyntheticOTMethodBinding.java
new file mode 100644
index 0000000..4c26576
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lookup/SyntheticOTMethodBinding.java
@@ -0,0 +1,33 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ *
+ * Copyright 2010 GK Software AG
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * $Id$
+ *
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ *
+ * Contributors:
+ * Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.core.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public abstract class SyntheticOTMethodBinding extends SyntheticMethodBinding {
+
+ public SyntheticOTMethodBinding(SourceTypeBinding declaringClass, int modifiers, char[] selector, TypeBinding[] parameters, TypeBinding returnType)
+ {
+ super(declaringClass, modifiers, selector, parameters, returnType);
+ }
+
+ public abstract void generateInstructions(CodeStream codeStream);
+
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lookup/SyntheticRoleBridgeMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lookup/SyntheticRoleBridgeMethodBinding.java
new file mode 100644
index 0000000..23a6fed
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lookup/SyntheticRoleBridgeMethodBinding.java
@@ -0,0 +1,171 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ *
+ * Copyright 2010 GK Software AG
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * $Id$
+ *
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ *
+ * Contributors:
+ * Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.core.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
+import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstConverter;
+import org.eclipse.objectteams.otdt.internal.core.compiler.util.TypeAnalyzer;
+
+public class SyntheticRoleBridgeMethodBinding extends SyntheticOTMethodBinding {
+
+ public SyntheticRoleBridgeMethodBinding(SourceTypeBinding declaringRole, MethodBinding targetMethod, int bridgeKind) {
+ super(declaringRole, ClassFileConstants.AccPublic|ClassFileConstants.AccSynthetic, targetMethod.selector, targetMethod.parameters, targetMethod.returnType);
+ this.purpose = bridgeKind;
+ switch (bridgeKind) {
+ case RoleMethodBridgeOuter:
+ // correction: this method sits in the team not the role:
+ this.declaringClass = declaringRole.enclosingType();
+ break;
+ case RoleMethodBridgeInner:
+ // correction: add role as first parameter:
+ int len = targetMethod.parameters.length;
+ int offset = targetMethod.isStatic()?2:0;
+ this.parameters = new TypeBinding[len+1+offset];
+ this.parameters[0] = declaringRole.getRealType();
+ if (offset > 0) {
+ this.parameters[1] = TypeBinding.INT; // dummy int
+ this.parameters[2] = declaringRole.enclosingType(); // team arg
+ }
+ System.arraycopy(targetMethod.parameters, 0, this.parameters, 1+offset, len);
+ // correction: this bridge is static:
+ this.modifiers |= ClassFileConstants.AccStatic;
+ // correction: generate the bridge method name:
+ this.selector = SyntheticRoleBridgeMethodBinding.getPrivateBridgeSelector(targetMethod.selector, declaringRole.sourceName());
+ break;
+ }
+ this.targetMethod = targetMethod;
+ this.thrownExceptions = targetMethod.thrownExceptions;
+ this.typeVariables = targetMethod.typeVariables;
+ SyntheticMethodBinding[] knownAccessMethods = ((SourceTypeBinding) this.declaringClass).syntheticMethods();
+ int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
+ this.index = methodId;
+ }
+
+ @Override
+ public void generateInstructions(CodeStream codeStream) {
+ TypeBinding[] arguments = this.parameters;
+ int argLen = arguments.length;
+ TypeBinding[] targetParameters = this.targetMethod.parameters;
+ int resolvedPosition = 0;
+ int argIdx = 0;
+ int targetIdx = 0;
+ switch (this.purpose) {
+ case RoleMethodBridgeInner:
+ codeStream.aload_0(); // synthetic first arg is the receiver role
+ codeStream.checkcast(this.targetMethod.declaringClass);
+ resolvedPosition = 1; // first arg is processed
+ argIdx = 1;
+ if (this.targetMethod.isStatic()) {
+ codeStream.iconst_0(); // dummy int
+ codeStream.aload_2(); // pass synth. team arg
+ argIdx += 2;
+ resolvedPosition += 2;
+ }
+ break;
+ case RoleMethodBridgeOuter:
+ resolvedPosition = 1; // ignore team instance at 0
+ argIdx = 0; // pass all args unchanged
+ break;
+ }
+ while (argIdx < argLen) {
+ TypeBinding parameter = targetParameters[targetIdx++];
+ TypeBinding argument = arguments[argIdx++];
+ codeStream.load(argument, resolvedPosition);
+ if (argument != parameter)
+ codeStream.checkcast(parameter);
+ switch(parameter.id) {
+ case TypeIds.T_long :
+ case TypeIds.T_double :
+ resolvedPosition += 2;
+ break;
+ default :
+ resolvedPosition++;
+ break;
+ }
+ }
+ switch (this.purpose) {
+ case RoleMethodBridgeInner :
+ // call the private role method
+ codeStream.invoke(Opcodes.OPC_invokespecial, this.targetMethod, null);
+ break;
+ case RoleMethodBridgeOuter :
+ // call the static role method bridge:
+ codeStream.invoke(Opcodes.OPC_invokestatic, this.targetMethod, null);
+ break;
+ }
+ switch (this.targetMethod.returnType.id) {
+ case TypeIds.T_void :
+ codeStream.return_();
+ break;
+ case TypeIds.T_boolean :
+ case TypeIds.T_byte :
+ case TypeIds.T_char :
+ case TypeIds.T_short :
+ case TypeIds.T_int :
+ codeStream.ireturn();
+ break;
+ case TypeIds.T_long :
+ codeStream.lreturn();
+ break;
+ case TypeIds.T_float :
+ codeStream.freturn();
+ break;
+ case TypeIds.T_double :
+ codeStream.dreturn();
+ break;
+ default :
+ codeStream.areturn();
+ }
+ }
+
+ public static char[] getPrivateBridgeSelector(char[] selector, char[] roleName) {
+ return CharOperation.concat(
+ CharOperation.concat(IOTConstants.OT_DOLLAR_NAME, roleName),
+ CharOperation.concat(AstConverter.PRIVATE, selector));
+ }
+
+ public static boolean isPrivateBridgeSelector(char[] selector) {
+ if (!CharOperation.prefixEquals(IOTConstants.OT_DOLLAR_NAME, selector))
+ return false;
+ return CharOperation.indexOf(AstConverter.PRIVATE, selector, true, IOTConstants.OT_DOLLAR_LEN) > -1;
+ }
+
+ public static MethodBinding findOuterAccessor(Scope scope, ReferenceBinding roleType, MethodBinding targetMethod) {
+ ReferenceBinding roleClass = roleType.getRealClass();
+ if (roleClass instanceof SourceTypeBinding)
+ return ((SourceTypeBinding)roleClass).findOuterRoleMethodSyntheticAccessor(targetMethod);
+ // for binary type find it in the team's regular methods:
+ int len = targetMethod.parameters.length;
+ TypeBinding[] extendedParamters = new TypeBinding[len+1];
+ extendedParamters[0] = roleType;
+ System.arraycopy(targetMethod.parameters, 0, extendedParamters, 1, len);
+ char[] selector = getPrivateBridgeSelector(targetMethod.selector, roleType.sourceName());
+ return TypeAnalyzer.findMethod(scope, roleType.enclosingType(), selector, extendedParamters);
+ }
+
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementor.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementor.java
index 2f533d7..73822b0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementor.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementor.java
@@ -585,7 +585,7 @@
// ------------- the role message send:
MessageSend roleMessageSend = gen.messageSend(receiver, roleMethodName, messageSendArguments);
- roleMessageSend.isCallinRoleMethodCall = true;
+ roleMessageSend.isPushedOutRoleMethodCall = true;
// ---------------- store or ignore the result:
if ( callinBindingDeclaration.isReplaceCallin())
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementorDyn.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementorDyn.java
index 36ca4b5..6ac87a4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementorDyn.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CallinImplementorDyn.java
@@ -420,7 +420,7 @@
}
// -- assemble the method call:
MessageSend roleMethodCall = gen.messageSend(receiver, callinDecl.roleMethodSpec.selector, callArgs);
- roleMethodCall.isCallinRoleMethodCall = true;
+ roleMethodCall.isPushedOutRoleMethodCall = true;
if (isReplace) {
blockStatements[statIdx] = gen.returnStatement(roleMethodCall);
} else {
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 e174c7d..3b4f72f 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
@@ -77,6 +77,7 @@
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.RoleTypeBinding;
+import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticRoleBridgeMethodBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.TThisBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.WeakenedTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.FieldModel;
@@ -85,7 +86,6 @@
import org.eclipse.objectteams.otdt.internal.core.compiler.model.TeamModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.AbstractStatementsGenerator;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstClone;
-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.IProtectable;
@@ -547,7 +547,7 @@
// because the method body is a call to the method specific by the spec.
sStart = calloutDecl.baseMethodSpec.sourceStart;
sEnd = calloutDecl.baseMethodSpec.sourceEnd;
- AstGenerator gen = new AstGenerator(sStart, sEnd);
+ final AstGenerator gen = new AstGenerator(sStart, sEnd);
Expression receiver;
char[] selector = calloutDecl.baseMethodSpec.selector;
@@ -560,6 +560,7 @@
gen.baseclassReference(baseType),
CastExpression.DO_WRAP);
+ MessageSend messageSend;
if (calloutDecl.baseMethodSpec.isPrivate() && baseType.isRole()) {
// tricky case: callout to a private role method (base-side)
// requires the indirection via two wrapper methods (privateBridgeMethod)
@@ -571,30 +572,43 @@
// generated message send refers to public bridge, report decapsulation now:
calloutDecl.scope.problemReporter().decapsulation(calloutDecl.baseMethodSpec, baseType, calloutDecl.scope);
- // determine the receiver: convert the team anchor into an expression
- receiver = gen.typeAnchorReference(((RoleTypeBinding)baseType)._teamAnchor);
- ((TypeAnchorReference)receiver).isExpression = true;
+// if (!(calloutDecl.baseMethodSpec instanceof FieldAccessSpec)) {
+// // one more argument: the base instance:
+// int len = arguments.length;
+// System.arraycopy(arguments, 0,
+// arguments = new Expression[len+1], 1,
+// len);
+// }
+// // add to front (callout-to-method), or simply replace (callout-to-field) first arg:
+// arguments[0] = gen.baseNameReference(IOTConstants._OT_BASE);
- // now get the bridge method (at the base-side team)
- selector = AstConverter.getPrivateBridgeSelector(selector, baseType.sourceName());
+ messageSend = new MessageSend() {
+ @Override
+ public void generateCode(org.eclipse.jdt.internal.compiler.lookup.BlockScope currentScope, org.eclipse.jdt.internal.compiler.codegen.CodeStream codeStream, boolean valueRequired) {
+ // manually redirect to synth bridge:
+ // new receiver is the anchor denoting the base role's enclosing team instance:
+ TypeAnchorReference syntheticReceiver = gen.typeAnchorReference(((RoleTypeBinding)this.actualReceiverType)._teamAnchor);
+ syntheticReceiver.isExpression = true;
+ syntheticReceiver.resolve(currentScope);
+ syntheticReceiver.generateCode(currentScope, codeStream, true/*valueRequired*/);
+ // directly use the accessor and its declaring class for the invoke instruction:
+ this.binding = this.syntheticAccessor;
+ this.actualReceiverType = this.syntheticAccessor.declaringClass;
+ this.syntheticAccessor = null;
+ super.generateCode(currentScope, codeStream, valueRequired);
+ }
+ };
+ MethodBinding targetMethod = calloutDecl.baseMethodSpec.resolvedMethod;
+ messageSend.syntheticAccessor = SyntheticRoleBridgeMethodBinding.findOuterAccessor(calloutDecl.scope, baseType, targetMethod);
+ messageSend.receiver = receiver;
+ messageSend.selector = selector;
+ messageSend.arguments = arguments;
+ messageSend.sourceStart = sStart;
+ messageSend.sourceEnd = sEnd;
+ } else {
- if (!(calloutDecl.baseMethodSpec instanceof FieldAccessSpec)) {
- // one more argument: the base instance:
- int len = arguments.length;
- System.arraycopy(arguments, 0,
- arguments = new Expression[len+1], 1,
- len);
- }
- // add to front (callout-to-method), or simply replace (callout-to-field) first arg:
- arguments[0] = gen.baseNameReference(IOTConstants._OT_BASE);
+ messageSend = gen.messageSend(receiver, selector, arguments);
}
-
- MessageSend messageSend = gen.messageSend
- (
- receiver,
- selector,
- arguments
- );
// TODO(SH): create receiver via gen, too.
messageSend.receiver.sourceStart = sStart;
messageSend.receiver.sourceEnd = sEnd;
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 57bd8e9..d109903 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
@@ -91,6 +91,7 @@
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.DependentTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticBaseCallSurrogate;
+import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticRoleBridgeMethodBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticRoleFieldAccess;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.WeakenedTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.MethodModel;
@@ -877,6 +878,8 @@
// some, but not all, synthetics shall be generated with strong signatures as indicated by 'site':
if (!SyntheticBaseCallSurrogate.isBaseCallSurrogateName(method.selector))
site = targetRoleDecl.binding;
+ if (SyntheticRoleBridgeMethodBinding.isPrivateBridgeSelector(method.selector))
+ return; // will be generated anew
}
if (TypeContainerMethod.isTypeContainer(method))
@@ -1035,25 +1038,6 @@
newMethodDecl.isMappingWrapper = WrapperKind.CALLIN;
if (methodFound == null) {
- if ( method.isPrivate() // private role methods need special preparation for callout:
- && !CharOperation.prefixEquals(IOTConstants.OT_DOLLAR_NAME, method.selector)
- && !method.isConstructor()
- && !targetRoleDecl.isInterface())
- {
- // re-create (override) bridge methods which are _not_ copied (fake methods):
- AstEdit.addMethod(targetTeamDecl,
- AstConverter.genBridgeForPrivateRoleMethod(targetTeamDecl,
- targetRoleDecl,
- srcRole.sourceName(),
- (MethodDeclaration)newMethodDecl,
- /*teamPart*/true));
- AstEdit.addMethod(targetRoleDecl,
- AstConverter.genBridgeForPrivateRoleMethod(targetTeamDecl,
- targetRoleDecl,
- srcRole.sourceName(),
- (MethodDeclaration)newMethodDecl,
- /*teamPart*/false));
- }
// copy down some more properties:
if (TSuperHelper.isTSuper(method))
newMethodDecl.isTSuper = true;
@@ -1149,20 +1133,6 @@
srcMethod.resolveTypes();
srcMethod.resolvedField();
copySyntheticMethod(srcMethod, tgtTeamDecl, tgtTeamDecl);
- } else if (AstConverter.isPrivateBridgeSelector(method.selector)) {
- TypeBinding roleType = TeamModel.strengthenRoleType(tgtTeamDecl.binding, method.parameters[0]);
- // need to create team part of a bridge to a binary (re-used) role?
- if (roleType instanceof ReferenceBinding && ((ReferenceBinding)roleType).isBinaryBinding()) {
- // _OT$Role$private$selector <- pick selector (may contain more $s)
- int start = CharOperation.indexOf('$', method.selector, IOTConstants.OT_DOLLAR_LEN)+AstConverter.PRIVATE.length;
- char[] targetSelector = CharOperation.subarray(method.selector, start, -1);
- if (CharOperation.prefixEquals(IOTConstants.OT_GETFIELD, targetSelector))
- ; // FIXME(SH): implement copying bridge to fieldget
- else if (CharOperation.prefixEquals(IOTConstants.OT_SETFIELD, targetSelector))
- ; // FIXME(SH): implement copying bridge to fieldset
- else
- copyPrivateRoleMethodBridge(tgtTeamDecl, roleType, method, targetSelector);
- }
}
}
}
@@ -1177,33 +1147,6 @@
if (dstMethod != null)
tgtRoleModel.addSyntheticMethodMapping(srcMethod, dstMethod);
}
-
- private static void copyPrivateRoleMethodBridge(TypeDeclaration tgtTeamDecl, TypeBinding roleType, MethodBinding superMethod, char[] targetSelector)
- {
- ReferenceBinding tgtTeam = tgtTeamDecl.binding;
- AstGenerator gen = new AstGenerator(tgtTeamDecl);
- gen.replaceableEnclosingClass = tgtTeam; // like during copyMethod
-
- MethodDeclaration newMethodDecl = (MethodDeclaration)AstConverter.createMethod(superMethod,
- tgtTeam,
- tgtTeamDecl.compilationResult,
- DecapsulationState.REPORTED,
- gen);
- // we will *not* copy byte code:
- newMethodDecl.isCopied = false;
-
- // but generate AST:
- newMethodDecl.arguments[0].name = AstConverter.ROLE_ARG_NAME;
- AstConverter.genPrivateRoleMethodBridgeStatements(targetSelector,
- false, // isStatic is irrelevant for team part
- superMethod.parameters.length-1, // source args len not including role arg
- newMethodDecl,
- roleType.sourceName(),
- true, // teamPart
- gen);
-
- AstEdit.addMethod(tgtTeamDecl, newMethodDecl, false/*wasSynthetic*/, false/*addToFront*/);
- }
/**
* Copy a synthetic access method to `tgtTypeDecl'.
@@ -1267,6 +1210,9 @@
if (dstMethod == null)
tgtTypeDecl.scope.problemReporter().abortDueToInternalError("Expected synthetic bridge method does not exist: "+new String(srcMethod.readableName())); //$NON-NLS-1$
break;
+ case SyntheticMethodBinding.RoleMethodBridgeInner:
+ case SyntheticMethodBinding.RoleMethodBridgeOuter:
+ return null; // not copied but generated anew
default:
tgtTypeDecl.scope.problemReporter().abortDueToInternalError("Synthetic methods only partially supported"); //$NON-NLS-1$
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/RoleSplitter.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/RoleSplitter.java
index 96e3b8a..d9bcad1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/RoleSplitter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/RoleSplitter.java
@@ -204,24 +204,6 @@
newmethod.binding.tagBits |= TagBits.AnnotationDeprecated;
}
}});
- } else {
- // private methods add a wrapper chain to team/role:
- final MethodDeclaration bridge1 = AstConverter.genBridgeForPrivateRoleMethod(
- teamDecl, roleClassDecl, roleIfcDecl.name, method, true);
- AstEdit.addMethodDeclOnly(teamDecl, bridge1, false);
- if (teamDecl.binding != null && bridge1.binding == null)
- roleIfcDecl.getRoleModel()._state.addJob(ITranslationStates.STATE_ROLES_LINKED,
- new Runnable() { public void run() {
- teamDecl.binding.resolveGeneratedMethod(bridge1, false);
- }});
- final MethodDeclaration bridge2 = AstConverter.genBridgeForPrivateRoleMethod(
- teamDecl, roleClassDecl, roleIfcDecl.name, method, false);
- AstEdit.addMethodDeclOnly(roleClassDecl, bridge2, false);
- if (teamDecl.binding != null && bridge2.binding == null)
- roleClassDecl.getRoleModel()._state.addJob(ITranslationStates.STATE_ROLES_LINKED,
- new Runnable() { public void run() {
- roleClassDecl.binding.resolveGeneratedMethod(bridge2, false);
- }});
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstConverter.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstConverter.java
index 242d939..b496b00 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstConverter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstConverter.java
@@ -69,10 +69,10 @@
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;
-import org.eclipse.objectteams.otdt.internal.core.compiler.ast.LiftingTypeReference;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.ConstantPoolObjectMapper;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.AnchorMapping;
+import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticRoleBridgeMethodBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.MethodModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.MethodModel.FakeKind;
@@ -489,129 +489,6 @@
return newmethod;
}
- public static char[] getPrivateBridgeSelector(char[] selector, char[] roleName) {
- return CharOperation.concat(
- CharOperation.concat(OT_DOLLAR_NAME, roleName),
- CharOperation.concat(PRIVATE, selector));
- }
-
- public static boolean isPrivateBridgeSelector(char[] selector) {
- if (!CharOperation.prefixEquals(OT_DOLLAR_NAME, selector))
- return false;
- return CharOperation.indexOf(PRIVATE, selector, true, OT_DOLLAR_LEN) > -1;
- }
-
- /**
- * Generate a method that bridges from a callout to a private role method.
- * @param teamDecl
- * @param roleName
- * @param privateRoleMethod
- * @param teamPart select whether the team part should be created or the role part.
- * @return the new method.
- */
- public static MethodDeclaration genBridgeForPrivateRoleMethod(TypeDeclaration teamDecl,
- TypeDeclaration roleDecl,
- char[] roleName,
- MethodDeclaration privateRoleMethod,
- boolean teamPart)
- {
- // teamMeth looks like this (delegates to role method below):
- // public T MyTeam._OT$R$private$m(R _OT$role, args) {
- // [return] __OT__R._OT$R$private$m(_OT$role, args);
- // }
-
- // roleMeth looks like this (delegates to original private method):
- // public static T _OT$R$private$m(R _OT$role, args) {
- // [return] ((__OT__R)_OT$role).m(args);
- // }
-
- AstGenerator gen = (teamPart && roleDecl.isRoleFile())
- ? new AstGenerator(teamDecl.sourceStart, teamDecl.sourceEnd) // have no better position
- : new AstGenerator(privateRoleMethod.sourceStart, privateRoleMethod.sourceEnd);
-
- MethodDeclaration meth = AstClone.copyMethod(teamPart?teamDecl:roleDecl, privateRoleMethod, gen);
-
- meth.modifiers = AccPublic;
- if (!teamPart)
- meth.modifiers |= AccStatic;
-
- meth.selector = getPrivateBridgeSelector(meth.selector, roleName);
-
- // add role argument to front of arguments:
- int len = 0;
- if (meth.arguments != null) {
- len = meth.arguments.length;
- System.arraycopy(meth.arguments, 0,
- meth.arguments = new Argument[len+1], 1,
- len);
- for (int i=1; i < len+1; i++)
- if (meth.arguments[i].type instanceof LiftingTypeReference) // defer the declared lifting to the original method
- meth.arguments[i].type = AstClone.copyTypeReference(((LiftingTypeReference)meth.arguments[i].type).baseReference);
- } else {
- meth.arguments = new Argument[1];
- }
- meth.arguments[0] = gen.argument(ROLE_ARG_NAME, gen.singleTypeReference(roleName), AccFinal);
-
- if (!roleDecl.isConverted) {
- genPrivateRoleMethodBridgeStatements(privateRoleMethod.selector, privateRoleMethod.isStatic(), len, meth, roleName, teamPart, gen);
- meth.hasParsedStatements = true;
- }
- MethodModel model = MethodModel.getModel(meth);
- model._fakeKind= FakeKind.ROLE_FEATURE_BRIDGE;
- model._thisSubstitution = meth.arguments[0];
- if (teamPart)
- model._sourceDeclaringType = roleDecl;
- return meth;
- }
-
- public static void genPrivateRoleMethodBridgeStatements (char[] selector,
- boolean isStatic, // irrelevant for team part
- int srcArgsLen,
- MethodDeclaration bridgeMethod,
- char[] roleName,
- boolean isTeamPart,
- AstGenerator gen)
- {
- char[] roleClassName = CharOperation.concat(OT_DELIM_NAME, roleName);
-
- int offset = 0; // into call arguments (0 or 1)
- Expression receiver;
- if (isTeamPart) {
- receiver = gen.singleNameReference(roleClassName); // __OT__R.
- selector = bridgeMethod.selector; // _OT$R$private$m
- offset = 1; // call arguments include role arg
- } else {
- if (isStatic)
- receiver = gen.singleNameReference(roleClassName); // __OT__R.
- else
- receiver = gen.castExpression( // ((__OT__R)_OT$role).
- gen.singleNameReference(ROLE_ARG_NAME),
- gen.singleTypeReference(roleClassName),
- CastExpression.RAW);
- // plain call arguments (no offset)
- }
-
- // call params differ (according to offset)
- Expression[] params = new Expression[srcArgsLen+offset];
- for (int i=0; i<srcArgsLen; i++)
- params[i+offset] = gen.singleNameReference(bridgeMethod.arguments[i+1].name);
- if (offset == 1)
- params[0] = gen.singleNameReference(ROLE_ARG_NAME);
-
- // assemble call:
- Expression call = gen.messageSend(receiver, selector, params);
-
-
- if ( bridgeMethod.returnType instanceof SingleTypeReference
- && CharOperation.equals(((SingleTypeReference)bridgeMethod.returnType).token,
- TypeConstants.VOID))
- {
- bridgeMethod.statements = new Statement[]{ call };
- } else {
- bridgeMethod.statements = new Statement[]{ gen.returnStatement(call) };
- }
- }
-
/**
* Generate a method that bridges from a callout to a private role field.
* @param teamDecl
@@ -650,7 +527,7 @@
isGetter ?
fieldTypeRef
: gen.typeReference(TypeBinding.VOID),
- getPrivateBridgeSelector(accessorSelector, roleName),
+ SyntheticRoleBridgeMethodBinding.getPrivateBridgeSelector(accessorSelector, roleName),
isGetter ?
new Argument[] {
roleArg,
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/RoleTypeCreator.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/RoleTypeCreator.java
index f6662bd..9f1be43 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/RoleTypeCreator.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/RoleTypeCreator.java
@@ -327,7 +327,7 @@
{
AbstractMethodDeclaration referenceMethod = scope.methodScope().referenceMethod();
if (referenceMethod != null)
- isCalloutGet &= (referenceMethod.isMappingWrapper == AbstractMethodDeclaration.WrapperKind.CALLOUT);
+ isCalloutGet &= (referenceMethod.isMappingWrapper.callout());
}
if (!isCalloutGet) {
if (refReturn instanceof WeakenedTypeBinding) {
@@ -533,8 +533,7 @@
MethodScope methodScope = scope.methodScope();
if ( methodScope != null
&& methodScope.referenceMethod() != null
- && methodScope.referenceMethod().isMappingWrapper
- == AbstractMethodDeclaration.WrapperKind.CALLIN
+ && methodScope.referenceMethod().isMappingWrapper._callin()
//{OTDyn
&& !CallinImplementorDyn.DYNAMIC_WEAVING) // this heuristic doesn't work for dyn weaving, FIXME(SH): check if still needed!
// SH}