Example usage for org.eclipse.jdt.internal.compiler.lookup MethodScope referenceMethod

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

Introduction

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

Prototype

public AbstractMethodDeclaration referenceMethod() 

Source Link

Document

Answer the reference method of this scope, or null if initialization scope or lambda scope.

Usage

From source file:com.codenvy.ide.ext.java.server.internal.core.util.HandleFactory.java

License:Open Source License

/**
 * Create handle by adding child to parent obtained by recursing into parent scopes.
 *//* w ww . j  av a  2 s .c o  m*/
private IJavaElement createElement(Scope scope, int elementPosition, ICompilationUnit unit,
        HashSet existingElements, HashMap knownScopes) {
    IJavaElement newElement = (IJavaElement) knownScopes.get(scope);
    if (newElement != null)
        return newElement;

    switch (scope.kind) {
    case Scope.COMPILATION_UNIT_SCOPE:
        newElement = unit;
        break;
    case Scope.CLASS_SCOPE:
        IJavaElement parentElement = createElement(scope.parent, elementPosition, unit, existingElements,
                knownScopes);
        switch (parentElement.getElementType()) {
        case IJavaElement.COMPILATION_UNIT:
            newElement = ((ICompilationUnit) parentElement)
                    .getType(new String(scope.enclosingSourceType().sourceName));
            break;
        case IJavaElement.TYPE:
            newElement = ((IType) parentElement).getType(new String(scope.enclosingSourceType().sourceName));
            break;
        case IJavaElement.FIELD:
        case IJavaElement.INITIALIZER:
        case IJavaElement.METHOD:
            IMember member = (IMember) parentElement;
            if (member.isBinary()) {
                return null;
            } else {
                newElement = member.getType(new String(scope.enclosingSourceType().sourceName), 1);
                // increment occurrence count if collision is detected
                if (newElement != null) {
                    while (!existingElements.add(newElement))
                        ((SourceRefElement) newElement).occurrenceCount++;
                }
            }
            break;
        }
        if (newElement != null) {
            knownScopes.put(scope, newElement);
        }
        break;
    case Scope.METHOD_SCOPE:
        IType parentType = (IType) createElement(scope.parent, elementPosition, unit, existingElements,
                knownScopes);
        MethodScope methodScope = (MethodScope) scope;
        if (methodScope.isInsideInitializer()) {
            // inside field or initializer, must find proper one
            TypeDeclaration type = methodScope.referenceType();
            int occurenceCount = 1;
            int length = type.fields == null ? 0 : type.fields.length;
            for (int i = 0; i < length; i++) {
                FieldDeclaration field = type.fields[i];
                if (field.declarationSourceStart <= elementPosition
                        && elementPosition <= field.declarationSourceEnd) {
                    switch (field.getKind()) {
                    case AbstractVariableDeclaration.FIELD:
                    case AbstractVariableDeclaration.ENUM_CONSTANT:
                        newElement = parentType.getField(new String(field.name));
                        break;
                    case AbstractVariableDeclaration.INITIALIZER:
                        newElement = parentType.getInitializer(occurenceCount);
                        break;
                    }
                    break;
                } else if (field.getKind() == AbstractVariableDeclaration.INITIALIZER) {
                    occurenceCount++;
                }
            }
        } else {
            // method element
            AbstractMethodDeclaration method = methodScope.referenceMethod();
            newElement = parentType.getMethod(new String(method.selector),
                    Util.typeParameterSignatures(method));
            if (newElement != null) {
                knownScopes.put(scope, newElement);
            }
        }
        break;
    case Scope.BLOCK_SCOPE:
        // standard block, no element per se
        newElement = createElement(scope.parent, elementPosition, unit, existingElements, knownScopes);
        break;
    }
    return newElement;
}

From source file:org.eclipse.che.jdt.internal.core.util.HandleFactory.java

License:Open Source License

/**
 * Create handle by adding child to parent obtained by recursing into parent scopes.
 *//* ww  w  .  j a v a2 s .c  om*/
