Example usage for org.eclipse.jdt.internal.compiler.lookup Binding LOCAL

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

Introduction

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

Prototype

int LOCAL

To view the source code for org.eclipse.jdt.internal.compiler.lookup Binding LOCAL.

Click Source Link

Usage

From source file:com.codenvy.ide.ext.java.server.internal.core.search.matching.PackageReferenceLocator.java

License:Open Source License

protected int resolveLevel(QualifiedNameReference qNameRef) {
    TypeBinding typeBinding = null;/*w  ww. j  a  va2  s .c o  m*/
    switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) {
    case Binding.FIELD: // reading a field
        if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 3 : qNameRef.otherBindings.length + 3))
            return IMPOSSIBLE_MATCH; // must be at least p1.A.x
        typeBinding = qNameRef.actualReceiverType;
        break;
    case Binding.LOCAL: // reading a local variable
        return IMPOSSIBLE_MATCH; // no package match in it
    case Binding.TYPE: //=============only type ==============
        if (qNameRef.binding instanceof TypeBinding)
            typeBinding = (TypeBinding) qNameRef.binding;
        break;
    /*
     * Handling of unbound qualified name references. The match may reside in the resolved fragment,
     * which is recorded inside the problem binding, along with the portion of the name until it became a problem.
     */
    case Binding.VARIABLE: //============unbound cases===========
    case Binding.TYPE | Binding.VARIABLE:
        Binding binding = qNameRef.binding;
        if (binding instanceof ProblemReferenceBinding) {
            typeBinding = (TypeBinding) binding;
        } else if (binding instanceof ProblemFieldBinding) {
            if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 3
                    : qNameRef.otherBindings.length + 3))
                return IMPOSSIBLE_MATCH; // must be at least p1.A.x
            typeBinding = qNameRef.actualReceiverType;
        } else if (binding instanceof ProblemBinding) {
            ProblemBinding pbBinding = (ProblemBinding) binding;
            if (CharOperation.occurencesOf('.', pbBinding.name) <= 0) // index of last bound token is one before the pb token
                return INACCURATE_MATCH;
            typeBinding = pbBinding.searchType;
        }
        break;
    }
    return resolveLevel(typeBinding);
}

From source file:com.codenvy.ide.ext.java.server.internal.core.search.matching.TypeReferenceLocator.java

License:Open Source License

protected int resolveLevel(NameReference nameRef) {
    Binding binding = nameRef.binding;

    if (nameRef instanceof SingleNameReference) {
        if (binding instanceof ProblemReferenceBinding)
            binding = ((ProblemReferenceBinding) binding).closestMatch();
        if (binding instanceof ReferenceBinding)
            return resolveLevelForType((ReferenceBinding) binding);
        return binding == null || binding instanceof ProblemBinding ? INACCURATE_MATCH : IMPOSSIBLE_MATCH;
    }//from  w  ww  . j  a v  a  2s.c o m

    TypeBinding typeBinding = null;
    QualifiedNameReference qNameRef = (QualifiedNameReference) nameRef;
    switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) {
    case Binding.FIELD: // reading a field
        if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 2 : qNameRef.otherBindings.length + 2))
            return IMPOSSIBLE_MATCH; // must be at least A.x
        typeBinding = nameRef.actualReceiverType;
        break;
    case Binding.LOCAL: // reading a local variable
        return IMPOSSIBLE_MATCH; // no type match in it
    case Binding.TYPE: //=============only type ==============
        if (binding instanceof TypeBinding)
            typeBinding = (TypeBinding) binding;
        break;
    /*
     * Handling of unbound qualified name references. The match may reside in the resolved fragment,
     * which is recorded inside the problem binding, along with the portion of the name until it became a problem.
     */
    case Binding.VARIABLE: //============unbound cases===========
    case Binding.TYPE | Binding.VARIABLE:
        if (binding instanceof ProblemReferenceBinding) {
            typeBinding = (TypeBinding) binding;
        } else if (binding instanceof ProblemFieldBinding) {
            if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 2
                    : qNameRef.otherBindings.length + 2))
                return IMPOSSIBLE_MATCH; // must be at least A.x
            typeBinding = nameRef.actualReceiverType;
        } else if (binding instanceof ProblemBinding) {
            ProblemBinding pbBinding = (ProblemBinding) binding;
            if (CharOperation.occurencesOf('.', pbBinding.name) <= 0) // index of last bound token is one before the pb token
                return INACCURATE_MATCH;
            typeBinding = pbBinding.searchType;
        }
        break;
    }
    return resolveLevel(typeBinding);
}

