Example usage for org.eclipse.jdt.internal.compiler.lookup LocalVariableBinding LocalVariableBinding

List of usage examples for org.eclipse.jdt.internal.compiler.lookup LocalVariableBinding LocalVariableBinding

Introduction

In this page you can find the example usage for org.eclipse.jdt.internal.compiler.lookup LocalVariableBinding LocalVariableBinding.

Prototype

public LocalVariableBinding(LocalDeclaration declaration, TypeBinding type, int modifiers,
            MethodScope declaringScope) 

Source Link

Usage

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);
}