public IJavaElement createElement(Scope scope, int elementPosition, ICompilationUnit unit,
        HashSet existingElements, HashMap knownScopes) {
    IJavaElement newElement = (IJavaElement) knownScopes.get(scope);
    if (newElement != null)
        return newElement;

    switch (scope.kind) {
    case Scope.COMPILATION_UNIT_SCOPE:
        newElement = unit;
        break;
    case Scope.CLASS_SCOPE:
        IJavaElement parentElement = createElement(scope.parent, elementPosition, unit, existingElements,
                knownScopes);
        switch (parentElement.getElementType()) {
        case IJavaElement.COMPILATION_UNIT:
            newElement = ((ICompilationUnit) parentElement)
                    .getType(new String(scope.enclosingSourceType().sourceName));
            break;
        case IJavaElement.TYPE:
            newElement = ((IType) parentElement).getType(new String(scope.enclosingSourceType().sourceName));
            break;
        case IJavaElement.FIELD:
        case IJavaElement.INITIALIZER:
        case IJavaElement.METHOD:
            IMember member = (IMember) parentElement;
            if (member.isBinary()) {
                return null;
            } else {
                newElement = member.getType(new String(scope.enclosingSourceType().sourceName), 1);
                // increment occurrence count if collision is detected
                if (newElement != null) {
                    while (!existingElements.add(newElement))
                        ((SourceRefElement) newElement).occurrenceCount++;
                }
            }
            break;
        }
        if (newElement != null) {
            knownScopes.put(scope, newElement);
        }
        break;
    case Scope.METHOD_SCOPE:
        if (scope.isLambdaScope()) {
            parentElement = createElement(scope.parent, elementPosition, unit, existingElements, knownScopes);
            LambdaExpression expression = (LambdaExpression) scope.originalReferenceContext();
            if (expression.resolvedType != null && expression.resolvedType.isValidBinding()
                    && !(expression.descriptor instanceof ProblemMethodBinding)) { // chain in lambda element only if resolved properly.
                //newElement = new org.eclipse.jdt.internal.core.SourceLambdaExpression((JavaElement) parentElement, expression)
                // .getMethod();

                newElement = LambdaFactory.createLambdaExpression((JavaElement) parentElement, expression)
                        .getMethod();
                knownScopes.put(scope, newElement);
                return newElement;
            }
            return parentElement;
        }
        IType parentType = (IType) createElement(scope.parent, elementPosition, unit, existingElements,
                knownScopes);
        MethodScope methodScope = (MethodScope) scope;
        if (methodScope.isInsideInitializer()) {
            // inside field or initializer, must find proper one
            TypeDeclaration type = methodScope.referenceType();
            int occurenceCount = 1;
            int length = type.fields == null ? 0 : type.fields.length;
            for (int i = 0; i < length; i++) {
                FieldDeclaration field = type.fields[i];
                if (field.declarationSourceStart <= elementPosition
                        && elementPosition <= field.declarationSourceEnd) {
                    switch (field.getKind()) {
                    case AbstractVariableDeclaration.FIELD:
                    case AbstractVariableDeclaration.ENUM_CONSTANT:
                        newElement = parentType.getField(new String(field.name));
                        break;
                    case AbstractVariableDeclaration.INITIALIZER:
                        newElement = parentType.getInitializer(occurenceCount);
                        break;
                    }
                    break;
                } else if (field.getKind() == AbstractVariableDeclaration.INITIALIZER) {
                    occurenceCount++;
                }
            }
        } else {
            // method element
            AbstractMethodDeclaration method = methodScope.referenceMethod();
            newElement = parentType.getMethod(new String(method.selector),
                    Util.typeParameterSignatures(method));
            if (newElement != null) {
                knownScopes.put(scope, newElement);
            }
        }
        break;
    case Scope.BLOCK_SCOPE:
        // standard block, no element per se
        newElement = createElement(scope.parent, elementPosition, unit, existingElements, knownScopes);
        break;
    }
    return newElement;
}

From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java

License:Open Source License

