List of usage examples for org.eclipse.jdt.internal.compiler.lookup ReferenceBinding readableName
@Override public char[] readableName()
From source file:com.codenvy.ide.ext.java.server.internal.core.search.matching.PatternLocator.java
License:Open Source License
protected int resolveLevelForType(char[] simpleNamePattern, char[] qualificationPattern, char[][][] patternTypeArguments, int depth, TypeBinding type) { // standard search with no generic additional information must succeed int level = resolveLevelForType(simpleNamePattern, qualificationPattern, type); if (level == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH; if (type == null || patternTypeArguments == null || patternTypeArguments.length == 0 || depth >= patternTypeArguments.length) { return level; }//from w ww . j a v a2 s . co m // if pattern is erasure match (see bug 79790), commute impossible to erasure int impossible = this.isErasureMatch ? ERASURE_MATCH : IMPOSSIBLE_MATCH; // pattern has type parameter(s) or type argument(s) if (type.isGenericType()) { // Binding is generic, get its type variable(s) TypeVariableBinding[] typeVariables = null; if (type instanceof SourceTypeBinding) { SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) type; typeVariables = sourceTypeBinding.typeVariables; } else if (type instanceof BinaryTypeBinding) { BinaryTypeBinding binaryTypeBinding = (BinaryTypeBinding) type; if (this.mustResolve) typeVariables = binaryTypeBinding.typeVariables(); // TODO (frederic) verify performance } if (patternTypeArguments[depth] != null && patternTypeArguments[depth].length > 0 && typeVariables != null && typeVariables.length > 0) { if (typeVariables.length != patternTypeArguments[depth].length) return IMPOSSIBLE_MATCH; } // TODO (frederic) do we need to verify each parameter? return level; // we can't do better } // raw type always match if (type.isRawType()) { return level; } // Standard types (i.e. neither generic nor parameterized nor raw types) // cannot match pattern with type parameters or arguments TypeBinding leafType = type.leafComponentType(); if (!leafType.isParameterizedType()) { return (patternTypeArguments[depth] == null || patternTypeArguments[depth].length == 0) ? level : IMPOSSIBLE_MATCH; } // Parameterized type ParameterizedTypeBinding paramTypeBinding = (ParameterizedTypeBinding) leafType; // Compare arguments only if there ones on both sides if (patternTypeArguments[depth] != null && patternTypeArguments[depth].length > 0 && paramTypeBinding.arguments != null && paramTypeBinding.arguments.length > 0) { // type parameters length must match at least specified type names length int length = patternTypeArguments[depth].length; if (paramTypeBinding.arguments.length != length) return IMPOSSIBLE_MATCH; // verify each pattern type parameter nextTypeArgument: for (int i = 0; i < length; i++) { char[] patternTypeArgument = patternTypeArguments[depth][i]; TypeBinding argTypeBinding = paramTypeBinding.arguments[i]; // get corresponding pattern wildcard switch (patternTypeArgument[0]) { case Signature.C_STAR: // unbound parameter always match case Signature.C_SUPER: // needs pattern type parameter binding // skip to next type argument as it will be resolved later continue nextTypeArgument; case Signature.C_EXTENDS: // remove wildcard from patter type argument patternTypeArgument = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length); break; default: // no wildcard break; } // get pattern type argument from its signature patternTypeArgument = Signature.toCharArray(patternTypeArgument); if (!this.isCaseSensitive) patternTypeArgument = CharOperation.toLowerCase(patternTypeArgument); boolean patternTypeArgHasAnyChars = CharOperation.contains(new char[] { '*', '?' }, patternTypeArgument); // Verify that names match... // ...special case for wildcard if (argTypeBinding instanceof CaptureBinding) { WildcardBinding capturedWildcard = ((CaptureBinding) argTypeBinding).wildcard; if (capturedWildcard != null) argTypeBinding = capturedWildcard; } if (argTypeBinding.isWildcard()) { WildcardBinding wildcardBinding = (WildcardBinding) argTypeBinding; switch (wildcardBinding.boundKind) { case Wildcard.EXTENDS: // Invalid if type argument is not exact if (patternTypeArgHasAnyChars) return impossible; continue nextTypeArgument; case Wildcard.UNBOUND: // there's no bound name to match => valid continue nextTypeArgument; } // Look if bound name match pattern type argument ReferenceBinding boundBinding = (ReferenceBinding) wildcardBinding.bound; if (CharOperation.match(patternTypeArgument, boundBinding.shortReadableName(), this.isCaseSensitive) || CharOperation.match(patternTypeArgument, boundBinding.readableName(), this.isCaseSensitive)) { // found name in hierarchy => match continue nextTypeArgument; } // If pattern is not exact then match fails if (patternTypeArgHasAnyChars) return impossible; // Look for bound name in type argument superclasses boundBinding = boundBinding.superclass(); while (boundBinding != null) { if (CharOperation.equals(patternTypeArgument, boundBinding.shortReadableName(), this.isCaseSensitive) || CharOperation.equals(patternTypeArgument, boundBinding.readableName(), this.isCaseSensitive)) { // found name in hierarchy => match continue nextTypeArgument; } else if (boundBinding.isLocalType() || boundBinding.isMemberType()) { // for local or member type, verify also source name (bug 81084) if (CharOperation.match(patternTypeArgument, boundBinding.sourceName(), this.isCaseSensitive)) continue nextTypeArgument; } boundBinding = boundBinding.superclass(); } return impossible; } // See if names match if (CharOperation.match(patternTypeArgument, argTypeBinding.shortReadableName(), this.isCaseSensitive) || CharOperation.match(patternTypeArgument, argTypeBinding.readableName(), this.isCaseSensitive)) { continue nextTypeArgument; } else if (argTypeBinding.isLocalType() || argTypeBinding.isMemberType()) { // for local or member type, verify also source name (bug 81084) if (CharOperation.match(patternTypeArgument, argTypeBinding.sourceName(), this.isCaseSensitive)) continue nextTypeArgument; } // If pattern is not exact then match fails if (patternTypeArgHasAnyChars) return impossible; // Scan hierarchy TypeBinding leafTypeBinding = argTypeBinding.leafComponentType(); if (leafTypeBinding.isBaseType()) return impossible; ReferenceBinding refBinding = ((ReferenceBinding) leafTypeBinding).superclass(); while (refBinding != null) { if (CharOperation.equals(patternTypeArgument, refBinding.shortReadableName(), this.isCaseSensitive) || CharOperation.equals(patternTypeArgument, refBinding.readableName(), this.isCaseSensitive)) { // found name in hierarchy => match continue nextTypeArgument; } else if (refBinding.isLocalType() || refBinding.isMemberType()) { // for local or member type, verify also source name (bug 81084) if (CharOperation.match(patternTypeArgument, refBinding.sourceName(), this.isCaseSensitive)) continue nextTypeArgument; } refBinding = refBinding.superclass(); } return impossible; } } // Recurse on enclosing type TypeBinding enclosingType = paramTypeBinding.enclosingType(); if (enclosingType != null && enclosingType.isParameterizedType() && depth < patternTypeArguments.length && qualificationPattern != null) { int lastDot = CharOperation.lastIndexOf('.', qualificationPattern); char[] enclosingQualificationPattern = lastDot == -1 ? null : CharOperation.subarray(qualificationPattern, 0, lastDot); char[] enclosingSimpleNamePattern = lastDot == -1 ? qualificationPattern : CharOperation.subarray(qualificationPattern, lastDot + 1, qualificationPattern.length); int enclosingLevel = resolveLevelForType(enclosingSimpleNamePattern, enclosingQualificationPattern, patternTypeArguments, depth + 1, enclosingType); if (enclosingLevel == impossible) return impossible; if (enclosingLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH; } return level; }
From source file:com.redhat.ceylon.eclipse.core.model.mirror.JDTMethod.java
License:Open Source License
public boolean isOverridingMethod() { if (isOverriding == null) { isOverriding = false;//from ww w . j a v a2 s . c o m doWithBindings(new ActionOnMethodBinding() { @Override public void doWithBinding(IType declaringClassModel, ReferenceBinding declaringClass, MethodBinding method) { if (CharOperation.equals(declaringClass.readableName(), "ceylon.language.Identifiable".toCharArray())) { if ("equals".equals(name) || "hashCode".equals(name)) { isOverriding = true; return; } } if (CharOperation.equals(declaringClass.readableName(), "ceylon.language.Object".toCharArray())) { if ("equals".equals(name) || "hashCode".equals(name) || "toString".equals(name)) { isOverriding = false; return; } } // try the superclass first if (isDefinedInSuperClasses(declaringClass, method)) { isOverriding = true; } if (isDefinedInSuperInterfaces(declaringClass, method)) { isOverriding = true; } } }); } return isOverriding.booleanValue(); }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.RoleClassLiteralAccess.java
License:Open Source License
private static TypeBinding ensureGetClassMethodPart(TypeDeclaration teamDecl, ReferenceBinding teamBinding, TypeDeclaration roleDecl, ReferenceBinding roleBinding, char[] selector) { MethodBinding[] existingMethods = teamBinding.getMethods(selector); if (existingMethods != NO_METHODS) return existingMethods[0].returnType; // already generated if (teamDecl == null) throw new InternalCompilerError("Requesting to generate a method for binary type " //$NON-NLS-1$ + String.valueOf(teamBinding.readableName())); AstGenerator gen;/*ww w. ja v a2 s . c om*/ if (roleDecl != null) gen = new AstGenerator(roleDecl.scope.compilerOptions().sourceLevel, roleDecl.sourceStart, roleDecl.sourceEnd); else gen = new AstGenerator(teamDecl.scope.compilerOptions().sourceLevel, teamDecl.sourceStart, teamDecl.sourceEnd); // return type reference is either "Class<Role>" or "Class<Role<?,?...>>" TypeVariableBinding[] typeVariables = roleBinding.typeVariables(); TypeReference roleTypeRef; if (typeVariables != Binding.NO_TYPE_VARIABLES) { Wildcard[] wildcards = new Wildcard[typeVariables.length]; for (int i = 0; i < typeVariables.length; i++) wildcards[i] = gen.wildcard(Wildcard.UNBOUND); roleTypeRef = gen.parameterizedSingleTypeReference(roleBinding.sourceName(), wildcards, 0); } else { roleTypeRef = gen.singleTypeReference(roleBinding.sourceName()); } TypeReference[] typeArguments = new TypeReference[] { roleTypeRef }; MethodDeclaration method = gen.method(teamDecl.compilationResult, (teamBinding.isRole()) ? ClassFileConstants.AccPublic // advertized via ifc, must be public : roleBinding.modifiers & AccVisibilityMASK, gen.parameterizedQualifiedTypeReference( // java.lang.Class<R> TypeConstants.JAVA_LANG_CLASS, typeArguments), selector, null); if (teamBinding.isInterface()) method.modifiers |= ClassFileConstants.AccAbstract | ExtraCompilerModifiers.AccSemicolonBody; else method.setStatements(new Statement[] { gen.returnStatement(new ClassLiteralAccess(gen.sourceEnd, gen.singleTypeReference(roleBinding.sourceName()), true)) }); AstEdit.addMethod(teamDecl, method); return method.returnType.resolvedType; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.OTSpecialAccessAttribute.java
License:Open Source License
@SuppressWarnings("nls") @Override//from ww w . j a v a2 s . c om public String toString() { StringBuilder result = new StringBuilder(); result.append(this._site.readableName()); result.append(" requires special access to these elements:"); for (DecapsulatedMethodDesc method : this._decapsulatedMethods) { result.append("\n\tmethod "); result.append(method.toString()); } for (CalloutToFieldDesc field : this._calloutToFields) { result.append("\n\tfield "); result.append(field.toString()); } for (SuperMethodDesc method : this._superMethods) { result.append("\n\t"); result.append(method.toString()); } for (ReferenceBinding baseclass : this._adaptedBaseclasses) { result.append("\n\tbase class "); result.append(baseclass.readableName()); } return result.toString(); }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lifting.DeclaredLifting.java
License:Open Source License
static Statement generateDynamicSwitch(BlockScope scope, ReferenceBinding roleType, int problemId, AstGenerator gen) {//from ww w .j av a2 s. c om ReferenceBinding[] boundDescendants = roleType.roleModel.getBoundDescendants(); int len = boundDescendants.length; if (len == 0) return gen.throwStatement(gen.allocation(gen.qualifiedTypeReference(TypeConstants.JAVA_LANG_ERROR), new Expression[] { gen.stringLiteral(CharOperation.concat( "Lifting impossible, role has no bound descendants: ".toCharArray(), //$NON-NLS-1$ roleType.readableName())) })); LookupEnvironment environment = scope.compilationUnitScope().environment; // toplevel "if" IfStatement ifStat = genNewIf(scope, gen, boundDescendants[0], environment); IfStatement current = ifStat; // needed at least one if, nested ifs are optional: for (int i = 1; i < len; i++) { IfStatement newIf = genNewIf(scope, gen, boundDescendants[i], environment); current.elseStatement = newIf; // nest within existing "if else { /* here */ }" current = newIf; } // final branch: current.elseStatement = Lifting.genLiftingFailedException(IOTConstants.BASE, roleType, problemId, gen); return ifStat; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lifting.Lifting.java
License:Open Source License
/** * API for AbstractMethodDeclaration:/*from w w w.j ava2 s. c o m*/ * * Create a byte code sequence for a runtime check in a creation method: * R _OT$create_OT$R(B b) { * if (this._OT$cache_OT$R.contains(b)) * throw new DuplicateRoleException("R"); * // continue regular code. * } * * Note, the need for this runtime check is detected quite late. * At this point it is easier to create the byte code sequence directly, * rather the creating AST first. */ public static void createDuplicateRoleCheck(CodeStream codeStream, AbstractMethodDeclaration method) { MethodBinding binding = method.binding; Scope scope = method.scope; ReferenceBinding roleType = (ReferenceBinding) binding.returnType; String roleName = new String(roleType.readableName()); // TODO(SH): check why roleType.getRoleModel().getClassPartBinding().roleModel may yield a different result. // I think it occured in haeder/stopwatch from smile-CVS. //RoleModel role = roleType.getRealClass().roleModel; char[] cacheName = LiftingEnvironment.getCacheName(roleType.roleModel.getBoundRootRole()); ReferenceBinding teamBinding = roleType.enclosingType();//role.getTeamModel().getBinding(); FieldBinding cache = TypeAnalyzer.findField(teamBinding, cacheName, /*static*/false, /*outer*/false, ITranslationStates.STATE_FULL_LIFTING); // generated by this state if (cache == null) throw new InternalCompilerError("generated cache field not found: " + new String(cacheName)); //$NON-NLS-1$ ReferenceBinding map = (ReferenceBinding) scope.getType(IOTConstants.WEAK_HASH_MAP, 3); MethodBinding contains = map.getMethod(scope, IOTConstants.CONTAINS_KEY); ReferenceBinding exc = (ReferenceBinding) scope.getType(IOTConstants.ORG_OBJECTTEAMS_DUPLICATE_ROLE, 3); TypeBinding[] types = new TypeBinding[] { scope.getJavaLangString() }; MethodBinding excInit = exc.getExactConstructor(types); BranchLabel normalCase = new BranchLabel(codeStream); codeStream.aload_0(); // this codeStream.fieldAccess(Opcodes.OPC_getfield, cache, teamBinding); // getfield MyTeam._OT$cache_OT$R Ljava/util/WeakHashMap; codeStream.aload_1(); // arg0 codeStream.invoke(Opcodes.OPC_invokevirtual, contains, map); // invokevirtual java.util.WeakHashMap.containsKey (Ljava/lang/Object;)Z codeStream.ifeq(normalCase); // false -> #endif codeStream.new_(exc); // new <org.objectteams.DuplicateRoleException> codeStream.dup(); // dup codeStream.ldc(roleName); // ldc "R" codeStream.invoke(Opcodes.OPC_invokespecial, excInit, exc); // invokespecial org.objectteams.DuplicateRoleException.<init> (Ljava/lang/String;)V codeStream.athrow(); // athrow normalCase.place(); // #endif }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lookup.CallinCalloutBinding.java
License:Open Source License
/** Answer the name of this callin qualified with the declaring class's name. */ public char[] getQualifiedName() { char[] name = this.name; if (name[0] == '<') return name; // synthetic name is already unique. ReferenceBinding currentType = this._declaringRoleClass; return CharOperation.concat(name, currentType.readableName(), '$'); }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.mappings.CallinImplementor.java
License:Open Source License
/** * Record that the base argument is equivalent to the base field. * @param newMethod//w ww . java 2 s .c o m */ private void setBaseArgBestName(MethodDeclaration newMethod, Argument baseArg) { // base arg is always first, so binding cannot disturb argument order. baseArg.bind(newMethod.scope, baseArg.type.resolvedType, false); ITeamAnchor baseArgBinding = newMethod.arguments[0].binding; // lookup _OT$base: ReferenceBinding roleBinding = this._role.getBinding(); if (!roleBinding.isHierarchyInconsistent() && !this._role.hasBaseclassProblem()) // CLOVER: never false in jacks suite { // have no base field if hierarchy is inconsistent (see TPX-214). ITeamAnchor baseField = TypeAnalyzer.findField(roleBinding, IOTConstants._OT_BASE, /*static*/false, /*outer*/true, ITranslationStates.STATE_ROLE_HIERARCHY_ANALYZED); // link both vars: if (baseField != null) { baseArgBinding.shareBestName(baseField); } else if (roleBinding.isRegularInterface()) { // OK!? } else { // Notes: Observed this while preparing the NODe-tutorial. // Reoccurred as TPX-491, fixed by v14499. throw new InternalCompilerError( "Role has no base field: " + new String(roleBinding.readableName())); //$NON-NLS-1$ } } }
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;/*from w w w.j av a 2 s . co m*/ 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; } }); }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.model.FieldModel.java
License:Open Source License
/** Given that this is the model of a fake strong base field, return the original field from the super role. */ public FieldBinding getOriginalFromFake() { ReferenceBinding superRole = this.actualDeclaringClass; FieldBinding fieldBinding = superRole.getField(this._binding.name, true); if (fieldBinding == null) throw new InternalCompilerError( "Expected base field not found in super Role " + new String(superRole.readableName())); //$NON-NLS-1$ return fieldBinding; }