List of usage examples for org.eclipse.jdt.internal.compiler.lookup LocalVariableBinding LocalVariableBinding
public LocalVariableBinding(LocalDeclaration declaration, TypeBinding type, int modifiers, MethodScope declaringScope)
From source file:org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.java
License:Open Source License
public MethodBinding resolveTypesFor(MethodBinding method) { if ((method.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0) return method; if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { if ((method.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0) method.modifiers |= ClassFileConstants.AccDeprecated; }// w w w . jav a 2 s . c o m if (isViewedAsDeprecated() && !method.isDeprecated()) method.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly; if (hasRestrictedAccess()) method.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess; AbstractMethodDeclaration methodDecl = method.sourceMethod(); // GROOVY /* old { if (methodDecl == null) return null; // method could not be resolved in previous iteration } new*/ if (methodDecl == null) { if (method instanceof LazilyResolvedMethodBinding) { LazilyResolvedMethodBinding lrMethod = (LazilyResolvedMethodBinding) method; // the rest is a copy of the code below but doesn't depend on the method declaration // nothing to do for method type parameters (there are none) // nothing to do for method exceptions (there are none) TypeBinding ptb = lrMethod.getParameterTypeBinding(); if (ptb == null) { method.parameters = Binding.NO_PARAMETERS; } else { method.parameters = new TypeBinding[] { ptb }; } method.returnType = lrMethod.getReturnTypeBinding(); method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved; return method; } // returning null is what this clause would have done anyway return null; } // FIXASC - end TypeParameter[] typeParameters = methodDecl.typeParameters(); if (typeParameters != null) { methodDecl.scope.connectTypeVariables(typeParameters, true); // Perform deferred bound checks for type variables (only done after type variable hierarchy is connected) for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) typeParameters[i].checkBounds(methodDecl.scope); } TypeReference[] exceptionTypes = methodDecl.thrownExceptions; if (exceptionTypes != null) { int size = exceptionTypes.length; method.thrownExceptions = new ReferenceBinding[size]; int count = 0; ReferenceBinding resolvedExceptionType; for (int i = 0; i < size; i++) { resolvedExceptionType = (ReferenceBinding) exceptionTypes[i].resolveType(methodDecl.scope, true /* check bounds*/); if (resolvedExceptionType == null) continue; if (resolvedExceptionType.isBoundParameterizedType()) { methodDecl.scope.problemReporter().invalidParameterizedExceptionType(resolvedExceptionType, exceptionTypes[i]); continue; } if (resolvedExceptionType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) { if (resolvedExceptionType.isValidBinding()) { methodDecl.scope.problemReporter().cannotThrowType(exceptionTypes[i], resolvedExceptionType); continue; } } if ((resolvedExceptionType.tagBits & TagBits.HasMissingType) != 0) { method.tagBits |= TagBits.HasMissingType; } method.modifiers |= (resolvedExceptionType.modifiers & ExtraCompilerModifiers.AccGenericSignature); method.thrownExceptions[count++] = resolvedExceptionType; } if (count < size) System.arraycopy(method.thrownExceptions, 0, method.thrownExceptions = new ReferenceBinding[count], 0, count); } final boolean reportUnavoidableGenericTypeProblems = this.scope .compilerOptions().reportUnavoidableGenericTypeProblems; boolean foundArgProblem = false; Argument[] arguments = methodDecl.arguments; if (arguments != null) { int size = arguments.length; method.parameters = Binding.NO_PARAMETERS; TypeBinding[] newParameters = new TypeBinding[size]; for (int i = 0; i < size; i++) { Argument arg = arguments[i]; if (arg.annotations != null) { method.tagBits |= TagBits.HasParameterAnnotations; } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=322817 boolean deferRawTypeCheck = !reportUnavoidableGenericTypeProblems && !method.isConstructor() && (arg.type.bits & ASTNode.IgnoreRawTypeCheck) == 0; TypeBinding parameterType; if (deferRawTypeCheck) { arg.type.bits |= ASTNode.IgnoreRawTypeCheck; } try { parameterType = arg.type.resolveType(methodDecl.scope, true /* check bounds*/); } finally { if (deferRawTypeCheck) { arg.type.bits &= ~ASTNode.IgnoreRawTypeCheck; } } if (parameterType == null) { foundArgProblem = true; } else if (parameterType == TypeBinding.VOID) { methodDecl.scope.problemReporter().argumentTypeCannotBeVoid(this, methodDecl, arg); foundArgProblem = true; } else { if ((parameterType.tagBits & TagBits.HasMissingType) != 0) { method.tagBits |= TagBits.HasMissingType; } TypeBinding leafType = parameterType.leafComponentType(); if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) method.modifiers |= ExtraCompilerModifiers.AccGenericSignature; newParameters[i] = parameterType; arg.binding = new LocalVariableBinding(arg, parameterType, arg.modifiers, true); } } // only assign parameters if no problems are found if (!foundArgProblem) { method.parameters = newParameters; } } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=337799 if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_7) { if ((method.tagBits & TagBits.AnnotationSafeVarargs) != 0) { if (!method.isVarargs()) { methodDecl.scope.problemReporter().safeVarargsOnFixedArityMethod(method); } else if (!method.isStatic() && !method.isFinal() && !method.isConstructor()) { methodDecl.scope.problemReporter().safeVarargsOnNonFinalInstanceMethod(method); } } else if (method.parameters != null && method.parameters.length > 0 && method.isVarargs()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=337795 if (!method.parameters[method.parameters.length - 1].isReifiable()) { methodDecl.scope.problemReporter() .possibleHeapPollutionFromVararg(methodDecl.arguments[methodDecl.arguments.length - 1]); } } } boolean foundReturnTypeProblem = false; if (!method.isConstructor()) { TypeReference returnType = methodDecl instanceof MethodDeclaration ? ((MethodDeclaration) methodDecl).returnType : null; if (returnType == null) { methodDecl.scope.problemReporter().missingReturnType(methodDecl); method.returnType = null; foundReturnTypeProblem = true; } else { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=322817 boolean deferRawTypeCheck = !reportUnavoidableGenericTypeProblems && (returnType.bits & ASTNode.IgnoreRawTypeCheck) == 0; TypeBinding methodType; if (deferRawTypeCheck) { returnType.bits |= ASTNode.IgnoreRawTypeCheck; } try { methodType = returnType.resolveType(methodDecl.scope, true /* check bounds*/); } finally { if (deferRawTypeCheck) { returnType.bits &= ~ASTNode.IgnoreRawTypeCheck; } } if (methodType == null) { foundReturnTypeProblem = true; } else if (methodType.isArrayType() && ((ArrayBinding) methodType).leafComponentType == TypeBinding.VOID) { methodDecl.scope.problemReporter().returnTypeCannotBeVoidArray((MethodDeclaration) methodDecl); foundReturnTypeProblem = true; } else { if ((methodType.tagBits & TagBits.HasMissingType) != 0) { method.tagBits |= TagBits.HasMissingType; } method.returnType = methodType; TypeBinding leafType = methodType.leafComponentType(); if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) method.modifiers |= ExtraCompilerModifiers.AccGenericSignature; } } } if (foundArgProblem) { methodDecl.binding = null; method.parameters = Binding.NO_PARAMETERS; // see 107004 // nullify type parameter bindings as well as they have a backpointer to the method binding // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=81134) if (typeParameters != null) for (int i = 0, length = typeParameters.length; i < length; i++) typeParameters[i].binding = null; return null; } if (foundReturnTypeProblem) return method; // but its still unresolved with a null return type & is still connected to its method declaration method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved; return method; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseCallTrackingVariable.java
License:Open Source License
/** * Resolving a BaseCallTrackingVariable must happen after everything else of * the callin method has been resolved, because we need to know the number * of (real) allocated local variables./* w ww . jav a 2 s . co m*/ */ public void resolve(BlockScope scope) { // only need the binding, which is used as reference in FlowInfo methods. this.binding = new LocalVariableBinding(this.name, Scope.getBaseType("boolean".toCharArray()), // arbitrary.. //$NON-NLS-1$ ClassFileConstants.AccFinal, false); this.binding.setConstant(Constant.NotAConstant); // use a free slot without assigning it: this.binding.id = scope.outerMostMethodScope().analysisIndex++; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.OTQualifiedAllocationExpression.java
License:Open Source License
/** * During resolve we make the decision which variant to use. *///from w w w . j a v a 2 s. c o m public TypeBinding resolveType(BlockScope scope) { if (this.anonymousType == null && this.creatorCall == null && this.enclosingInstance == null) // special case during code assist return super.resolveType(scope); CompilationResult compilationResult = scope.referenceContext().compilationResult(); CheckPoint cp = compilationResult.getCheckPoint(scope.referenceContext()); this.hasEnclosingInstanceProblem = false; if (this.anonymousType == null && this.creatorCall == null) { // no double processing if (this.enclosingInstance instanceof CastExpression) this.enclosingInstance.bits |= DisableUnnecessaryCastCheck; // will check later on (within super.resolveType()) TypeBinding enclosingInstanceType = this.enclosingInstance.resolveType(scope); this.hasEnclosingInstanceProblem = enclosingInstanceType == null; if (!scope.isGeneratedScope() && enclosingInstanceType != null && enclosingInstanceType.isTeam()) // non reference types will trigger error reporting via super.resolveType() { if (this.enclosingInstance instanceof NameReference) { final NameReference anchorRef = (NameReference) this.enclosingInstance; if (!((VariableBinding) anchorRef.binding).isFinal()) { // replace non-final anchor with fake-binding, // so that this type is not compatibly to anything else: char[] variableName = ((VariableBinding) anchorRef.binding).name; switch (anchorRef.bits & ASTNode.RestrictiveFlagMASK) { case Binding.LOCAL: final LocalVariableBinding localOrig = (LocalVariableBinding) anchorRef.binding; // mark the original as used before we procede with a fake copy: localOrig.useFlag = LocalVariableBinding.USED; anchorRef.binding = new LocalVariableBinding(variableName, enclosingInstanceType, ClassFileConstants.AccFinal, false) { @Override public int problemId() { return IProblem.AnchorNotFinal; } }; this.preGenerateTask = new Runnable() { public void run() { // need to transfer this info from the real local to the fake one (don't have that info yet): ((LocalVariableBinding) anchorRef.binding).resolvedPosition = localOrig.resolvedPosition; } }; break; case Binding.FIELD: anchorRef.binding = new FieldBinding(variableName, enclosingInstanceType, ClassFileConstants.AccFinal, scope.referenceType().binding, Constant.NotAConstant) { @Override public int problemId() { return IProblem.AnchorNotFinal; } }; break; default: throw new InternalCompilerError("Unexpected bits, neither local nor field " //$NON-NLS-1$ + anchorRef.bits + ": " + anchorRef); //$NON-NLS-1$ } } } if (this.type.getTypeName().length > 1) { scope.problemReporter().roleCreationNotRelativeToEnclosingTeam(this); return null; } // now it's finally time to create the alternate version: this.creatorCall = CopyInheritance.createConstructorMethodInvocationExpression(scope, this); if (this.creatorCall == null) return null; } } if (this.creatorCall == null) { TypeBinding typ = super.resolveType(scope); if (typ == null || typ instanceof PolyTypeBinding) return typ; if (!this.hasEnclosingInstanceProblem) { // more checks only if no error already // if enclosing is a role request a cast to the class part as required by the inner constructor if (this.enclosingInstance != null) { TypeBinding enclosingType = this.enclosingInstance.resolvedType; if (enclosingType instanceof ReferenceBinding && ((ReferenceBinding) enclosingType).isDirectRole()) this.enclosingInstanceCast = ((ReferenceBinding) enclosingType).getRealClass(); } ReferenceBinding superType = null; if (this.resolvedType instanceof ReferenceBinding) superType = ((ReferenceBinding) this.resolvedType).superclass(); if (superType != null && (superType instanceof RoleTypeBinding)) { RoleTypeBinding superRole = (RoleTypeBinding) superType; if (superRole.hasExplicitAnchor()) scope.problemReporter().extendingExternalizedRole(superRole, this.type); } } } else { // === with creatorCall === this.constant = Constant.NotAConstant; this.resolvedType = this.creatorCall.resolveType(scope); // when creating role nested instance, no cast of enclosing role needed in this branch, // because creator call is routed via the interface of the enclosing role. if (this.resolvedType != null) { if (((ReferenceBinding) this.resolvedType).isAbstract()) { if (!((ReferenceBinding) enclosingInstance().resolvedType).isAbstract()) scope.problemReporter().abstractRoleIsRelevant(this, (ReferenceBinding) this.creatorCall.resolvedType); } if (this.resolvedType.isValidBinding()) { // FIXME(SH): remove cast unwrapping Expression createExpr = this.creatorCall; while (createExpr instanceof CastExpression) // may have been wrapped using CollectedReplacementsTransformer createExpr = ((CastExpression) createExpr).expression; this.binding = ((MessageSend) createExpr).binding; // store the method binding // using lift-ctor in a qualified way? (OTJDL 2.4.1(a)) ReferenceBinding role = (ReferenceBinding) this.resolvedType; MethodBinding creator = this.binding; if (creator != null) { MethodBinding ctor = role.getExactConstructor(creator.parameters); if (Lifting.isLiftToConstructor(ctor, role)) scope.problemReporter().qualifiedUseOfLiftingConstructor(ctor, this.creatorCall); } } } } return this.resolvedType; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.AnchorListAttribute.java
License:Open Source License
/** * @param typeToWrap ReferenceBinding or array thereof * @param anchorName/*from w ww . j ava 2 s . c o m*/ * @param site * @param declaringMethod where to look for arguments being used as type anchor. * @param environment * @return a wrapped version of typeToWrap */ private TypeBinding getWrappedType(TypeBinding typeToWrap, char[] anchorName, ReferenceBinding site, final MethodBinding declaringMethod, LookupEnvironment environment) { assert !CharOperation.equals(anchorName, NO_ANCHOR) : "NO_ANCHOR should have been filtered out"; //$NON-NLS-1$ ReferenceBinding type = (ReferenceBinding) typeToWrap.leafComponentType(); if (CharOperation.prefixEquals(ARG_ANCHOR_PREFIX.toCharArray(), anchorName)) { // Type anchored to another argument: LocalVariableBinding anchor = new LocalVariableBinding(anchorName, type.enclosingType(), 0, true); // name is irrelevant. // make sure this anchor can answer `anchor.declaringScope.referenceMethodBinding()`: anchor.declaringScope = new CallinCalloutScope(null, null) { public MethodBinding referenceMethodBinding() { return declaringMethod; } }; TypeBinding wrappedType = anchor.getRoleTypeBinding(type, typeToWrap.dimensions()); // argument position is relevant: char[] tail = CharOperation.subarray(anchorName, ARG_ANCHOR_PREFIX.length(), -1); RoleTypeBinding wrappedRole = (RoleTypeBinding) wrappedType.leafComponentType(); wrappedRole._argumentPosition = Integer.parseInt(String.valueOf(tail)); wrappedRole._declaringMethod = new IMethodProvider() { public MethodBinding getMethod() { return declaringMethod; } }; return wrappedType; } else { return RoleTypeCreator.wrapTypeWithAnchorFromName(typeToWrap, anchorName, site, environment); } }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.BytecodeTransformer.java
License:Open Source License
/** * Add a byte code sequence that is a placeholder for chaining the * marker arg if the current method is copied lateron. * (See class comment in class ExplicitConstructorCall). * * @param scope/* ww w.j a va 2 s. com*/ * @param codeStream * @param chainTSuperMarkArgPos position that a marker arg will get when added. */ public static void addChainingPlaceholder(BlockScope scope, CodeStream codeStream, int chainTSuperMarkArgPos) { // create local variable "Object _OT$chainArg" // at the very position that will be taken by an added // marker argument: LocalVariableBinding nullVar = new LocalVariableBinding("_OT$chainArg".toCharArray(), //$NON-NLS-1$ scope.getJavaLangObject(), 0, false); nullVar.resolvedPosition = chainTSuperMarkArgPos; nullVar.useFlag = LocalVariableBinding.USED; nullVar.declaringScope = scope.methodScope(); codeStream.record(nullVar); codeStream.addVisibleLocalVariable(nullVar); // add dummy code sequence "aconst_null; astore <i>" // which will be changed by BytecodeTransformer.replaceChainArg // to "nop; aload <i>" with the same <i>. codeStream.aconst_null(); codeStream.astore(chainTSuperMarkArgPos); // optimize small indices? // record positions for local varaible table. nullVar.recordInitializationStartPC(0); if (nullVar.initializationPCs != null) nullVar.recordInitializationEndPC(codeStream.position); }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lifting.Lowering.java
License:Open Source License
@NonNull LocalVariableBinding makeNewLocal(BlockScope scope, TypeBinding variableType, int sourceStart, int sourceEnd, boolean deferredResolve) { char[] name = ("_OT$unlowered$" + sourceStart).toCharArray(); //$NON-NLS-1$ LocalVariableBinding varBinding = new LocalVariableBinding(name, variableType, 0, false); varBinding.declaration = new LocalDeclaration(name, sourceStart, sourceEnd); // needed for BlockScope.computeLocalVariablePositions() -> CodeStream.record() if (!deferredResolve) scope.addLocalVariable(varBinding); varBinding.setConstant(Constant.NotAConstant); varBinding.useFlag = LocalVariableBinding.USED; return varBinding; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticRoleFieldAccess.java
License:Open Source License
private LocalVariableBinding createArgumentBinding(CodeStream codeStream, char[] argName, TypeBinding argType, int pos) { LocalVariableBinding argBinding = new LocalVariableBinding(argName, argType, 0, true); argBinding.resolvedPosition = pos;//from w ww. j av a 2 s . c o m // declaration needed because otherwise completeCodeAttributeForSyntheticMethod // would refuse to generate the local variable entry argBinding.declaration = new Argument(argName, 0, null, 0); codeStream.addVisibleLocalVariable(argBinding); codeStream.record(argBinding); argBinding.recordInitializationStartPC(0); return argBinding; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticRoleFieldAccess.java
License:Open Source License
/** * Generate the sequence for invoking this accessor. * * PRE: the role instance is on the stack, for write access also the new value * POST: values from PRE have been consumed, for read access the value is on the stack * * @param codeStream//from w w w .j av a2 s. co m */ public byte prepareOrGenerateInvocation(CodeStream codeStream, byte opcode) { ReferenceBinding roleType = (ReferenceBinding) this.parameters[0]; if (roleType instanceof UnresolvedReferenceBinding) { try { roleType = ((UnresolvedReferenceBinding) roleType).resolve(Config.getLookupEnvironment(), false); } catch (NotConfiguredException e) { e.logWarning("Failed to generate accessor"); //$NON-NLS-1$ return opcode; } this.parameters[0] = roleType; } if (this.purpose == FieldReadAccess || this.purpose == SuperFieldReadAccess) { insertOuterAccess(codeStream, roleType); // role -> role,team codeStream.swap(); // role,team -> team,role codeStream.invoke(Opcodes.OPC_invokevirtual, this, // team,role -> result this.declaringClass); } else { TypeBinding targetType = this.targetWriteField.type; LocalVariableBinding arg = new LocalVariableBinding("<tmp>".toCharArray(), //$NON-NLS-1$ targetType, 0, false); arg.resolvedPosition = codeStream.maxLocals; arg.useFlag = LocalVariableBinding.USED; codeStream.record(arg); arg.recordInitializationStartPC(codeStream.position); codeStream.store(arg, false/*valueRequired*/); // role, arg -> role insertOuterAccess(codeStream, roleType); // role -> role,team codeStream.swap(); // role,team -> team,role codeStream.load(arg); // -> team,role,arg codeStream.invoke(Opcodes.OPC_invokevirtual, this, // -> <empty> this.declaringClass); if (arg.initializationPCs != null) // null checking is asymmetric in LocalVariableBinding. arg.recordInitializationEndPC(codeStream.position); } return 0; // done }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator.java
License:Open Source License
static TypeBinding internalWrapQualifiedRoleType(final Scope scope, final Expression anchorExpr, TypeBinding originalType, final ASTNode typedNode, ReferenceBinding refBinding, int dimensions) { ReferenceBinding site = scope.enclosingSourceType(); assert (!(site == null)); boolean needAnchor = true; // already wrapped? ITeamAnchor existingAnchor = retrieveAnchor(refBinding); if (existingAnchor == null) { if (!refBinding.isDirectRole()) return originalType.maybeWrapRoleType(typedNode, new TypeArgumentUpdater() { public TypeBinding updateArg(ReferenceBinding arg) { return maybeWrapQualifiedRoleType(scope, anchorExpr, arg, typedNode); }//from w w w . j a va 2 s . c o m }); } else { if (!(existingAnchor instanceof TThisBinding)) { // possibly have two significant anchors.. // if a relevant anchor exists, we could well be content with typeToWrap! needAnchor = false; } else { // do handle tthis RoleTypeBindings, too, because we might need to // set a new anchor // (report errors only, if this type is not already acceptable). needAnchor = (TeamModel.findEnclosingTeamContainingRole(site, refBinding) == null); } } ProblemReporter problemReporter = scope.problemReporter(); ITeamAnchor variableBinding = getAnchorVariableBinding(site, anchorExpr, refBinding, needAnchor ? problemReporter : null, // no reporting if not needed typedNode); // only report one error (referenceContext is reset during reporting) if (problemReporter.referenceContext == null) { class NullReporter extends ProblemReporter { NullReporter(ProblemReporter orig) { super(orig.policy, orig.options, orig.problemFactory); } @Override public void handle(int problemId, String[] problemArguments, int elaborationId, String[] messageArguments, int severity, int problemStartPosition, int problemEndPosition, ReferenceContext context, CompilationResult unitResult) { /* NO-OP! */ } } problemReporter = new NullReporter(problemReporter); } // report errors: boolean decapsulationAllowed = false; if (typedNode instanceof Expression) decapsulationAllowed = ((Expression) typedNode).getBaseclassDecapsulation().isAllowed(); if ((variableBinding instanceof LocalVariableBinding) // note that for FieldBinding Bit63L has a different meaning! && (((LocalVariableBinding) variableBinding).tagBits & TagBits.IsFreshTeamInstance) != 0) { if (!refBinding.isRoleType()) return variableBinding.getDependentTypeBinding(refBinding, -1, null, dimensions); return originalType; } else if (variableBinding == null) { if (needAnchor) problemReporter.missingTypeAnchor(typedNode, refBinding); } else if (variableBinding == RoleTypeBinding.NoAnchor) { if (existingAnchor != null) { variableBinding = TeamAnchor.maybeImproveAnchor(site, existingAnchor, anchorExpr); if (variableBinding != null && variableBinding != existingAnchor) return variableBinding.getRoleTypeBinding(refBinding, dimensions); return originalType; } if (needAnchor) problemReporter.noTeamAnchorInScope(anchorExpr, refBinding); } else { if (!variableBinding.isFinal()) { // old version: directly report: //problemReporter.anchorPathNotFinal(anchorExpr, variableBinding, refBinding.sourceName()); // new version: don't complain now but use a non-compatible anchor: TypeBinding variableType = variableBinding.getResolvedType(); if (variableType.isRole()) variableType = ((ReferenceBinding) variableType).getRealClass(); // will be asked for members later variableBinding = new LocalVariableBinding(variableBinding.internalName(), variableType, ClassFileConstants.AccFinal, false) { @Override public int problemId() { return IProblem.AnchorNotFinal; } }; } if (!(variableBinding instanceof TThisBinding) && !isThisLike(anchorExpr) && !refBinding.isPublic() && !decapsulationAllowed) { problemReporter.externalizingNonPublicRole(typedNode, refBinding); } else { if (existingAnchor != null && !(existingAnchor instanceof TThisBinding) && !existingAnchor.hasSameBestNameAs(variableBinding)) { variableBinding = TeamAnchor.maybeImproveAnchor(site, existingAnchor, anchorExpr); if (variableBinding == null) return originalType; // cannot merge anchors -> original type cannot be improved. } // delegate to the principal function: TypeBinding[] typeArguments = refBinding.isParameterizedType() ? ((ParameterizedTypeBinding) refBinding).arguments : null; return getAnchoredType(scope, typedNode, variableBinding, refBinding, typeArguments, dimensions); } } return originalType; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator.java
License:Open Source License
/** * Extract a variable binding from an expression, which is * suitable as an anchor for a role type. * * Note, that checking for final is not done here! * * @param site context for type name resolution * @param anchorExpr should refer to a (final) variable holding a Team instance * @param roleType Use this if the anchor expression is 'this' to * retrieve the appropriate tthis binding. * @param problemReporter for error reporting or null (no reporting) * @param typedNode expression whose type is currently being resolved (only for error positions) * @return a valid anchor or NoAnchor(reported via cannotWrap) or null (also reported) *//*w ww .j a va 2 s . c om*/ public static ITeamAnchor getAnchorVariableBinding(ReferenceBinding site, /*nonnull*/ Expression anchorExpr, ReferenceBinding roleType, ProblemReporter problemReporter, ASTNode typedNode) { ITeamAnchor anchorBinding = null; // unwrap meaningless cast: if (anchorExpr instanceof CastExpression) { CastExpression cast = (CastExpression) anchorExpr; if (RoleTypeBinding.isRoleWithExplicitAnchor(cast.resolvedType)) anchorBinding = ((RoleTypeBinding) cast.resolvedType)._teamAnchor; else anchorExpr = ((CastExpression) anchorExpr).expression; } if (anchorExpr instanceof PotentialLowerExpression) anchorExpr = ((PotentialLowerExpression) anchorExpr).expression; if (anchorExpr instanceof ThisReference) { ReferenceBinding teamBinding = (ReferenceBinding) anchorExpr.resolvedType; ReferenceBinding enclosingTeam = TeamModel.findEnclosingTeamContainingRole(teamBinding, roleType); if (enclosingTeam == null) { if ((problemReporter != null)) { ASTNode location = anchorExpr; if (location.sourceEnd == 0) location = typedNode; problemReporter.typeAnchorNotEnclosingTeam(location, teamBinding, roleType); } return null; } anchorBinding = TThisBinding.getTThisForRole(roleType, enclosingTeam); if (anchorBinding == null) return cannotWrapType(roleType, problemReporter, typedNode); } else { // extract the name reference from a type anchor reference used as expression: if (anchorExpr instanceof TypeAnchorReference && ((TypeAnchorReference) anchorExpr).isExpression) { anchorExpr = ((TypeAnchorReference) anchorExpr).anchor; } if (anchorExpr instanceof ArrayReference) anchorExpr = ((ArrayReference) anchorExpr).receiver; if (anchorExpr instanceof FieldReference) { anchorBinding = ((Reference) anchorExpr).fieldBinding(); } else if (anchorExpr.isTypeReference()) { anchorBinding = null; // not an instance: not usable. ReferenceBinding teamBinding = TeamModel.findEnclosingTeamContainingRole(site, roleType); if (teamBinding == null) { if ((problemReporter != null)) problemReporter.missingTypeAnchor(anchorExpr, roleType); return null; } anchorBinding = TThisBinding.getTThisForRole(roleType, teamBinding); if (anchorBinding == null) { if ((problemReporter != null)) problemReporter.typeAnchorIsNotAVariable(anchorExpr, roleType.sourceName()); return null; } } else if (anchorExpr instanceof NameReference) { if (anchorExpr instanceof QualifiedNameReference) { QualifiedNameReference qRef = (QualifiedNameReference) anchorExpr; anchorBinding = getAnchorFromQualifiedReceiver(site, roleType, (VariableBinding) qRef.binding, qRef.otherBindings, /*mergePaths*/false, problemReporter, anchorExpr, qRef.sourcePositions); if (anchorBinding == null) return RoleTypeBinding.NoAnchor; // already reported } else { if (((NameReference) anchorExpr).binding instanceof VariableBinding) { anchorBinding = (ITeamAnchor) ((NameReference) anchorExpr).binding; if (roleType.isTypeVariable()) { ITeamAnchor[] anchors = ((TypeVariableBinding) roleType).anchors; if (anchors != null) return anchorBinding; // avoid analysis which requires knowledge about the role type } // FIXME(SH): manual resolving of base-anchor? // if (CharOperation.equals(((SingleNameReference)anchorExpr).token, IOTConstants._OT_BASE)) // { // ReferenceBinding anchorSite = ((FieldBinding)anchorBinding).declaringClass; // if ( anchorSite != site && // site.isCompatibleWith(anchorSite)) { // anchorBinding = new FieldBinding((FieldBinding)anchorBinding, site); // ((FieldBinding)anchorBinding).type = site.baseclass(); // } // } } else { if ((problemReporter != null)) problemReporter.typeAnchorIsNotAVariable(anchorExpr, roleType.sourceName()); return null; } } } else if (anchorExpr instanceof QualifiedAllocationExpression) { // propagate anchor from resolved type: QualifiedAllocationExpression allocation = (QualifiedAllocationExpression) anchorExpr; return ((RoleTypeBinding) allocation.resolvedType)._teamAnchor; } else if (anchorExpr instanceof MessageSend) { TypeBinding receiverLeaf = ((MessageSend) anchorExpr).actualReceiverType.leafComponentType(); if (RoleTypeBinding.isRoleWithExplicitAnchor(receiverLeaf)) { anchorBinding = ((RoleTypeBinding) receiverLeaf)._teamAnchor; } else { // regression fix during work on https://bugs.eclipse.org/331877 if (anchorExpr.resolvedType != null && anchorExpr.resolvedType.isRoleType()) return ((DependentTypeBinding) anchorExpr.resolvedType)._teamAnchor; return cannotWrapType(roleType, problemReporter, typedNode); } } else if (anchorExpr instanceof AllocationExpression) { // this anchor matches nothing String displayName = "fresh-instance-of-" + ((AllocationExpression) anchorExpr).type.toString(); //$NON-NLS-1$ LocalVariableBinding fakeVariable = new LocalVariableBinding(displayName.toCharArray(), roleType.enclosingType(), ClassFileConstants.AccFinal, false); fakeVariable.tagBits |= TagBits.IsFreshTeamInstance; return fakeVariable; } else if (anchorBinding == null) { return cannotWrapType(roleType, problemReporter, typedNode); } /* * anchorBinding = non-null * FieldReference * NameReference * isTypeReference() -> TThisBinding */ assert (anchorBinding != null); } /* * variableBinding = non-null, anchorType = non-null: * ThisReference * + all others that did not already quit with an error. */ // if ((problemReporter != null)) // assert anchorBinding != null; // redundant if (!anchorBinding.isTeamContainingRole(roleType)) { anchorBinding = anchorBinding.retrieveAnchorFromAnchorRoleTypeFor(roleType); if (anchorBinding == null) { if (roleType instanceof DependentTypeBinding && ((DependentTypeBinding) roleType).hasExplicitAnchor()) return cannotWrapType(roleType, problemReporter, typedNode); // not improved ReferenceBinding teamBinding = TeamModel.findEnclosingTeamContainingRole(site, roleType); if (teamBinding == null) return cannotWrapType(roleType, problemReporter, typedNode); anchorBinding = TThisBinding.getTThisForRole(roleType, teamBinding); } } assert (anchorBinding != null); return anchorBinding.asAnchorFor(roleType); }