final Binding getTypeOrPackage(char[] name, int mask, boolean needResolve) {
    Scope scope = this;
    ReferenceBinding foundType = null;/*w  w w. j  av a2s.  co  m*/
    boolean insideStaticContext = false;
    boolean insideTypeAnnotation = false;
    if ((mask & Binding.TYPE) == 0) {
        Scope next = scope;
        while ((next = scope.parent) != null)
            scope = next;
    } else {
        boolean inheritedHasPrecedence = compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
        done: while (true) { // done when a COMPILATION_UNIT_SCOPE is found
            switch (scope.kind) {
            case METHOD_SCOPE:
                MethodScope methodScope = (MethodScope) scope;
                AbstractMethodDeclaration methodDecl = methodScope.referenceMethod();
                if (methodDecl != null) {
                    if (methodDecl.binding != null) {
                        TypeVariableBinding typeVariable = methodDecl.binding.getTypeVariable(name);
                        if (typeVariable != null)
                            return typeVariable;
                    } else {
                        // use the methodDecl's typeParameters to handle problem cases when the method binding doesn't exist
                        TypeParameter[] params = methodDecl.typeParameters();
                        for (int i = params == null ? 0 : params.length; --i >= 0;)
                            if (CharOperation.equals(params[i].name, name))
                                if (params[i].binding != null && params[i].binding.isValidBinding())
                                    return params[i].binding;
                    }
                }
                insideStaticContext |= methodScope.isStatic;
                insideTypeAnnotation = methodScope.insideTypeAnnotation;
                //$FALL-THROUGH$
            case BLOCK_SCOPE:
                ReferenceBinding localType = ((BlockScope) scope).findLocalType(name); // looks in this scope only
                if (localType != null) {
                    if (foundType != null && foundType != localType)
                        return new ProblemReferenceBinding(new char[][] { name }, foundType,
                                ProblemReasons.InheritedNameHidesEnclosingName);
                    return localType;
                }
                break;
            case CLASS_SCOPE:
                SourceTypeBinding sourceType = ((ClassScope) scope).referenceContext.binding;
                if (scope == this && (sourceType.tagBits & TagBits.TypeVariablesAreConnected) == 0) {
                    // type variables take precedence over the source type, ex. class X <X> extends X == class X <Y> extends Y
                    // but not when we step out to the enclosing type
                    TypeVariableBinding typeVariable = sourceType.getTypeVariable(name);
                    if (typeVariable != null)
                        return typeVariable;
                    if (CharOperation.equals(name, sourceType.sourceName))
                        return sourceType;
                    insideStaticContext |= sourceType.isStatic();
                    break;
                }
                // member types take precedence over type variables
                if (!insideTypeAnnotation) {
                    // 6.5.5.1 - member types have precedence over top-level type in same unit
                    ReferenceBinding memberType = findMemberType(name, sourceType);
                    if (memberType != null) { // skip it if we did not find anything
                        if (memberType.problemId() == ProblemReasons.Ambiguous) {
                            if (foundType == null || foundType.problemId() == ProblemReasons.NotVisible)
                                // supercedes any potential InheritedNameHidesEnclosingName problem
                                return memberType;
                            // make the user qualify the type, likely wants the first inherited type
                            return new ProblemReferenceBinding(new char[][] { name }, foundType,
                                    ProblemReasons.InheritedNameHidesEnclosingName);
                        }
                        if (memberType.isValidBinding()) {
                            if (sourceType == memberType.enclosingType() || inheritedHasPrecedence) {
                                if (insideStaticContext && !memberType.isStatic() && sourceType.isGenericType())
                                    return new ProblemReferenceBinding(new char[][] { name }, memberType,
                                            ProblemReasons.NonStaticReferenceInStaticContext);
                                // found a valid type in the 'immediate' scope (i.e. not inherited)
                                // OR in 1.4 mode (inherited visible shadows enclosing)
                                if (foundType == null || (inheritedHasPrecedence
                                        && foundType.problemId() == ProblemReasons.NotVisible))
                                    return memberType;
                                // if a valid type was found, complain when another is found in an 'immediate' enclosing type (i.e. not inherited)
                                if (foundType.isValidBinding() && foundType != memberType)
                                    return new ProblemReferenceBinding(new char[][] { name }, foundType,
                                            ProblemReasons.InheritedNameHidesEnclosingName);
                            }
                        }
                        if (foundType == null || (foundType.problemId() == ProblemReasons.NotVisible
                                && memberType.problemId() != ProblemReasons.NotVisible))
                            // only remember the memberType if its the first one found or the previous one was not visible & memberType is...
                            foundType = memberType;
                    }
                }
                TypeVariableBinding typeVariable = sourceType.getTypeVariable(name);
                if (typeVariable != null) {
                    if (insideStaticContext) // do not consider this type modifiers: access is legite within same type
                        return new ProblemReferenceBinding(new char[][] { name }, typeVariable,
                                ProblemReasons.NonStaticReferenceInStaticContext);
                    return typeVariable;
                }
                insideStaticContext |= sourceType.isStatic();
                insideTypeAnnotation = false;
                if (CharOperation.equals(sourceType.sourceName, name)) {
                    if (foundType != null && foundType != sourceType
                            && foundType.problemId() != ProblemReasons.NotVisible)
                        return new ProblemReferenceBinding(new char[][] { name }, foundType,
                                ProblemReasons.InheritedNameHidesEnclosingName);
                    return sourceType;
                }
                break;
            case COMPILATION_UNIT_SCOPE:
                break done;
            }
            scope = scope.parent;
        }
        if (foundType != null && foundType.problemId() != ProblemReasons.NotVisible)
            return foundType;
    }

    // at this point the scope is a compilation unit scope
    CompilationUnitScope unitScope = (CompilationUnitScope) scope;
    HashtableOfObject typeOrPackageCache = unitScope.typeOrPackageCache;
    if (typeOrPackageCache != null) {
        Binding cachedBinding = (Binding) typeOrPackageCache.get(name);
        if (cachedBinding != null) { // can also include NotFound ProblemReferenceBindings if we already know this name is not found
            if (cachedBinding instanceof ImportBinding) { // single type import cached in faultInImports(), replace it in the cache with the type
                ImportReference importReference = ((ImportBinding) cachedBinding).reference;
                if (importReference != null) {
                    importReference.bits |= ASTNode.Used;
                }
                if (cachedBinding instanceof ImportConflictBinding)
                    typeOrPackageCache.put(name,
                            cachedBinding = ((ImportConflictBinding) cachedBinding).conflictingTypeBinding); // already know its visible
                else
                    typeOrPackageCache.put(name,
                            cachedBinding = ((ImportBinding) cachedBinding).resolvedImport); // already know its visible
            }
            if ((mask & Binding.TYPE) != 0) {
                if (foundType != null && foundType.problemId() != ProblemReasons.NotVisible
                        && cachedBinding.problemId() != ProblemReasons.Ambiguous)
                    return foundType; // problem type from above supercedes NotFound type but not Ambiguous import case
                if (cachedBinding instanceof ReferenceBinding)
                    return cachedBinding; // cached type found in previous walk below
            }
            if ((mask & Binding.PACKAGE) != 0 && cachedBinding instanceof PackageBinding)
                return cachedBinding; // cached package found in previous walk below
        }
    }

    // ask for the imports + name
    if ((mask & Binding.TYPE) != 0) {
        ImportBinding[] imports = unitScope.imports;
        if (imports != null && typeOrPackageCache == null) { // walk single type imports since faultInImports() has not run yet
            nextImport: for (int i = 0, length = imports.length; i < length; i++) {
                ImportBinding importBinding = imports[i];
                if (!importBinding.onDemand) {
                    // GROOVY start
                    /* old {
                    if (CharOperation.equals(importBinding.compoundName[importBinding.compoundName.length - 1], name)) {
                    } new */
                    if (CharOperation.equals(getSimpleName(importBinding), name)) {
                        // GROOVY end
                        Binding resolvedImport = unitScope.resolveSingleImport(importBinding, Binding.TYPE);
                        if (resolvedImport == null)
                            continue nextImport;
                        if (resolvedImport instanceof TypeBinding) {
                            ImportReference importReference = importBinding.reference;
                            if (importReference != null)
                                importReference.bits |= ASTNode.Used;
                            return resolvedImport; // already know its visible
                        }
                    }
                }
            }
        }

        // check if the name is in the current package, skip it if its a sub-package
        PackageBinding currentPackage = unitScope.fPackage;
        unitScope.recordReference(currentPackage.compoundName, name);
        Binding binding = currentPackage.getTypeOrPackage(name);
        if (binding instanceof ReferenceBinding) {
            ReferenceBinding referenceType = (ReferenceBinding) binding;
            if ((referenceType.tagBits & TagBits.HasMissingType) == 0) {
                if (typeOrPackageCache != null)
                    typeOrPackageCache.put(name, referenceType);
                return referenceType; // type is always visible to its own package
            }
        }

        // check on demand imports
        if (imports != null) {
            boolean foundInImport = false;
            ReferenceBinding type = null;
            for (int i = 0, length = imports.length; i < length; i++) {
                ImportBinding someImport = imports[i];
                if (someImport.onDemand) {
                    Binding resolvedImport = someImport.resolvedImport;
                    ReferenceBinding temp = null;
                    if (resolvedImport instanceof PackageBinding) {
                        temp = findType(name, (PackageBinding) resolvedImport, currentPackage);
                    } else if (someImport.isStatic()) {
                        temp = findMemberType(name, (ReferenceBinding) resolvedImport); // static imports are allowed to see inherited member types
                        if (temp != null && !temp.isStatic())
                            temp = null;
                    } else {
                        temp = findDirectMemberType(name, (ReferenceBinding) resolvedImport);
                    }
                    if (temp != type && temp != null) {
                        if (temp.isValidBinding()) {
                            // GROOVY - start - allow for imports expressed in source to override 'default' imports - GRECLIPSE-945
                            boolean conflict = true; // do we need to continue checking
                            if (this.parent != null && foundInImport) {
                                CompilationUnitScope cuScope = compilationUnitScope();
                                if (cuScope != null) {
                                    ReferenceBinding chosenBinding = cuScope.selectBinding(temp, type,
                                            someImport.reference != null);
                                    if (chosenBinding != null) {
                                        // The new binding was selected as a valid answer
                                        conflict = false;
                                        foundInImport = true;
                                        type = chosenBinding;
                                    }
                                }
                            }
                            if (conflict) {
                                // GROOVY - end
                                ImportReference importReference = someImport.reference;
                                if (importReference != null) {
                                    importReference.bits |= ASTNode.Used;
                                }
                                if (foundInImport) {
                                    // Answer error binding -- import on demand conflict; name found in two import on demand packages.
                                    temp = new ProblemReferenceBinding(new char[][] { name }, type,
                                            ProblemReasons.Ambiguous);
                                    if (typeOrPackageCache != null)
                                        typeOrPackageCache.put(name, temp);
                                    return temp;
                                }
                                type = temp;
                                foundInImport = true;
                                // GROOVY - start
                            }
                            // GROOVY - end
                        } else if (foundType == null) {
                            foundType = temp;
                        }
                    }
                }
            }
            if (type != null) {
                if (typeOrPackageCache != null)
                    typeOrPackageCache.put(name, type);
                return type;
            }
        }
    }

    unitScope.recordSimpleReference(name);
    if ((mask & Binding.PACKAGE) != 0) {
        PackageBinding packageBinding = unitScope.environment.getTopLevelPackage(name);
        if (packageBinding != null) {
            if (typeOrPackageCache != null)
                typeOrPackageCache.put(name, packageBinding);
            return packageBinding;
        }
    }

    // Answer error binding -- could not find name
    if (foundType == null) {
        char[][] qName = new char[][] { name };
        ReferenceBinding closestMatch = null;
        if ((mask & Binding.PACKAGE) != 0) {
            if (needResolve) {
                closestMatch = environment().createMissingType(unitScope.fPackage, qName);
            }
        } else {
            PackageBinding packageBinding = unitScope.environment.getTopLevelPackage(name);
            if (packageBinding == null || !packageBinding.isValidBinding()) {
                if (needResolve) {
                    closestMatch = environment().createMissingType(unitScope.fPackage, qName);
                }
            }
        }
        foundType = new ProblemReferenceBinding(qName, closestMatch, ProblemReasons.NotFound);
        if (typeOrPackageCache != null && (mask & Binding.PACKAGE) != 0) { // only put NotFound type in cache if you know its not a package
            typeOrPackageCache.put(name, foundType);
        }
    } else if ((foundType.tagBits & TagBits.HasMissingType) != 0) {
        char[][] qName = new char[][] { name };
        foundType = new ProblemReferenceBinding(qName, foundType, ProblemReasons.NotFound);
        if (typeOrPackageCache != null && (mask & Binding.PACKAGE) != 0) // only put NotFound type in cache if you know its not a package
            typeOrPackageCache.put(name, foundType);
    }
    return foundType;
}