From source file:org.eclipse.ajdt.core.parserbridge.AJSourceElementParser2.java

License:Open Source License

public NameReference getUnspecifiedReferenceOptimized() {
    /* build a (unspecified) NameReference which may be qualified
    The optimization occurs for qualified reference while we are
    certain in this case the last item of the qualified name is
    a field access. This optimization is IMPORTANT while it results
    that when a NameReference is build, the type checker should always
    look for that it is not a type reference */

    int length;/* www  .j av a2 s  .com*/
    if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
        // single variable reference
        SingleNameReference ref = newSingleNameReference(identifierStack[identifierPtr],
                identifierPositionStack[identifierPtr--]);
        ref.bits &= ~ASTNode.RestrictiveFlagMASK;
        ref.bits |= Binding.LOCAL | Binding.FIELD;
        if (reportReferenceInfo) {
            this.addUnknownRef(ref);
        }
        return ref;
    }

    //Qualified-variable-reference
    //In fact it is variable-reference DOT field-ref , but it would result in a type
    //conflict tha can be only reduce by making a superclass (or inetrface ) between
    //nameReference and FiledReference or putting FieldReference under NameReference
    //or else..........This optimisation is not really relevant so just leave as it is

    char[][] tokens = new char[length][];
    identifierPtr -= length;
    System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
    long[] positions = new long[length];
    System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
    QualifiedNameReference ref = newQualifiedNameReference(tokens, positions,
            (int) (identifierPositionStack[identifierPtr + 1] >> 32),
            // sourceStart
            (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
    ref.bits &= ~ASTNode.RestrictiveFlagMASK;
    ref.bits |= Binding.LOCAL | Binding.FIELD;
    if (reportReferenceInfo) {
        this.addUnknownRef(ref);
    }
    return ref;
}

From source file:org.eclipse.jdt.internal.compiler.parser.Parser.java

License:Open Source License

protected NameReference getUnspecifiedReferenceOptimized() {
    /* build a (unspecified) NameReference which may be qualified
    The optimization occurs for qualified reference while we are
    certain in this case the last item of the qualified name is
    a field access. This optimization is IMPORTANT while it results
    that when a NameReference is build, the type checker should always
    look for that it is not a type reference */

    int length;// w  w w.j  a v  a2  s  .c om
    NameReference ref;
    if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1) {
        // single variable reference
        ref = new SingleNameReference(this.identifierStack[this.identifierPtr],
                this.identifierPositionStack[this.identifierPtr--]);
        ref.bits &= ~ASTNode.RestrictiveFlagMASK;
        ref.bits |= Binding.LOCAL | Binding.FIELD;
        return ref;
    }

    //Qualified-variable-reference
    //In fact it is variable-reference DOT field-ref , but it would result in a type
    //conflict tha can be only reduce by making a superclass (or inetrface ) between
    //nameReference and FiledReference or putting FieldReference under NameReference
    //or else..........This optimisation is not really relevant so just leave as it is

    char[][] tokens = new char[length][];
    this.identifierPtr -= length;
    System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
    long[] positions = new long[length];
    System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
    ref = new QualifiedNameReference(tokens, positions,
            (int) (this.identifierPositionStack[this.identifierPtr + 1] >> 32), // sourceStart
            (int) this.identifierPositionStack[this.identifierPtr + length]); // sourceEnd
    ref.bits &= ~ASTNode.RestrictiveFlagMASK;
    ref.bits |= Binding.LOCAL | Binding.FIELD;
    return ref;
}

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 ww  . j a v a2  s  . c  om
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.ast.ResultReference.java

License:Open Source License

/**
 * Create a ResultReference by copying from a SingleNameReference
 * @param ref template//from  w  w w.ja va  2 s.  c o m
 * @param mapping link it with this mapping.
 */
