List of usage examples for org.eclipse.jdt.internal.compiler.lookup TypeBinding INT
BaseTypeBinding INT
To view the source code for org.eclipse.jdt.internal.compiler.lookup TypeBinding INT.
Click Source Link
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
public static TypeBinding getBaseType(char[] name) { // list should be optimized (with most often used first) int length = name.length; if (length > 2 && length < 8) { switch (name[0]) { case 'i': if (length == 3 && name[1] == 'n' && name[2] == 't') return TypeBinding.INT; break; case 'v': if (length == 4 && name[1] == 'o' && name[2] == 'i' && name[3] == 'd') return TypeBinding.VOID; break; case 'b': if (length == 7 && name[1] == 'o' && name[2] == 'o' && name[3] == 'l' && name[4] == 'e' && name[5] == 'a' && name[6] == 'n') return TypeBinding.BOOLEAN; if (length == 4 && name[1] == 'y' && name[2] == 't' && name[3] == 'e') return TypeBinding.BYTE; break; case 'c': if (length == 4 && name[1] == 'h' && name[2] == 'a' && name[3] == 'r') return TypeBinding.CHAR; break; case 'd': if (length == 6 && name[1] == 'o' && name[2] == 'u' && name[3] == 'b' && name[4] == 'l' && name[5] == 'e') return TypeBinding.DOUBLE; break; case 'f': if (length == 5 && name[1] == 'l' && name[2] == 'o' && name[3] == 'a' && name[4] == 't') return TypeBinding.FLOAT; break; case 'l': if (length == 4 && name[1] == 'o' && name[2] == 'n' && name[3] == 'g') return TypeBinding.LONG; break; case 's': if (length == 5 && name[1] == 'h' && name[2] == 'o' && name[3] == 'r' && name[4] == 't') return TypeBinding.SHORT; }/*from w w w .ja v a2 s . c o m*/ } return null; }
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
private TypeBinding leastContainingTypeArgument(TypeBinding u, TypeBinding v, ReferenceBinding genericType, int rank, List lubStack) { if (u == null) return v; if (u == v)//from www .j av a2 s . c om return u; if (v.isWildcard()) { WildcardBinding wildV = (WildcardBinding) v; if (u.isWildcard()) { WildcardBinding wildU = (WildcardBinding) u; switch (wildU.boundKind) { // ? extends U case Wildcard.EXTENDS: switch (wildV.boundKind) { // ? extends U, ? extends V case Wildcard.EXTENDS: TypeBinding lub = lowerUpperBound(new TypeBinding[] { wildU.bound, wildV.bound }, lubStack); if (lub == null) return null; // int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND); return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS); // ? extends U, ? SUPER V case Wildcard.SUPER: if (wildU.bound == wildV.bound) return wildU.bound; return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND); } break; // ? super U case Wildcard.SUPER: // ? super U, ? super V if (wildU.boundKind == Wildcard.SUPER) { TypeBinding[] glb = greaterLowerBound(new TypeBinding[] { wildU.bound, wildV.bound }); if (glb == null) return null; return environment().createWildcard(genericType, rank, glb[0], null /*no extra bound*/, Wildcard.SUPER); // TODO (philippe) need to capture entire bounds } } } else { switch (wildV.boundKind) { // U, ? extends V case Wildcard.EXTENDS: TypeBinding lub = lowerUpperBound(new TypeBinding[] { u, wildV.bound }, lubStack); if (lub == null) return null; // int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND); return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS); // U, ? super V case Wildcard.SUPER: TypeBinding[] glb = greaterLowerBound(new TypeBinding[] { u, wildV.bound }); if (glb == null) return null; return environment().createWildcard(genericType, rank, glb[0], null /*no extra bound*/, Wildcard.SUPER); // TODO (philippe) need to capture entire bounds case Wildcard.UNBOUND: } } } else if (u.isWildcard()) { WildcardBinding wildU = (WildcardBinding) u; switch (wildU.boundKind) { // U, ? extends V case Wildcard.EXTENDS: TypeBinding lub = lowerUpperBound(new TypeBinding[] { wildU.bound, v }, lubStack); if (lub == null) return null; // int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND); return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS); // U, ? super V case Wildcard.SUPER: TypeBinding[] glb = greaterLowerBound(new TypeBinding[] { wildU.bound, v }); if (glb == null) return null; return environment().createWildcard(genericType, rank, glb[0], null /*no extra bound*/, Wildcard.SUPER); // TODO (philippe) need to capture entire bounds case Wildcard.UNBOUND: } } TypeBinding lub = lowerUpperBound(new TypeBinding[] { u, v }, lubStack); if (lub == null) return null; // int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND); return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS); }
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
private TypeBinding lowerUpperBound(TypeBinding[] types, List lubStack) { int typeLength = types.length; if (typeLength == 1) { TypeBinding type = types[0];/*from ww w . ja v a2 s .c om*/ return type == null ? TypeBinding.VOID : type; } // cycle detection int stackLength = lubStack.size(); nextLubCheck: for (int i = 0; i < stackLength; i++) { TypeBinding[] lubTypes = (TypeBinding[]) lubStack.get(i); int lubTypeLength = lubTypes.length; if (lubTypeLength < typeLength) continue nextLubCheck; nextTypeCheck: for (int j = 0; j < typeLength; j++) { TypeBinding type = types[j]; if (type == null) continue nextTypeCheck; // ignore for (int k = 0; k < lubTypeLength; k++) { TypeBinding lubType = lubTypes[k]; if (lubType == null) continue; // ignore if (lubType == type || lubType.isEquivalentTo(type)) continue nextTypeCheck; // type found, jump to next one } continue nextLubCheck; // type not found in current lubTypes } // all types are included in some lub, cycle detected - stop recursion by answering special value (int) return TypeBinding.INT; } lubStack.add(types); Map invocations = new HashMap(1); TypeBinding[] mecs = minimalErasedCandidates(types, invocations); if (mecs == null) return null; int length = mecs.length; if (length == 0) return TypeBinding.VOID; int count = 0; TypeBinding firstBound = null; int commonDim = -1; for (int i = 0; i < length; i++) { TypeBinding mec = mecs[i]; if (mec == null) continue; mec = leastContainingInvocation(mec, invocations.get(mec), lubStack); if (mec == null) return null; int dim = mec.dimensions(); if (commonDim == -1) { commonDim = dim; } else if (dim != commonDim) { // not all types have same dimension return null; } if (firstBound == null && !mec.leafComponentType().isInterface()) firstBound = mec.leafComponentType(); mecs[count++] = mec; // recompact them to the front } switch (count) { case 0: return TypeBinding.VOID; case 1: return mecs[0]; case 2: if ((commonDim == 0 ? mecs[1].id : mecs[1].leafComponentType().id) == TypeIds.T_JavaLangObject) return mecs[0]; if ((commonDim == 0 ? mecs[0].id : mecs[0].leafComponentType().id) == TypeIds.T_JavaLangObject) return mecs[1]; } TypeBinding[] otherBounds = new TypeBinding[count - 1]; int rank = 0; for (int i = 0; i < count; i++) { TypeBinding mec = commonDim == 0 ? mecs[i] : mecs[i].leafComponentType(); if (mec.isInterface()) { otherBounds[rank++] = mec; } } TypeBinding intersectionType = environment().createWildcard(null, 0, firstBound, otherBounds, Wildcard.EXTENDS); return commonDim == 0 ? intersectionType : environment().createArrayType(intersectionType, commonDim); }
From source file:org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.java
License:Open Source License
public SyntheticFieldBinding addSyntheticFieldForSwitchEnum(char[] fieldName, String key) { if (this.synthetics == null) this.synthetics = new HashMap[MAX_SYNTHETICS]; if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null) this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap(5); SyntheticFieldBinding synthField = (SyntheticFieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL] .get(key);// w ww . j a v a 2 s .c o m if (synthField == null) { synthField = new SyntheticFieldBinding(fieldName, this.scope.createArrayType(TypeBinding.INT, 1), ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic, this, Constant.NotAConstant, this.synthetics[SourceTypeBinding.FIELD_EMUL].size()); this.synthetics[SourceTypeBinding.FIELD_EMUL].put(key, synthField); } // ensure there is not already such a field defined by the user boolean needRecheck; int index = 0; do { needRecheck = false; FieldBinding existingField; if ((existingField = getField(synthField.name, true /*resolve*/)) != null) { TypeDeclaration typeDecl = this.scope.referenceContext; FieldDeclaration[] fieldDeclarations = typeDecl.fields; int max = fieldDeclarations == null ? 0 : fieldDeclarations.length; for (int i = 0; i < max; i++) { FieldDeclaration fieldDecl = fieldDeclarations[i]; if (fieldDecl.binding == existingField) { synthField.name = CharOperation.concat(fieldName, ("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$ needRecheck = true; break; } } } } while (needRecheck); return synthField; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseAllocationExpression.java
License:Open Source License
public static Expression convertToDynAccess(BlockScope scope, AllocationExpression expression, int accessId) { TypeBinding baseclass = expression.resolvedType; AstGenerator gen = new AstGenerator(expression); Expression receiver = gen.typeReference(baseclass); char[] selector = CalloutImplementorDyn.OT_ACCESS_STATIC; int modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic; Expression[] arguments = expression.arguments; Expression enclosingInstance = null; if (expression instanceof QualifiedAllocationExpression) { enclosingInstance = ((QualifiedAllocationExpression) expression).enclosingInstance; } else if (baseclass.isMemberType()) { // extract the enclosing base instance from an outer playedBy: ReferenceBinding enclosingTeam = scope.enclosingReceiverType().enclosingType(); if (enclosingTeam != null && TypeBinding.equalsEquals(baseclass.enclosingType(), enclosingTeam.baseclass)) { enclosingInstance = gen.fieldReference(gen.qualifiedThisReference(gen.typeReference(enclosingTeam)), IOTConstants._OT_BASE); enclosingInstance.resolve(scope); }/*www . j a va 2 s .co m*/ } if (enclosingInstance != null) { if (arguments == null) { arguments = new Expression[] { enclosingInstance }; } else { int len = arguments.length; System.arraycopy(arguments, 0, arguments = new Expression[len + 1], 1, len); arguments[0] = enclosingInstance; } } MessageSend allocSend = new MessageSend() { @Override public boolean isDecapsulationAllowed(Scope scope2) { // this message send can decapsulate independent of scope return true; } @Override public DecapsulationState getBaseclassDecapsulation() { return DecapsulationState.ALLOWED; } }; gen.setPositions(allocSend); allocSend.receiver = receiver; allocSend.selector = selector; allocSend.constant = Constant.NotAConstant; allocSend.actualReceiverType = baseclass; allocSend.accessId = accessId; allocSend.arguments = createResolvedAccessArguments(gen, accessId, arguments, scope); allocSend.binding = new MethodBinding(modifiers, new TypeBinding[] { TypeBinding.INT, TypeBinding.INT, scope.createArrayType(scope.getJavaLangObject(), 1), scope.getOrgObjectteamsITeam() }, Binding.NO_EXCEPTIONS, (ReferenceBinding) baseclass); allocSend.binding.returnType = scope.getJavaLangObject(); allocSend.binding.selector = selector; return gen.resolvedCastExpression(allocSend, baseclass, CastExpression.RAW); }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.WithinStatement.java
License:Open Source License
public WithinStatement(Expression teamExpr, Statement action, int s, int e) { super(2); // two declarations: the team variable and the level variable this.sourceStart = s; this.sourceEnd = e; AstGenerator gen = new AstGenerator(s, e); // GEN: org.objectteams.Team __OT__team$<pos> = <teamExpr>; // use source position to generate unique name: this.teamVarName = (WithinStatement.TEAM_VAR_PREFIX + s).toCharArray(); char[] saveVarName = (SAVE_VAR_PREFIX + s).toCharArray(); this.teamVarDecl = gen.localVariable(this.teamVarName, gen.qualifiedTypeReference(ORG_OBJECTTEAMS_ITEAM), teamExpr);// w w w. j a va 2 s .co m // GEN: int _OT$save<pos> = __OT__team$<pos>._OT$saveActivationState(); LocalDeclaration saveVarDecl = gen.localVariable(saveVarName, gen.singleTypeReference(TypeBinding.INT), teamMethodInvocation(SAVE_STATE_NAME, gen, null)); // GEN: __OT__team$<pos>.activate(); MessageSend activateSend = teamMethodInvocation(ACTIVATE_NAME, gen, null); // ensure action is a Block this.body = action; Block actionBlock; if (action instanceof Block) { actionBlock = (Block) action; } else { actionBlock = new Block(0); // no declarations actionBlock.statements = new Statement[] { action }; } /* GEN resetter block: * { * __OT__team$<pos>_OT$restoreActivationState(_OT$save<pos>); * } */ Block deactivateBlock = new Block(0); deactivateBlock.sourceStart = s; deactivateBlock.sourceEnd = e; deactivateBlock.statements = new Statement[] { teamMethodInvocation(RESTORE_ACTIVATION_NAME, gen, gen.singleNameReference(saveVarName)) }; // assemble action and deactivation into a try-finally: TryStatement tryStatement = new TryStatement(); tryStatement.sourceStart = s; tryStatement.sourceEnd = e; tryStatement.tryBlock = actionBlock; // the actual source body tryStatement.finallyBlock = deactivateBlock; // final assembly: this.statements = new Statement[] { this.teamVarDecl, // Team __OT__team$<pos> = <teamExpr>; saveVarDecl, // _OT$save<pos> = __OT__team$<pos>._OT$saveActivationState(); activateSend, // __OT__team$<pos>.activate(); tryStatement // try { <action> } finally { <reset> } }; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.BytecodeTransformer.java
License:Open Source License
/** * Adjust further information outside the Code attribute. * * @param dstType//w ww. j a v a 2s . c o m * @param codeToAdjust * @param tailOffset * @param dstMethodBinding * @param srcMethodModel * @return the new offset between line-numbers in the copied byte code and original source lines */ private int adjustTail(SourceTypeBinding dstType, byte[] codeToAdjust, int tailOffset, MethodBinding dstMethodBinding, MethodModel srcMethodModel) { int newLineOffset = 0; int exceptionCount = OTByteCodes.getWord(codeToAdjust, tailOffset); int offset = tailOffset + 2; for (int i = 0; i < exceptionCount; i++) { if (OTByteCodes.getWord(codeToAdjust, offset + 6) != 0) // 0 means any exception updateCPO(dstType, codeToAdjust, offset + 6, 2); // catch type offset += 8; } // remap arguments and locals: // non-static methods: [0] is "this", shift others by 1 // static methods: [0] is dummy int, [1] is synthetic team arg, // these two have no entry in LVT and LVTT, so just ignore them. // however, shift all real parameters to positions 2 .. int implicitSlots = dstMethodBinding.isStatic() ? 2 : 1; TypeBinding[] arguments = new TypeBinding[dstMethodBinding.parameters.length + implicitSlots]; System.arraycopy(dstMethodBinding.parameters, 0, arguments, implicitSlots, dstMethodBinding.parameters.length); if (!dstMethodBinding.isStatic()) { arguments[0] = dstMethodBinding.declaringClass; } else { arguments[0] = TypeBinding.INT; arguments[1] = dstType.enclosingType(); } // Attributes within the Code attribute: int attribCount = OTByteCodes.getWord(codeToAdjust, offset); offset += 2; for (int i = 0; i < attribCount; i++) { ConstantPoolObject newCPO = updateCPO(dstType, codeToAdjust, offset, 2); // attribute name offset += 2; int attrLen = OTByteCodes.getInt(codeToAdjust, offset); offset += 4; char[] attrName = newCPO.getUtf8(); if (CharOperation.equals(attrName, LineNumberTableName) && dstType.roleModel != null) { int[][] lineNumberTable = getLineNumberTable(codeToAdjust, offset); if (lineNumberTable != null) { // this offset is used to reconstruct original source lines: int oldLineOffset = srcMethodModel != null ? srcMethodModel._lineOffset : 0; // while iterating all lines and creating an appropriate LineInfo // compute the offset between new byte code lines and src: newLineOffset = mapLines(dstMethodBinding.copyInheritanceSrc.declaringClass, lineNumberTable, dstType.roleModel.getLineNumberProvider(), oldLineOffset); // patch the new byte code lines into the byte code attribute for (int j = 0; j < lineNumberTable.length; j++) { if (lineNumberTable[j][1] < ISMAPConstants.STEP_INTO_LINENUMBER) { int numberOffset = offset + 2 /*skip numbersCount*/ + j * 4 /*previous entries*/ + 2 /*skip start_pc*/; this._writer.write2(codeToAdjust, numberOffset, lineNumberTable[j][1] - oldLineOffset + newLineOffset); } } } } else if (CharOperation.equals(attrName, LocalVariableTableName)) { int localsCount = OTByteCodes.getWord(codeToAdjust, offset); for (int j = 0; j < localsCount; j++) { int localBase = offset + 2/*localsCount*/ + j * 10; int nameOffset = localBase + 4; updateCPO(dstType, codeToAdjust, nameOffset, 2); // local variable name int descOffset = localBase + 6; // type descriptor int slotOffset = localBase + 8; // local variable slot int slotNumber = OTByteCodes.getWord(codeToAdjust, slotOffset); if (slotNumber < arguments.length) { // map from parameters of the MethodBinding this._writer.writeUtf8(codeToAdjust, descOffset, arguments[slotNumber].signature()); } else { // lookup pure local variable from environment int descRef = OTByteCodes.getRef(2, codeToAdjust, descOffset); TypeBinding typeBinding = this._reader.getSignatureBinding(descRef, false/*generic*/); ConstantPoolObject typeCPO = this._mapper.mapTypeUtf8(typeBinding, false/*generic*/); this._writer.writeConstantPoolObject(codeToAdjust, descOffset, 2, typeCPO); } } } else if (CharOperation.equals(attrName, LocalVariableTypeTableName)) { int localsCount = OTByteCodes.getWord(codeToAdjust, offset); for (int j = 0; j < localsCount; j++) { int localBase = offset + 2/*localsCount*/ + j * 10; int nameOffset = localBase + 4; updateCPO(dstType, codeToAdjust, nameOffset, 2); // local variable name int descOffset = localBase + 6; // type descriptor int slotOffset = localBase + 8; // local variable slot int slotNumber = OTByteCodes.getWord(codeToAdjust, slotOffset); if (slotNumber < arguments.length) { // map from parameters of the MethodBinding this._writer.writeUtf8(codeToAdjust, descOffset, arguments[slotNumber].genericTypeSignature()); } else { // lookup pure local variable from environment int descRef = OTByteCodes.getRef(2, codeToAdjust, descOffset); TypeBinding typeBinding = this._reader.getSignatureBinding(descRef, true/*generic*/); ConstantPoolObject typeCPO = this._mapper.mapTypeUtf8(typeBinding, true/*generic*/); this._writer.writeConstantPoolObject(codeToAdjust, descOffset, 2, typeCPO); } } } else if (CharOperation.equals(attrName, StackMapTableName)) { rewriteStackMapTable(codeToAdjust, offset); } offset += attrLen; } return newLineOffset; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.WordValueAttribute.java
License:Open Source License
/** can only transfer some flags once we have the method binding */ public boolean evaluate(MethodInfo info, MethodBinding method, LookupEnvironment environment) { if (this._methodInfo != info) return false; // MODIFIERS and ROLECLASS_METHOD_MODIFIERS_NAME and CALLS_BASE_CTOR are already evaluated at the MethodInfo level. if (CharOperation.equals(this._name, IOTConstants.CALLIN_FLAGS)) { MethodModel.getModel(method).callinFlags = this._value & 0xFF; int typeCode = this._value & IOTConstants.CALLIN_RETURN_MASK; if (typeCode != 0) { TypeBinding returnType;/* ww w .j a v a2s . c om*/ switch (typeCode) { case IOTConstants.CALLIN_RETURN_VOID: returnType = TypeBinding.VOID; break; case IOTConstants.CALLIN_RETURN_BOOLEAN: returnType = TypeBinding.BOOLEAN; break; case IOTConstants.CALLIN_RETURN_BYTE: returnType = TypeBinding.BYTE; break; case IOTConstants.CALLIN_RETURN_CHAR: returnType = TypeBinding.CHAR; break; case IOTConstants.CALLIN_RETURN_SHORT: returnType = TypeBinding.SHORT; break; case IOTConstants.CALLIN_RETURN_DOUBLE: returnType = TypeBinding.DOUBLE; break; case IOTConstants.CALLIN_RETURN_FLOAT: returnType = TypeBinding.FLOAT; break; case IOTConstants.CALLIN_RETURN_INT: returnType = TypeBinding.INT; break; case IOTConstants.CALLIN_RETURN_LONG: returnType = TypeBinding.LONG; break; default: throw new InternalCompilerError("Unexpected callin return type code " + typeCode); //$NON-NLS-1$ } MethodModel.saveReturnType(method, returnType); } return true; } return false; // not handled, keep it. }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticRoleBridgeMethodBinding.java
License:Open Source License
public SyntheticRoleBridgeMethodBinding(SourceTypeBinding declaringRole, ReferenceBinding originalRole, MethodBinding targetMethod, int bridgeKind) { super(declaringRole, AccPublic | AccSynthetic, targetMethod.selector, originalParameters(targetMethod), originalReturnType(targetMethod)); this.purpose = bridgeKind; switch (bridgeKind) { case RoleMethodBridgeOuter: // correction: this method sits in the team not the role: this.declaringClass = declaringRole.enclosingType(); // perform two adjustments of the first parameter passing the role instance: // - weakening (using originalRole) // - use ifc-part: inner field accessor uses role class, don't expose it at this level int len = this.parameters.length; if (len > 0) { // accessor to static field has no argument System.arraycopy(this.parameters, 0, this.parameters = new TypeBinding[len], 0, len); this.parameters[0] = originalRole.getRealType(); // may also be weakened }//from w w w . j a v a 2s. c o m break; case RoleMethodBridgeInner: // correction: add role as first parameter: len = this.parameters.length; int offset = targetMethod.isStatic() ? 2 : 0; TypeBinding[] newParameters = new TypeBinding[len + 1 + offset]; newParameters[0] = originalRole.getRealType(); if (offset > 0) { newParameters[1] = TypeBinding.INT; // dummy int newParameters[2] = originalRole.enclosingType(); // team arg } System.arraycopy(this.parameters, 0, newParameters, 1 + offset, len); this.parameters = newParameters; // correction: this bridge is static: this.modifiers |= 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; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.mappings.CallinImplementorDyn.java
License:Open Source License
private void generateDispatchMethod(char[] methodName, final boolean isReplace, final boolean isAfter, final List<CallinMappingDeclaration> callinDecls, final TeamModel aTeam) { // FIXME(SH): once we know that Team has empty implementations (and checked cases involving team inheritance) // we probably want to avoid generating empty methods here. final TypeDeclaration teamDecl = aTeam.getAst(); if (teamDecl == null) return;/* w w w .j av a2s. c om*/ final AstGenerator gen = new AstGenerator(teamDecl); gen.replaceableEnclosingClass = teamDecl.binding; // public void _OT$callBefore (IBoundBase2 base, int boundMethodId, int callinId, Object[] args) // public void _OT$callAfter (IBoundBase2 base, int boundMethodId, int callinId, Object[] args, Object result) // public void _OT$callReplace (IBoundBase2 base, Team[] teams, int index, int boundMethodId, int[] callinIds, Object[] args) int length = 4; if (isReplace) length = 6; else if (isAfter) length = 5; Argument[] arguments = new Argument[length]; int a = 0; arguments[a++] = gen.argument(_BASE$, gen.qualifiedTypeReference(IOTConstants.ORG_OBJECTTEAMS_IBOUNDBASE2)); if (isReplace) arguments[a++] = gen.argument(TEAMS, gen.qualifiedArrayTypeReference(IOTConstants.ORG_OBJECTTEAMS_ITEAM, 1)); if (isReplace) arguments[a++] = gen.argument(INDEX, gen.typeReference(TypeBinding.INT)); arguments[a++] = isReplace ? gen.argument(CALLIN_ID, gen.createArrayTypeReference(TypeBinding.INT, 1)) : gen.argument(CALLIN_ID, gen.typeReference(TypeBinding.INT)); arguments[a++] = gen.argument(BOUND_METHOD_ID, gen.typeReference(TypeBinding.INT)); arguments[a++] = gen.argument(ARGUMENTS, gen.qualifiedArrayTypeReference(TypeConstants.JAVA_LANG_OBJECT, 1)); if (isAfter) arguments[a++] = gen.argument(_OT_RESULT, gen.qualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT)); TypeReference returnTypeRef = isReplace ? gen.qualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT) : gen.typeReference(TypeBinding.VOID); final MethodDeclaration callMethod = gen.method(teamDecl.compilationResult, AccPublic, returnTypeRef, methodName, arguments); callMethod.isMappingWrapper = AbstractMethodDeclaration.WrapperKind.CALLIN; AstEdit.addMethod(teamDecl, callMethod); MethodModel.addCallinFlag(callMethod, IOTConstants.CALLIN_FLAG_WRAPPER); callMethod.model._declaringMappings = callinDecls; MethodModel.getModel(callMethod).setStatementsGenerator(new AbstractStatementsGenerator() { protected boolean generateStatements(AbstractMethodDeclaration methodDecl) { // into head of tryStats we generate local vars to be shared by case statements: List<Statement> tryStats = new ArrayList<Statement>(); SwitchStatement switchStat = new SwitchStatement(); switchStat.expression = isReplace ? gen.arrayReference(gen.singleNameReference(CALLIN_ID), gen.singleNameReference(INDEX)) // switch(callinId[index]) { ... : gen.singleNameReference(CALLIN_ID); // switch(callinId) { ... // statements for the body of the switchStatement: List<Statement> statements = new ArrayList<Statement>(); int callinIdCount = teamDecl.getTeamModel().getCallinIdCount(); // callinIds not handled here will be handled using a super-call. boolean[] handledCallinIds = new boolean[callinIdCount]; // do we need to catch LiftingFailedException? boolean canLiftingFail = false; // one case block per callin mapping: for (CallinMappingDeclaration callinDecl : callinDecls) { if (callinDecl.ignoreFurtherInvestigation || RoleModel.isRoleWithBaseProblem(callinDecl.scope.referenceType())) continue; if (!callinDecl.hasParsedParamMappings) // during reconcile we may not be interested in this level of detail (e.g., of a role file) continue; gen.retargetFrom(callinDecl); // one case label per bound base method: for (MethodSpec baseSpec : callinDecl.baseMethodSpecs) { statements.add(gen.caseStatement(gen.intLiteral(baseSpec.callinID))); // case <baseMethod.callinId>: handledCallinIds[baseSpec.callinID] = true; PredicateGenerator predGen = new PredicateGenerator(callinDecl.binding._declaringRoleClass, callinDecl.isReplaceCallin()); TypeBinding baseReturn = baseSpec.resolvedType(); boolean isStaticRoleMethod = callinDecl.getRoleMethod().isStatic(); ReferenceBinding roleType = callinDecl.scope.enclosingSourceType(); if (roleType.isGenericType()) // cannot handle generic role in this generated code roleType = (ReferenceBinding) callinDecl.scope.environment().convertToRawType(roleType, false); MethodBinding roleMethodBinding = callinDecl.getRoleMethod(); boolean needLiftedRoleVar = !isStaticRoleMethod && roleType.isCompatibleWith(roleMethodBinding.declaringClass); List<Statement> blockStatements = new ArrayList<Statement>(); // do we need to expose _OT$result as result? char[] resultName = null; if (callinDecl.callinModifier == TerminalTokens.TokenNameafter && (callinDecl.mappings != null || callinDecl.predicate != null) && baseReturn != TypeBinding.VOID) { resultName = RESULT; callinDecl.resultVar = gen.localBaseVariable(RESULT, baseReturn, // BaseReturnType result = (BaseReturnType)_OT$result; gen.createCastOrUnboxing(gen.singleNameReference(_OT_RESULT), baseReturn, true/*baseAccess*/)); blockStatements.add(callinDecl.resultVar); } // expose casted _base$ as "base": blockStatements.add(gen.localVariable(IOTConstants.BASE, gen.alienScopeTypeReference(gen.baseTypeReference(roleType.baseclass()), callinDecl.scope), gen.castExpression(gen.baseNameReference(_BASE$), gen.alienScopeTypeReference(gen.baseTypeReference(roleType.baseclass()), callinDecl.scope), CastExpression.RAW))); // -------------- base predicate check ------- boolean hasBasePredicate = false; for (MethodSpec baseMethodSpec : callinDecl.baseMethodSpecs) { // FIXME: check this inner loop, outer already loops over baseMethods!! char[] resultName2 = null; if (callinDecl.callinModifier == TerminalTokens.TokenNameafter && baseMethodSpec.resolvedType() != TypeBinding.VOID) { resultName2 = IOTConstants.RESULT; } // FIXME(SH): only call predidate for the current base method (from BoundMethodID?) Statement predicateCheck = predGen.createBasePredicateCheck(callinDecl, baseMethodSpec, resultName2, gen); if (predicateCheck != null) { blockStatements.add(predicateCheck); // if (!base$when(baseArg,...)) throw new LiftingVetoException(); hasBasePredicate = true; } } Expression resetFlag = CallinImplementor.setExecutingCallin(roleType.roleModel, blockStatements); // boolean _OT$oldIsExecutingCallin = _OT$setExecutingCallin(true); // ----------- receiver for role method call: ----------- Expression receiver; char[] roleVar = null; if (!isStaticRoleMethod) { if (needLiftedRoleVar) { canLiftingFail |= checkLiftingProblem(teamDecl, callinDecl, roleType); roleVar = (LOCAL_ROLE + statements.size()).toCharArray(); TypeReference roleTypeReference = gen .roleTypeReference(teamDecl.getTeamModel().getTThis(), roleType, 0); blockStatements.add(gen.localVariable(roleVar, // RoleType local$n = this._OT$liftToRoleType((BaseType)base); gen.alienScopeTypeReference(roleTypeReference, callinDecl.scope), ClassFileConstants.AccFinal, Lifting.liftCall(callMethod.scope, gen.thisReference(), gen.baseNameReference(IOTConstants.BASE), callMethod.scope .getType(IOTConstants.ORG_OBJECTTEAMS_IBOUNDBASE2, 3), roleType, false, gen))); receiver = gen.thislikeNameReference(roleVar); // private receiver needs to be casted to the class. } else { // method is from role's enclosing team receiver = gen.qualifiedThisReference(TeamModel .strengthenEnclosing(teamDecl.binding, roleMethodBinding.declaringClass)); } } else { receiver = gen .singleNameReference(callinDecl.getRoleMethod().declaringClass.sourceName()); } int baseArgOffset = 0; if (baseSpec.isCallin()) baseArgOffset += MethodSignatureEnhancer.getEnhancingArgLen(WeavingScheme.OTDRE); if (baseSpec.isStatic() && baseSpec.getDeclaringClass().isRole()) baseArgOffset += 2; // unpack arguments to be used by parameter mappings and base predicate: // ArgTypeN argn = args[n] if (callinDecl.mappings != null || (hasBasePredicate && baseSpec.arguments != null)) { TypeBinding[] baseParams = baseSpec.resolvedParameters(); for (int i = 0; i < baseSpec.arguments.length; i++) { // BaseType baseArg = castAndOrUnbox(arguments[n]); Argument baseArg = baseSpec.arguments[i]; Expression rawArg = gen.arrayReference(gen.singleNameReference(ARGUMENTS), i + baseArgOffset); Expression init = rawArg; if (!baseParams[i].isTypeVariable()) init = gen.createCastOrUnboxing(rawArg, baseParams[i], callinDecl.scope); LocalDeclaration baseArgLocal = gen.localVariable(baseArg.name, gen.alienScopeTypeReference(baseArg.type, callinDecl.scope), init); baseArgLocal.modifiers |= (baseArg.modifiers & ClassFileConstants.AccFinal); if (hasBasePredicate) { // add to front so it is already available for the base predicate check: blockStatements.add(i, baseArgLocal); } else { // otherwise give it a chance for expressions/types that depend on the role instance baseArgLocal.initialization = new PotentialRoleReceiverExpression(init, roleVar, gen.typeReference(roleType)); blockStatements.add(baseArgLocal); } } } // -- assemble arguments: TypeBinding[] roleParams = callinDecl.roleMethodSpec.resolvedParameters(); Expression[] callArgs = new Expression[roleParams.length + (isReplace ? MethodSignatureEnhancer.getEnhancingArgLen(WeavingScheme.OTDRE) : 0)]; int idx = 0; if (isReplace) for (char[] argName : REPLACE_ARG_NAMES) callArgs[idx++] = gen.singleNameReference(argName); // prepare: base, teams, boundMethodId, callinIds, index, arguments ... // prepare parameter mappings: callinDecl.traverse(new ReplaceResultReferenceVisitor(callinDecl), callinDecl.scope.classScope()); boolean hasArgError = false; for (int i = 0; i < roleParams.length; i++) { Expression arg; TypeBinding roleParam = roleParams[i]; if (roleParam.isTypeVariable()) { TypeVariableBinding tvb = (TypeVariableBinding) roleParam; if (tvb.declaringElement instanceof MethodBinding) { if (TypeBinding.equalsEquals( ((MethodBinding) tvb.declaringElement).declaringClass, roleType)) // don't use type variable of target method, see test4140_callinReplaceCompatibility10s() roleParam = roleParam.erasure(); } } TypeReference localTypeRef = null; if (callinDecl.mappings == null) { // ------------ unmapped arguments -------------- arg = gen.arrayReference(gen.singleNameReference(ARGUMENTS), i + baseArgOffset); // prepare: somePreparation(arguments[i]) TypeBinding baseArgType = baseSpec.resolvedParameters()[i]; if (roleParam.isBaseType()) { // this includes intermediate cast to boxed type: arg = gen.createUnboxing(arg, (BaseTypeBinding) roleParam); } else if (baseArgType.isBaseType()) { // Object -> BoxingType arg = gen.castExpression(arg, gen.qualifiedTypeReference( AstGenerator.boxTypeName((BaseTypeBinding) baseArgType)), CastExpression.RAW); } else { // Object -> MyBaseClass ReferenceBinding baseclass = roleType.baseclass(); if (baseclass instanceof DependentTypeBinding && baseArgType instanceof ReferenceBinding) baseArgType = RoleTypeCreator.maybeInstantiateFromPlayedBy(callinDecl.scope, (ReferenceBinding) baseArgType); arg = gen.castExpression(arg, gen.alienScopeTypeReference(gen.typeReference(baseArgType), callinDecl.scope), CastExpression.DO_WRAP); if (!roleParam.leafComponentType().isBaseType() && PotentialLiftExpression .isLiftingRequired(callinDecl.scope, roleParam, baseArgType, arg)) { // lift?(MyBaseClass) Reference liftReceiver = null; // default: let gen find the team if (roleType.isTeam() && TypeBinding.equalsEquals(roleParam.enclosingType(), roleType)) liftReceiver = gen.singleNameReference(roleVar); // lift to inner role arg = gen.potentialLift(liftReceiver, arg, roleParam, isReplace/*reversible*/); localTypeRef = gen.typeReference(roleParam); canLiftingFail |= checkLiftingProblem(teamDecl, callinDecl, (ReferenceBinding) roleParam.leafComponentType()); } } if (localTypeRef == null) localTypeRef = gen.baseclassReference(baseArgType); // unless lifting was required above } else { // ------------ mapped arguments -------------- if (roleParam.isTypeVariable() && ((TypeVariableBinding) roleParam).declaringElement instanceof CallinCalloutBinding) localTypeRef = gen.typeReference(roleParam.erasure()); // cannot explicitly mention this TVB else localTypeRef = gen.typeReference(roleParam); arg = getArgument(callinDecl, // prepare: <mappedArg<n>> (MethodDeclaration) methodDecl, callinDecl.getRoleMethod().parameters, i + idx, baseSpec); if (arg == null) { hasArgError = true; continue; // keep going to find problems with other args, too. } if (Lifting.isLiftToMethodCall(arg)) canLiftingFail |= checkLiftingProblem(teamDecl, callinDecl, roleType); boolean isBaseReference = arg instanceof SingleNameReference && CharOperation .equals(((SingleNameReference) arg).token, IOTConstants.BASE); if (needLiftedRoleVar) arg = new PotentialRoleReceiverExpression(arg, roleVar, gen.typeReference(roleType.getRealClass())); // mapped expression may require casting: "base" reference has static type IBoundBase2 if (isBaseReference) arg = gen.castExpression(arg, gen.typeReference(roleParam), CastExpression.RAW); } char[] localName = (OT_LOCAL + i).toCharArray(); // RoleParamType _OT$local$n = preparedArg<n>; blockStatements.add(gen.localVariable(localName, gen.alienScopeTypeReference(localTypeRef, callinDecl.scope), arg)); callArgs[i + idx] = gen.singleNameReference(localName); // prepare: ... _OT$local$ ... } if (hasArgError) continue; // -- role side predicate: Expression[] predicateArgs = isReplace ? MethodSignatureEnhancer.retrenchBasecallArguments(callArgs, true, WeavingScheme.OTDRE) : callArgs; predicateArgs = maybeAddResultReference(callinDecl, predicateArgs, resultName, gen); Statement rolePredicateCheck = predGen.createPredicateCheck( // if (!when(callArgs)) throw new LiftingVetoException(); callinDecl, callinDecl.scope.referenceType(), receiver, predicateArgs, callArgs, gen); if (rolePredicateCheck != null) // predicateCheck(_OT$role) blockStatements.add(rolePredicateCheck); // -- assemble the method call: // local$n.roleMethod((ArgType0)args[0], .. (ArgTypeN)args[n]); boolean lhsResolvesToTeamMethod = TypeBinding .equalsEquals(callinDecl.getRoleMethod().declaringClass, roleType.enclosingType()); // TODO(SH): more levels MessageSend roleMethodCall = (callinDecl.getRoleMethod().isPrivate() && !lhsResolvesToTeamMethod) ? new PrivateRoleMethodCall(receiver, callinDecl.roleMethodSpec.selector, callArgs, false/*c-t-f*/, callinDecl.scope, roleType, callinDecl.getRoleMethod(), gen) : gen.messageSend(receiver, callinDecl.roleMethodSpec.selector, callArgs); roleMethodCall.isGenerated = true; // for PrivateRoleMethodCall roleMethodCall.isPushedOutRoleMethodCall = true; // -- post processing: Statement[] messageSendStatements; if (isReplace) { Expression result = roleMethodCall; if (baseSpec.returnNeedsTranslation) { // lowering: TypeBinding[]/*role,base*/ returnTypes = getReturnTypes(callinDecl, 0); // who is responsible for lowering: the team or the current role? Expression lowerReceiver = (isRoleOfCurrentRole(roleType, returnTypes[0])) ? gen.singleNameReference(roleVar) : genTeamThis(gen, returnTypes[0]); result = new Lowering().lowerExpression(methodDecl.scope, result, returnTypes[0], returnTypes[1], lowerReceiver, true/*needNullCheck*/, true/*delayedResolve*/); } // possibly convert using result mapping callinDecl.checkResultMapping(); boolean isResultBoxed = baseReturn.isBaseType() && baseReturn != TypeBinding.VOID; if (callinDecl.mappings != null && callinDecl.isResultMapped) { if (isResultBoxed) result = gen.createUnboxing(result, (BaseTypeBinding) baseReturn); Expression mappedResult = new PotentialRoleReceiverExpression( callinDecl.getResultExpression(baseSpec, isResultBoxed, gen/*stepOverGen*/), roleVar, gen.typeReference(roleType.getRealClass())); messageSendStatements = new Statement[] { callinDecl.resultVar = gen.localVariable(IOTConstants.RESULT, baseReturn, // result = (Type)role.roleMethod(args); gen.castExpression(result, gen.typeReference(baseReturn), CastExpression.RAW)), // cast because role return might be generalized gen.returnStatement(mappedResult) // return mappedResult(result); }; } else { if (isResultBoxed) { // $if_need_result_unboxing$ messageSendStatements = new Statement[] { gen.localVariable(IOTConstants.OT_RESULT, // Object _OT$result = role.roleMethod(args); gen.qualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT), result), CallinImplementor.genResultNotProvidedCheck( // if (_OT$result == null) teamDecl.binding.readableName(), // throw new ResultNotProvidedException(..) roleType.readableName(), roleMethodBinding, roleType.baseclass(), baseSpec, gen), gen.returnStatement(gen.singleNameReference(IOTConstants.OT_RESULT)) // return _OT$result; }; } else { // $endif$ messageSendStatements = new Statement[] { gen.returnStatement(result) }; // return role.roleMethod(args); } } } else { messageSendStatements = new Statement[] { roleMethodCall, // role.roleMethod(args); gen.breakStatement() // break; }; } // assemble: // try { roleMessageSend(); } // catch(Exception _OT$caughtException) { throw new SneakyException(_OT$caughtException); } // finally { _OT$setExecutingCallin(_OT$oldIsExecutingCallin); } blockStatements.add( protectRoleMethodCall(messageSendStatements, roleMethodBinding, resetFlag, gen)); statements.add(gen.block(blockStatements.toArray(new Statement[blockStatements.size()]))); // collectively report the problem(s) if (canLiftingFail && callinDecl.rolesWithLiftingProblem != null) for (Map.Entry<ReferenceBinding, Integer> entry : callinDecl.rolesWithLiftingProblem .entrySet()) callinDecl.scope.problemReporter().callinDespiteLiftingProblem(entry.getKey(), entry.getValue(), callinDecl); } } // END for (CallinMappingDeclaration callinDecl : callinDecls) gen.retargetFrom(teamDecl); boolean needSuperCall = false; // do we have a relevant super team, which possibly defines more callins? ReferenceBinding superTeam = aTeam.getBinding().superclass(); if (superTeam != null && superTeam.isTeam() && superTeam.id != IOTConstants.T_OrgObjectTeamsTeam) { // callinIds to be handled by super call? for (int i = 0; i < callinIdCount; i++) if (!handledCallinIds[i]) { statements.add(gen.caseStatement(gen.intLiteral(i))); // case callinIdOfSuper: needSuperCall = true; } if (!isReplace) needSuperCall = true; // a super call might become necessary after the fact when this dispatch method // is copy-inherited to a tsub-team, because the tsub-team may have a super // with more callins, see test1111_roleInheritsCallinFromTsupers1. // TODO: can we safely handle this for the replace-case, too?? // (replace needs to "return _OT$callNext();" in the default branch, see below). // See https://bugs.eclipse.org/433123 } if (needSuperCall) { if (!isReplace) statements.add(gen.caseStatement(null)); // default label char[] selector; char[][] argNames; if (isReplace) { selector = OT_CALL_REPLACE; argNames = REPLACE_ARG_NAMES; } else if (isAfter) { selector = OT_CALL_AFTER; argNames = AFTER_ARG_NAMES; } else { selector = OT_CALL_BEFORE; argNames = BEFORE_ARG_NAMES; } Expression[] superCallArgs = new Expression[argNames.length]; for (int idx = 0; idx < argNames.length; idx++) superCallArgs[idx] = gen.singleNameReference(argNames[idx]); // if we have a tsuper team which a corresponding dispatch method that one takes precedence: MessageSend superCall = aTeam.hasTSuperTeamMethod(selector) ? gen.tsuperMessageSend(gen.thisReference(), selector, superCallArgs) : gen.messageSend(gen.superReference(), selector, superCallArgs); if (isReplace) statements.add(gen.returnStatement(superCall)); // return super._OT$callReplace(..); else statements.add(superCall); // super._OT$callBefore/After(..); } Statement catchStatement1 = gen.emptyStatement(); Statement catchStatement2 = gen.emptyStatement(); if (isReplace) { // default: callNext: Expression[] callArgs = new Expression[REPLACE_ARG_NAMES.length + 1]; for (int idx = 0; idx < REPLACE_ARG_NAMES.length; idx++) callArgs[idx] = gen.singleNameReference(REPLACE_ARG_NAMES[idx]); callArgs[callArgs.length - 1] = gen.nullLiteral(); // no explicit baseCallArguments statements.add(gen.caseStatement(null)); // default: statements.add(gen.returnStatement( // return _OT$callNext(..); gen.messageSend(gen.qualifiedThisReference(aTeam.getBinding()), OT_CALL_NEXT, callArgs))); catchStatement1 = gen.returnStatement(gen .messageSend(gen.qualifiedThisReference(aTeam.getBinding()), OT_CALL_NEXT, callArgs)); catchStatement2 = gen.returnStatement(gen .messageSend(gen.qualifiedThisReference(aTeam.getBinding()), OT_CALL_NEXT, callArgs)); } // ==== overall assembly: ==== switchStat.statements = statements.toArray(new Statement[statements.size()]); Argument[] exceptionArguments; Statement[][] exceptionStatementss; if (canLiftingFail) { exceptionArguments = new Argument[] { gen.argument("ex".toCharArray(), //$NON-NLS-1$ gen.qualifiedTypeReference(IOTConstants.ORG_OBJECTTEAMS_LIFTING_VETO)), gen.argument("ex".toCharArray(), //$NON-NLS-1$ gen.qualifiedTypeReference(IOTConstants.O_O_LIFTING_FAILED_EXCEPTION)) }; exceptionStatementss = new Statement[][] { { catchStatement1 }, { catchStatement2 } }; } else { exceptionArguments = new Argument[] { gen.argument("ex".toCharArray(), //$NON-NLS-1$ gen.qualifiedTypeReference(IOTConstants.ORG_OBJECTTEAMS_LIFTING_VETO)) }; exceptionStatementss = new Statement[][] { { catchStatement1 } }; } tryStats.add(switchStat); methodDecl.statements = new Statement[] { gen.tryCatch(tryStats.toArray(new Statement[tryStats.size()]), // expected exception is ignored, do nothing (before/after) or proceed to callNext (replace) exceptionArguments, exceptionStatementss) }; methodDecl.hasParsedStatements = true; return true; } }); }