From source file:org.eclipse.objectteams.otdt.internal.codeassist.SelectionOnBaseCallMessageSend.java

License:Open Source License

public TypeBinding resolveType(BlockScope scope) {
    try {/*www  . j a v a 2  s  .  co m*/
        super.resolveType(scope);
    } catch (SelectionNodeFound snf) {
        if ((snf.binding instanceof MethodBinding) && MethodModel.isFakedMethod((MethodBinding) snf.binding)) {
            // fake method (e.g. basecall surrogate) is not valid, continue below
        } else {
            throw snf;
        }
    }

    MessageSend wrappee = this._sendOrig; // _wrappee might have been replaced with an Assignment.

    // tolerate some error cases
    if (wrappee.binding == null
            || !(wrappee.binding.isValidBinding() || wrappee.binding.problemId() == ProblemReasons.NotVisible
                    || wrappee.binding.problemId() == ProblemReasons.InheritedNameHidesEnclosingName
                    || wrappee.binding.problemId() == ProblemReasons.NonStaticReferenceInConstructorInvocation
                    || wrappee.binding.problemId() == ProblemReasons.NonStaticReferenceInStaticContext)) {
        throw new SelectionNodeFound();
    } else {
        // wrappee.binding is the base call surrogate, find the proper enclosing method instead:
        MethodBinding callinMethod = null;
        MethodScope methodScope = scope.methodScope();
        if (methodScope == null)
            throw new SelectionNodeFound();

        MemberTypeBinding role = null;
        SourceTypeBinding site = scope.enclosingSourceType();

        if (site.isLocalType()) {
            MethodDeclaration callinDecl = getOuterCallinMethod(methodScope);
            if (callinDecl == null)
                throw new SelectionNodeFound();
            callinMethod = callinDecl.binding;
            role = (MemberTypeBinding) callinMethod.declaringClass;
        } else {
            callinMethod = methodScope.referenceMethod().binding;
            role = (MemberTypeBinding) site;
        }

        // find base methods bound in callin mappings which have callinMethod as their role method:
        MethodBinding[] baseBindings = findBaseMethodBindings(role, callinMethod);
        if (baseBindings == null || baseBindings.length == 0) {
            throw new SelectionNodeFound();
        } else {
            throw new SelectionNodesFound(baseBindings);
        }
    }
}

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