public ResultReference(SingleNameReference ref, AbstractMethodMappingDeclaration mapping) {
    super(ref.token, ((long) ref.sourceStart << 32) + ref.sourceEnd);
    this.bits = Binding.LOCAL; // restrictiveFlag (from NameReference)
    this._mapping = mapping;
    this.constant = Constant.NotAConstant;
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.TypeAnchorReference.java

License:Open Source License

@Override
public TypeBinding resolveType(BlockScope scope, boolean checkBounds, int location) {
    if (!this.isExpression) {
        scope.problemReporter().valueParamWrongPosition(this);
        return null;
    }/*from w w  w  . j a  v  a  2s. c  o  m*/
    // support to interpret this reference as an expression (see CalloutImplementor)
    ITeamAnchor binding = resolveAnchor(scope);
    if (binding == null)
        return null;
    if (binding.isValidBinding()) {
        ReferenceBinding receiverType = null;
        int bit = Binding.LOCAL;
        if (binding instanceof FieldBinding) {
            bit = Binding.FIELD;
            receiverType = ((FieldBinding) binding).declaringClass;
        }
        this.bits &= ~RestrictiveFlagMASK;
        this.bits |= bit;
        this.anchor.bits &= ~RestrictiveFlagMASK;
        this.anchor.bits |= bit;
        this.constant = Constant.NotAConstant;
        this.anchor.constant = Constant.NotAConstant;
        int depth = 0;
        if (receiverType != null && this.anchor instanceof InvocationSite) { // could be QualifiedBaseReference which sets its depth during resolveAnchor
            ReferenceBinding currentType = scope.enclosingSourceType();
            while (!currentType.isCompatibleWith(receiverType)) {
                depth++;
                currentType = currentType.enclosingType();
                if (currentType == null)
                    return null; // shouldn't happen, if callout was constructed correctly.
            }
            ((InvocationSite) this.anchor).setDepth(depth);
        }
    }
    return this.resolvedType = binding.getResolvedType();
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.TypeAnchorReference.java

License:Open Source License

ITeamAnchor resolveAnchor(Scope scope, Reference reference) {
    ITeamAnchor prefix = null;//  w  ww .  j  a v  a 2s. c o m
    ITeamAnchor currentAnchor = null;
    char[] currentToken = null; // for lookup and creation of problem binding

    // be careful not to trigger fields() which may be where we are called from!
    if (reference instanceof SingleNameReference) {
        SingleNameReference singleAnchor = (SingleNameReference) reference;
        currentToken = singleAnchor.token;
        currentAnchor = findVariable(scope, currentToken, scope.isStatic(), singleAnchor.sourceStart,
                singleAnchor.sourceEnd);
        this.anchor.bits |= (this.bits & DepthMASK);
        // could be ProblemAnchorBinding
    } else if (reference instanceof FieldReference) {
        FieldReference fieldRef = (FieldReference) reference;
        Expression prefixExpr = fieldRef.receiver;
        if (!(prefixExpr instanceof Reference))
            throw new InternalCompilerError("Unexpected anchor prefix " + prefixExpr); //$NON-NLS-1$
        prefix = resolveAnchor(scope, (Reference) prefixExpr);
        currentToken = fieldRef.token;
        // fieldRef holds on to problem binding:
        fieldRef.binding = TypeAnalyzer.findField(((ReferenceBinding) prefix.getResolvedType()).getRealClass(),
                currentToken, false/*static*/, true/*outer*/);
        currentAnchor = checkAnchor(scope, reference, currentToken, reference.sourceStart, reference.sourceEnd,
                fieldRef.binding);
    } else if (reference instanceof QualifiedBaseReference) {
        QualifiedBaseReference baseRef = (QualifiedBaseReference) reference;
        if (scope instanceof BlockScope)
            baseRef.resolveType((BlockScope) scope);
        else
            baseRef.resolveType((ClassScope) scope);
        currentAnchor = baseRef.baseField;
    } else if (reference instanceof QualifiedThisReference) {
        QualifiedThisReference thisRef = (QualifiedThisReference) reference;
        if (scope instanceof BlockScope)
            thisRef.resolveType((BlockScope) scope);
        else
            thisRef.resolveType((ClassScope) scope);
        if (thisRef.resolvedType.isTeam())
            currentAnchor = ((ReferenceBinding) thisRef.resolvedType).getTeamModel().getTThis();
    } else {
        boolean haveReportedProblem = false;
        long currentPos = 0;

        QualifiedNameReference qualifiedAnchor = (QualifiedNameReference) reference;
        char[][] tokens = qualifiedAnchor.tokens;
        currentToken = tokens[tokens.length - 1]; // default, so we never use null name for problem binding
        // check maximal static prefix:
        Binding staticPrefix = null;
        int j;
        for (j = 1; j <= tokens.length; j++) {
            Binding current = scope.getTypeOrPackage(CharOperation.subarray(tokens, 0, j));
            if (current == null || !current.isValidBinding())
                break;
            else
                staticPrefix = current;
        }
        if (j > tokens.length) {
            scope.problemReporter().typeAnchorReferenceNotAValue(reference);
            haveReportedProblem = true;
        } else {
            // find first field:
            if (staticPrefix != null) {
                currentPos = qualifiedAnchor.sourcePositions[j - 1];
                currentToken = tokens[j - 1];
                if (staticPrefix instanceof ReferenceBinding) {
                    currentAnchor = TypeAnalyzer.findField(((ReferenceBinding) staticPrefix).getRealClass(),
                            currentToken, /*static*/true, /*outer*/true);
                } else {
                    scope.problemReporter().typeAnchorReferenceNotAnObjectRef((int) (currentPos >>> 32),
                            (int) currentPos);
                    haveReportedProblem = true;
                }
            } else {
                currentPos = qualifiedAnchor.sourcePositions[0];
                currentToken = tokens[0];
                currentAnchor = findVariable(scope, currentToken, scope.isStatic(), (int) (currentPos >>> 32),
                        (int) currentPos);
                haveReportedProblem = currentAnchor == null;
            }
            if (currentAnchor != null) {
                if (!currentAnchor.hasValidReferenceType()) {
                    if (j < tokens.length) // would need to process more tokens?
                        currentAnchor = null; // replace with problem binding below
                } else {
                    // find more fields:
                    for (int i = j; i < tokens.length; i++) {
                        TypeBinding fieldType = currentAnchor.getResolvedType().leafComponentType();
                        if (fieldType instanceof SourceTypeBinding) {
                            SourceTypeBinding stb = (SourceTypeBinding) fieldType;
                            if ((stb.scope != null)
                                    && (stb.scope.compilationUnitScope() != scope.compilationUnitScope())
                                    && (stb.tagBits & (TagBits.BeginHierarchyCheck
                                            | TagBits.EndHierarchyCheck)) == (TagBits.BeginHierarchyCheck
                                                    | TagBits.EndHierarchyCheck)
                                    && StateHelper.isReadyToProcess(stb,
                                            ITranslationStates.STATE_LENV_DONE_FIELDS_AND_METHODS))
                                Dependencies.ensureBindingState(stb,
                                        ITranslationStates.STATE_LENV_DONE_FIELDS_AND_METHODS);
                        }
                        currentPos = qualifiedAnchor.sourcePositions[i];
                        currentToken = tokens[i];
                        FieldBinding nextField = currentAnchor.getFieldOfType(currentToken, /*static*/false,
                                true);
                        if (nextField == null || !nextField.hasValidReferenceType()) {
                            currentAnchor = null; // replace with problem binding below
                            break;
                        }
                        currentAnchor = nextField.setPathPrefix(currentAnchor);
                    }
                }
            }
        }
        if (!haveReportedProblem) {
            if (currentAnchor == null) {
                scope.problemReporter().typeAnchorNotFound(currentToken, (int) (currentPos >>> 32),
                        (int) currentPos);
            } else if (!currentAnchor.hasValidReferenceType()) {
                scope.problemReporter().typeAnchorReferenceNotAnObjectRef((int) (currentPos >>> 32),
                        (int) currentPos);
            }
        }
    }
    if (currentAnchor == null) {
        currentAnchor = new ProblemFieldBinding(scope.enclosingReceiverType(), currentToken,
                ProblemReasons.NotFound);
        ((FieldBinding) currentAnchor).type = reference.resolvedType = new ProblemReferenceBinding(
                "UnresolvedType".toCharArray(), null, ProblemReasons.NotFound); //$NON-NLS-1$
    } else if (currentAnchor.isValidBinding()) {
        if (prefix != null && !(prefix instanceof TThisBinding))
            currentAnchor = currentAnchor.setPathPrefix(prefix);

        // fill anchor with resolved data:
        reference.resolvedType = currentAnchor.getResolvedType();
        reference.bits &= ~RestrictiveFlagMASK; // clear bits
        if (currentAnchor instanceof FieldBinding) {
            reference.bits |= Binding.FIELD;
            // TODO(SH): must we remember a previous anchor to set this correctly?:
            if (reference instanceof NameReference)
                ((NameReference) reference).actualReceiverType = ((FieldBinding) currentAnchor).declaringClass;
            if (reference instanceof FieldReference)
                ((FieldReference) reference).actualReceiverType = ((FieldBinding) currentAnchor).declaringClass;
        } else {
            reference.bits |= Binding.LOCAL;
        }
        reference.constant = Constant.NotAConstant;
    }
    if (reference instanceof NameReference) {
        ((NameReference) reference).binding = (Binding) currentAnchor;
        ((NameReference) reference).resolveFinished();
    } else if (reference instanceof FieldReference) {
        ((FieldReference) reference).binding = (FieldBinding) currentAnchor;
        //TODO(SH): this method doesn't exist, is the call needed?
        //((FieldReference)this.anchor).resolveFinished();
    }
    return currentAnchor;
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lifting.Lowering.java

License:Open Source License

public Expression lowerExpression(final BlockScope scope, final Expression expression,
        TypeBinding unloweredType, TypeBinding requiredType, final Expression teamExpression,
        boolean needNullCheck, boolean deferredResolve) {
    // Note, unless deferredResolve, this method is responsible for 'resolving' all AST nodes it generates!

    int sourceStart = expression.sourceStart;
    int sourceEnd = expression.sourceEnd;
    AstGenerator gen = new AstGenerator(sourceStart, sourceEnd);

    unloweredType = TeamModel.strengthenRoleType(scope.enclosingSourceType(), unloweredType);
    Expression loweringExpr = null;

    TypeBinding expressionType = expression.resolvedType;
    // this assertion needed for pushing/casting using unchecked one-byte opcodes.
    assert expressionType == null || expressionType.leafComponentType() instanceof ReferenceBinding;

    LocalVariableBinding localVar = null;
    Expression unloweredExpression = expression;
    if (expression instanceof ThisReference || expression instanceof AllocationExpression)
        needNullCheck = false;//from w ww.  j  a v  a  2 s  .c  o m
    if (needNullCheck) {
        localVar = makeNewLocal(scope, unloweredType, sourceStart, sourceEnd, deferredResolve);
        SingleNameReference varRef = gen.singleNameReference(localVar.name);
        if (!deferredResolve) {
            varRef.binding = localVar;
            varRef.bits = Binding.LOCAL;
            varRef.constant = Constant.NotAConstant;
            varRef.resolvedType = unloweredType;
        }
        unloweredExpression = varRef;
    }

    if (unloweredType.isArrayType()) {
        // (1) array translation:
        ArrayLowering trans = new ArrayLowering(teamExpression);
        loweringExpr = trans.lowerArray(scope, unloweredExpression, unloweredType, requiredType,
                deferredResolve);
    } else {
        RoleTypeBinding roleType = (RoleTypeBinding) unloweredType;
        boolean needMethod = roleType.isRegularInterface()
                || !roleType.isSiblingRole(scope.enclosingSourceType());
        if (needMethod) {
            // (3) translation using _OT$.getBase() method:
            MessageSend callLower = gen.messageSend(unloweredExpression, IOTConstants._OT_GETBASE,
                    new Expression[0]);

            // manual resolving:
            if (!deferredResolve) {
                callLower.constant = Constant.NotAConstant;
                callLower.actualReceiverType = unloweredType;
                if (unloweredExpression.constant == null)
                    unloweredExpression.resolveType(scope);
                callLower.resolvedType = roleType.baseclass();

                callLower.binding = StandardElementGenerator.getGetBaseMethod(scope, roleType.roleModel,
                        roleType.baseclass());
            }
            loweringExpr = callLower;
        } else {
            // (2) translation using field _OT$base:
            FieldReference invokeBaseOnRole = new FieldReference(IOTConstants._OT_BASE,
                    (((long) sourceStart) << 32) + sourceEnd);
            ReferenceBinding roleClass = roleType.roleModel.getClassPartBinding();
            TypeReference classRef = gen.typeReference(roleClass);
            if (classRef != null) {
                // field access needs cast to the role-class.
                // FIXME(SH): use synthetic role field accessor instead!
                classRef.constant = Constant.NotAConstant;
                classRef.resolvedType = roleClass;
                CastExpression unloweredExpr;
                unloweredExpr = new CastExpression(unloweredExpression, classRef, CastExpression.NEED_CLASS);
                unloweredExpr.constant = Constant.NotAConstant;
                unloweredExpr.resolvedType = roleClass;
                unloweredExpr.bits |= ASTNode.GenerateCheckcast;
                invokeBaseOnRole.receiver = unloweredExpr;
            } else {
                invokeBaseOnRole.receiver = unloweredExpression;
            }

            invokeBaseOnRole.actualReceiverType = roleClass;
            invokeBaseOnRole.resolvedType = roleClass.baseclass();
            invokeBaseOnRole.binding = scope.findField(roleClass, IOTConstants._OT_BASE, invokeBaseOnRole,
                    true);
            invokeBaseOnRole.constant = Constant.NotAConstant;
            loweringExpr = invokeBaseOnRole;
        }
    }
    if (needNullCheck) {
        // ((local = (expression)) == null) ? (RequiredType)local : lower(local));
        @SuppressWarnings("null") // needNullCheck => localVar != null
        SingleNameReference lhs = gen.singleNameReference(localVar.name);
        Assignment assignment = gen.assignment(lhs, expression);
        loweringExpr = new CheckedLoweringExpression(expression, gen.nullCheck(assignment), gen.nullLiteral(),
                loweringExpr, localVar, teamExpression);
        if (!deferredResolve) {
            lhs.binding = localVar;
            lhs.resolvedType = unloweredType;
            lhs.bits = Binding.LOCAL | ASTNode.FirstAssignmentToLocal;
            assignment.constant = Constant.NotAConstant;
            loweringExpr.constant = Constant.NotAConstant;
            loweringExpr.resolvedType = requiredType;
        }
    }
    return loweringExpr;
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lookup.TeamAnchor.java

License:Open Source License

public TypeBinding getRoleTypeBinding(ReferenceBinding roleBinding, TypeBinding[] arguments, int dimensions) {
    if (kind() == Binding.LOCAL)
        ((LocalVariableBinding) this).useFlag = LocalVariableBinding.USED;

    if (RoleTypeBinding.isRoleWithExplicitAnchor(roleBinding)) {
        //         ITeamAnchor combinedAnchor = combineAnchors(this, ((RoleTypeBinding)roleBinding)._teamAnchor);
        //         if (combinedAnchor == null) {
        //            ITeamAnchor anchor = ((RoleTypeBinding)roleBinding)._teamAnchor;
        //            if (anchor.isPrefixLegal(roleBinding, this)) {
        //               //combinedAnchor = anchor.setPathPrefix(this);
        //               throw new InternalCompilerError("HERE!");
        //            } else {
        // FIXME(SH): who calls us with an RTB ?? is this strategy OK?
        // saw a call from FieldAccessSpec.resolveFeature() (improving anchor)
        return getRoleTypeBinding(roleBinding.getRealType(), arguments, dimensions);
        //            }
        //         }
        //         return combinedAnchor.getRoleTypeBinding(roleBinding.getRealType(), dimensions);
    }/*from w  ww. j  a  v a2 s . c om*/
    ReferenceBinding roleEnclosing = roleBinding.enclosingType();
    if (roleEnclosing != null
            && TypeBinding.notEquals(roleEnclosing.erasure(), leafReferenceType().getRealClass())) // i.e.: teams differ
    {
        //assert TeamModel.areCompatibleEnclosings(this.leafType(), roleEnclosing);
        // team of roleBinding is less specific than this anchor => requesting a weakened type
        ReferenceBinding strengthenedRole = (ReferenceBinding) TeamModel.strengthenRoleType(leafReferenceType(),
                roleBinding);
        if (TypeBinding.notEquals(strengthenedRole, roleBinding)) {// avoid infinite recursion if strengthening made no difference
            DependentTypeBinding strongRoleType = (DependentTypeBinding) getRoleTypeBinding(strengthenedRole,
                    arguments, 0);
            if (strongRoleType != null)
                return WeakenedTypeBinding.makeWeakenedTypeBinding(strongRoleType, roleBinding, dimensions);
        }
        if (dimensions == roleBinding.dimensions() && roleBinding instanceof DependentTypeBinding)
            return roleBinding;
    }

    int paramPosition = -1;
    if (roleBinding instanceof DependentTypeBinding)
        paramPosition = ((DependentTypeBinding) roleBinding)._valueParamPosition;

    if (roleBinding instanceof RoleTypeBinding)
        if (!this.isTeamContainingRole(roleBinding)) // need to switch to outer anchor?
            return this.asAnchorFor(roleBinding).getDependentTypeBinding(roleBinding, paramPosition, arguments,
                    dimensions, ((RoleTypeBinding) roleBinding).environment);

    if (roleBinding instanceof WeakenedTypeBinding) {
        if (((WeakenedTypeBinding) roleBinding)._teamAnchor == this)
            return roleBinding;
    }

    if (roleBinding instanceof ParameterizedTypeBinding)
        return getDependentTypeBinding(roleBinding, paramPosition, arguments, dimensions,
                ((ParameterizedTypeBinding) roleBinding).environment);
    return getDependentTypeBinding(roleBinding, paramPosition, arguments, dimensions);
}