License:Open Source License

public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
    flowInfo = super.analyseCode(currentScope, flowContext, flowInfo);
    MethodDeclaration callinMethod = getEnclosingCallinMethod(currentScope);
    LocalVariableBinding trackingVariable = callinMethod.baseCallTrackingVariable.binding;
    if (flowInfo.isDefinitelyAssigned(callinMethod.baseCallTrackingVariable))
        currentScope.problemReporter().definitelyDuplicateBasecall(this._wrappee);
    else if (flowInfo.isPotentiallyAssigned(trackingVariable))
        currentScope.problemReporter().potentiallyDuplicateBasecall(this._wrappee);
    else//from   w ww  .  java2  s  .  co  m
        flowInfo.markAsDefinitelyAssigned(trackingVariable);

    // check exceptions thrown by any bound base method:
    MethodScope methodScope = currentScope.methodScope();
    if (methodScope != null) {
        MethodModel methodModel = methodScope.referenceMethod().binding.model;
        if (methodModel != null && methodModel._baseExceptions != null) {
            for (ReferenceBinding exceptionType : methodModel._baseExceptions)
                flowContext.checkExceptionHandlers(exceptionType, this, flowInfo, currentScope);
        }
    }

    if (this.isSuperAccess)
        //    signal that the base call surrogate needs to handle super-access:
        MethodModel.addCallinFlag(currentScope.methodScope().referenceMethod(),
                IOTConstants.CALLIN_FLAG_BASE_SUPER_CALL);

    return flowInfo;
}

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

License:Open Source License

/**
 * If this base call resides in a local type retrieve the callin method enclosing that type.
 *//*from  w  w w. j a va 2  s  . c o m*/
public static MethodDeclaration getOuterCallinMethod(MethodScope scope) {
    Scope parent = scope.parent;
    if (parent != null) {
        MethodScope outerMethodScope = parent.methodScope();
        if (outerMethodScope == null)
            return null;
        AbstractMethodDeclaration outerMethod = outerMethodScope.referenceMethod();
        if (outerMethod.isCallin())
            return (MethodDeclaration) outerMethod;
    }
    return null;
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.control.Dependencies.java

License:Open Source License

/**
  * Perform several substitutions in method bodies.
  * (See TransformStatementsVisitor).//from ww  w  .jav  a 2s  .  co  m
  *
  * BinaryTypes: nothing to do.
  *
  * Recursion: NESTED_TEAMS.
  */
private static boolean establishStatementsTransformed(TypeModel clazz) {
    TypeDeclaration type = clazz.getAst();
    if (type != null) {
        if (needMethodBodies(type)) {
            TransformStatementsVisitor transformer = new TransformStatementsVisitor(clazz.getWeavingScheme());
            if ((type.bits & ASTNode.IsLocalType) != 0) {
                MethodScope methodScope = type.scope.methodScope();
                if (methodScope != null)
                    transformer.checkPushCallinMethod(methodScope.referenceMethod());
            }
            type.traverse(transformer, type.scope.compilationUnitScope());
        } else if (clazz.isTeam()) {
            if (type.memberTypes != null) {
                for (int i = 0; i < type.memberTypes.length; i++) {
                    establishStatementsTransformed(type.memberTypes[i].getRoleModel());
                }
            }
        }
        if (needMethodBodies(type) || type.isConverted) // converted types may contain local types but no other statements!
        {
            RecordLocalTypesVisitor recorder = new RecordLocalTypesVisitor();
            recorder.recordLocalTypesFor(type);
        }
    }
    clazz.setState(ITranslationStates.STATE_STATEMENTS_TRANSFORMED);
    clazz.setMemberState(ITranslationStates.STATE_STATEMENTS_TRANSFORMED);
    return true;
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.mappings.CallinImplementor.java

License:Open Source License

/**
 * the expression _OT$role.roleMethod(..) should not wrap its
 * return type anchored to the generated team anchor _OT$role,
 * because the method should actually be seen as being within
 * the scope of this role already, although, physically it is part of
 * the team.//from  w  w  w.j av a2  s  .  c  om
 *
 * @param scope use the scope to determine if we are acutally within
 *        a callin wrapper.
 * @param receiver if this is _OT$role this is the role method call.
 * @return true if the return type should not be wrapped further.
 */
public static boolean avoidWrapRoleType(BlockScope scope, Expression receiver) {
    MethodScope methodScope = scope.methodScope();
    if (methodScope != null) { // CLOVER: never false in jacks suite
        AbstractMethodDeclaration refMethod = methodScope.referenceMethod();
        if (refMethod != null && refMethod.isMappingWrapper._callin()) {
            if (receiver instanceof SingleNameReference
                    && CharOperation.equals(((SingleNameReference) receiver).token,
                            CharOperation.concat(IOTConstants.OT_DOLLAR_NAME, IOTConstants.ROLE)))
                return true;
        }
    }
    return false;
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator.java

License:Open Source License

/**
* This method assumes that the enclosing type of scope can be used for
* tthis anchors, i.e., types are used unqualified.
*
* @param scope determines tthis (NON-NULL).
* @param typeToWrap/*from  w w  w .  j av a  2s.  c  om*/
* @param typedNode
* @return valid type, null (possibly after reporting error), or (unreported) problem
*/
public static TypeBinding maybeWrapUnqualifiedRoleType(Scope scope, TypeBinding typeToWrap, ASTNode typedNode) {
    /* external invocations (via maybeWrapUnqualifiedRoleType(TypeBinding, Scope, AstNode)?):
    *      AllocationExpression.resolveType()      new R       R
    *      ArrayAllocationExpression.resolveType() new R[]     R
    *      Assignment.resolveType()                lhs = r     type(r)
    *      CastExpression.resolveType()            (R)expr     R
    *      LocalDeclaration.resolve()              R l = r     R, type(r)
    *      PotentialLiftExpression.resolveType()   liftToR(b)  R
    *      RoleTypeReference.resolveType()         this.R      R
    *      SingleNameReference.resolveType()       n           type(n)
    *      ThisReference.resolveType()             this        type(this)
    *      QualifiedThisReference.resolveType()    Mid.this    type(this)
    * other invocations:
    *      MethodVerifier.areTypesEqual()
    *        CopyInheritance.copyCastToMethods()
    *      AbstractMethodMappingDeclaration.resolveMethodSpecs()
    * other internal invocation:
    *      wrapTypesInMethodBindingSignature()
    *      wrapTypesInMethodDeclSignature()
    *          (via maybeWrapUnqualifiedRoleType(TypeBinding, Scope, AstNode))
    *
    */
    ReferenceBinding site = scope.enclosingSourceType();
    MethodScope methodScope = scope.methodScope();
    if (methodScope != null && methodScope.referenceMethod() != null
            && methodScope.referenceMethod().isMappingWrapper._callin()
            //{OTDyn
            && scope.compilerOptions().weavingScheme == WeavingScheme.OTRE) // this heuristic doesn't work for dyn weaving, FIXME(SH): check if still needed!
    // SH}
    {
        // in a callin wrapper, for visibility reasons, pretend we are in the
        // scope of the role (which is, where the declaration actually occurs):
        char[] selector = methodScope.referenceMethod().selector;
        int secondDollar = CharOperation.indexOf('$', selector, 4); // skip _OT$
        char[] roleName = CharOperation.subarray(selector, 4, secondDollar);
        site = site.getMemberType(roleName);
    }
    return maybeWrapUnqualifiedRoleType(scope, site, typeToWrap, typedNode, scope.problemReporter());
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator.java

License:Open Source License

/**
 * Try to resolve an argument or return type as an anchored type.
 *
 * PRE: Regular type resolution has already failed.
 *
 * Currently only handles references of two components: anchor and Type.
 * (for parameters this is probably OK?)
 * NO: TODO(SH): arguments could also be anchored to arbitrary expressions/paths!
 *
  * @param type type reference to be analyzed (resolvedType is null or invalid)
 * @param arguments the arguments of the current method
 * @param index position of the argument to be analyzed
  *        == arguments.length means: analyzing return type.
 * @param scope scope of the current method.
 * @return a RoleTypeBinding or null (after reporting error)
 *///w ww.j  a v  a  2 s. c  o m
public static TypeBinding getTypeAnchoredToParameter(TypeReference type, Argument[] arguments, int index,
        MethodScope scope, CheckPoint cp) {
    // we only handle QualifiedTypeReferences of length 2, or QualifiedArrayTypeReferences.
    if (!(type instanceof QualifiedTypeReference)) {
        return null; // not better than before
    }
    QualifiedTypeReference argType = (QualifiedTypeReference) type;

    // look for anchor in argument list:
    VariableBinding anchor = null;
    char[] anchorName = argType.tokens[0];
    int argPos;
    for (argPos = 0; argPos < index; argPos++) {
        Argument argument = arguments[argPos];
        // ensure arguments are bound, which must happen in correct order.
        argument.bind(scope, argument.type.resolvedType, /*used*/false);
        if (CharOperation.equals(argument.name, anchorName)) // compare possible anchor
        {
            argument.binding.useFlag = LocalVariableBinding.USED; // used as anchor
            anchor = argument.binding;
            if (scope.classScope().referenceContext.isConverted)
                anchor.modifiers |= ClassFileConstants.AccFinal; // lost during conversion.
            break;
        }
    }
    if (anchor == null) {
        argPos = -1; // mark as not found in argument list
        anchor = findAnchorInScope(scope, anchorName);
    }
    if (anchor == null)
        return null; // not better than before.

    if (!anchor.isFinal()) {
        char[][] typeName = type.getTypeName();
        scope.problemReporter().anchorPathNotFinal(argType, anchor, typeName[typeName.length - 1]);
        return null;
    }

    // defensive programming:
    if (anchor.type == null)
        return null;
    // anchor must be a team:
    if (!anchor.type.isTeam()) {
        if (!anchor.type.isValidBinding())
            return null; //can't decide whether this is a valid team or not.
        reportAnchorIsNotATeam(scope, argType);
        return null;
    }

    // delegate for role type lookup:
    TypeBinding anchoredType = resolveOtherPathElements(scope, type, anchor, argType.tokens, 1,
            argType.dimensions());

    if (anchoredType != null) {
        if (!anchoredType.isValidBinding()) {
            scope.problemReporter().invalidType(type, anchoredType);
            return null;
        }
        if (anchoredType.leafComponentType().isRoleType()) {
            // prepare for creating an AnchorListAttribute
            RoleTypeBinding leafRoleType = (RoleTypeBinding) anchoredType.leafComponentType();
            leafRoleType._argumentPosition = argPos;
            final AbstractMethodDeclaration methodDecl = scope.referenceMethod();
            leafRoleType._declaringMethod = new DependentTypeBinding.IMethodProvider() {
                public MethodBinding getMethod() {
                    return methodDecl.binding;
                }
            };
        }
        scope.referenceContext.compilationResult().rollBack(cp);
        scope.problemReporter().deprecatedPathSyntax(type);
    }
    return anchoredType;
}