Example usage for org.eclipse.jdt.internal.compiler.lookup Scope methodScope

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

Introduction

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

Prototype

public final MethodScope methodScope() 

Source Link

Usage

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

License:Open Source License

public Binding getBinding(char[] name, int mask, InvocationSite invocationSite, boolean needResolve) {
    CompilationUnitScope unitScope = compilationUnitScope();
    LookupEnvironment env = unitScope.environment;
    try {//  www  .ja v  a 2s .  co  m
        env.missingClassFileLocation = invocationSite;
        Binding binding = null;
        FieldBinding problemField = null;
        if ((mask & Binding.VARIABLE) != 0) {
            boolean insideStaticContext = false;
            boolean insideConstructorCall = false;
            boolean insideTypeAnnotation = false;

            FieldBinding foundField = null;
            // can be a problem field which is answered if a valid field is not found
            ProblemFieldBinding foundInsideProblem = null;
            // inside Constructor call or inside static context
            Scope scope = this;
            int depth = 0;
            int foundDepth = 0;
            ReferenceBinding foundActualReceiverType = null;
            done: while (true) { // done when a COMPILATION_UNIT_SCOPE is found
                switch (scope.kind) {
                case METHOD_SCOPE:
                    MethodScope methodScope = (MethodScope) scope;
                    insideStaticContext |= methodScope.isStatic;
                    insideConstructorCall |= methodScope.isConstructorCall;
                    insideTypeAnnotation = methodScope.insideTypeAnnotation;

                    //$FALL-THROUGH$ could duplicate the code below to save a cast - questionable optimization
                case BLOCK_SCOPE:
                    LocalVariableBinding variableBinding = scope.findVariable(name);
                    // looks in this scope only
                    if (variableBinding != null) {
                        if (foundField != null && foundField.isValidBinding())
                            return new ProblemFieldBinding(foundField, // closest match
                                    foundField.declaringClass, name,
                                    ProblemReasons.InheritedNameHidesEnclosingName);
                        if (depth > 0)
                            invocationSite.setDepth(depth);
                        return variableBinding;
                    }
                    break;
                case CLASS_SCOPE:
                    ClassScope classScope = (ClassScope) scope;
                    ReferenceBinding receiverType = classScope.enclosingReceiverType();
                    if (!insideTypeAnnotation) {
                        FieldBinding fieldBinding = classScope.findField(receiverType, name, invocationSite,
                                needResolve);
                        // Use next line instead if willing to enable protected access accross inner types
                        // FieldBinding fieldBinding = findField(enclosingType, name, invocationSite);

                        if (fieldBinding != null) { // skip it if we did not find anything
                            if (fieldBinding.problemId() == ProblemReasons.Ambiguous) {
                                if (foundField == null || foundField.problemId() == ProblemReasons.NotVisible)
                                    // supercedes any potential InheritedNameHidesEnclosingName problem
                                    return fieldBinding;
                                // make the user qualify the field, likely wants the first inherited field (javac generates an ambiguous error instead)
                                return new ProblemFieldBinding(foundField, // closest match
                                        foundField.declaringClass, name,
                                        ProblemReasons.InheritedNameHidesEnclosingName);
                            }

                            ProblemFieldBinding insideProblem = null;
                            if (fieldBinding.isValidBinding()) {
                                if (!fieldBinding.isStatic()) {
                                    if (insideConstructorCall) {
                                        insideProblem = new ProblemFieldBinding(fieldBinding, // closest match
                                                fieldBinding.declaringClass, name,
                                                ProblemReasons.NonStaticReferenceInConstructorInvocation);
                                    } else if (insideStaticContext) {
                                        insideProblem = new ProblemFieldBinding(fieldBinding, // closest match
                                                fieldBinding.declaringClass, name,
                                                ProblemReasons.NonStaticReferenceInStaticContext);
                                    }
                                }
                                if (receiverType == fieldBinding.declaringClass
                                        || compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
                                    // found a valid field in the 'immediate' scope (i.e. not inherited)
                                    // OR in 1.4 mode (inherited shadows enclosing)
                                    if (foundField == null) {
                                        if (depth > 0) {
                                            invocationSite.setDepth(depth);
                                            invocationSite.setActualReceiverType(receiverType);
                                        }
                                        // return the fieldBinding if it is not declared in a superclass of the scope's binding (that is, inherited)
                                        return insideProblem == null ? fieldBinding : insideProblem;
                                    }
                                    if (foundField.isValidBinding())
                                        // if a valid field was found, complain when another is found in an 'immediate' enclosing type (that is, not inherited)
                                        // but only if "valid field" was inherited in the first place.
                                        if (foundField.declaringClass != fieldBinding.declaringClass
                                                && foundField.declaringClass != foundActualReceiverType) // https://bugs.eclipse.org/bugs/show_bug.cgi?id=316956
                                            // i.e. have we found the same field - do not trust field identity yet
                                            return new ProblemFieldBinding(foundField, // closest match
                                                    foundField.declaringClass, name,
                                                    ProblemReasons.InheritedNameHidesEnclosingName);
                                }
                            }

                            if (foundField == null || (foundField.problemId() == ProblemReasons.NotVisible
                                    && fieldBinding.problemId() != ProblemReasons.NotVisible)) {
                                // only remember the fieldBinding if its the first one found or the previous one was not visible & fieldBinding is...
                                foundDepth = depth;
                                foundActualReceiverType = receiverType;
                                foundInsideProblem = insideProblem;
                                foundField = fieldBinding;
                            }
                        }
                    }
                    insideTypeAnnotation = false;
                    depth++;
                    insideStaticContext |= receiverType.isStatic();
                    // 1EX5I8Z - accessing outer fields within a constructor call is permitted
                    // in order to do so, we change the flag as we exit from the type, not the method
                    // itself, because the class scope is used to retrieve the fields.
                    MethodScope enclosingMethodScope = scope.methodScope();
                    insideConstructorCall = enclosingMethodScope == null ? false
                            : enclosingMethodScope.isConstructorCall;
                    break;
                case COMPILATION_UNIT_SCOPE:
                    break done;
                }
                scope = scope.parent;
            }

            if (foundInsideProblem != null)
                return foundInsideProblem;
            if (foundField != null) {
                if (foundField.isValidBinding()) {
                    if (foundDepth > 0) {
                        invocationSite.setDepth(foundDepth);
                        invocationSite.setActualReceiverType(foundActualReceiverType);
                    }
                    return foundField;
                }
                problemField = foundField;
                foundField = null;
            }

            if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
                // at this point the scope is a compilation unit scope & need to check for imported static fields
                unitScope.faultInImports(); // ensure static imports are resolved
                ImportBinding[] imports = unitScope.imports;
                if (imports != null) {
                    // check single static imports
                    for (int i = 0, length = imports.length; i < length; i++) {
                        ImportBinding importBinding = imports[i];
                        if (importBinding.isStatic() && !importBinding.onDemand) {
                            if (CharOperation.equals(
                                    importBinding.compoundName[importBinding.compoundName.length - 1], name)) {
                                if (unitScope.resolveSingleImport(importBinding,
                                        Binding.TYPE | Binding.FIELD | Binding.METHOD) != null
                                        && importBinding.resolvedImport instanceof FieldBinding) {
                                    foundField = (FieldBinding) importBinding.resolvedImport;
                                    ImportReference importReference = importBinding.reference;
                                    if (importReference != null && needResolve) {
                                        importReference.bits |= ASTNode.Used;
                                    }
                                    invocationSite.setActualReceiverType(foundField.declaringClass);
                                    if (foundField.isValidBinding()) {
                                        return foundField;
                                    }
                                    if (problemField == null)
                                        problemField = foundField;
                                }
                            }
                        }
                    }
                    // check on demand imports
                    boolean foundInImport = false;
                    for (int i = 0, length = imports.length; i < length; i++) {
                        ImportBinding importBinding = imports[i];
                        if (importBinding.isStatic() && importBinding.onDemand) {
                            Binding resolvedImport = importBinding.resolvedImport;
                            if (resolvedImport instanceof ReferenceBinding) {
                                FieldBinding temp = findField((ReferenceBinding) resolvedImport, name,
                                        invocationSite, needResolve);
                                if (temp != null) {
                                    if (!temp.isValidBinding()) {
                                        if (problemField == null)
                                            problemField = temp;
                                    } else if (temp.isStatic()) {
                                        if (foundField == temp)
                                            continue;
                                        ImportReference importReference = importBinding.reference;
                                        if (importReference != null && needResolve) {
                                            importReference.bits |= ASTNode.Used;
                                        }
                                        if (foundInImport)
                                            // Answer error binding -- import on demand conflict; name found in two import on demand packages.
                                            return new ProblemFieldBinding(foundField, // closest match
                                                    foundField.declaringClass, name, ProblemReasons.Ambiguous);
                                        foundField = temp;
                                        foundInImport = true;
                                    }
                                }
                            }
                        }
                    }
                    if (foundField != null) {
                        invocationSite.setActualReceiverType(foundField.declaringClass);
                        return foundField;
                    }
                }
            }
        }

        // We did not find a local or instance variable.
        if ((mask & Binding.TYPE) != 0) {
            if ((binding = getBaseType(name)) != null)
                return binding;
            binding = getTypeOrPackage(name,
                    (mask & Binding.PACKAGE) == 0 ? Binding.TYPE : Binding.TYPE | Binding.PACKAGE, needResolve);
            if (binding.isValidBinding() || mask == Binding.TYPE)
                return binding;
            // answer the problem type binding if we are only looking for a type
        } else if ((mask & Binding.PACKAGE) != 0) {
            unitScope.recordSimpleReference(name);
            if ((binding = env.getTopLevelPackage(name)) != null)
                return binding;
        }
        if (problemField != null)
            return problemField;
        if (binding != null && binding.problemId() != ProblemReasons.NotFound)
            return binding; // answer the better problem binding
        return new ProblemBinding(name, enclosingSourceType(), ProblemReasons.NotFound);
    } catch (AbortCompilation e) {
        e.updateContext(invocationSite, referenceCompilationUnit().compilationResult);
        throw e;
    } finally {
        env.missingClassFileLocation = null;
    }
}

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

License:Open Source License

public MethodBinding getImplicitMethod(char[] selector, TypeBinding[] argumentTypes,
        InvocationSite invocationSite) {

    boolean insideStaticContext = false;
    boolean insideConstructorCall = false;
    boolean insideTypeAnnotation = false;
    MethodBinding foundMethod = null;/*from  w ww.  j a v  a  2s  . c  o  m*/
    MethodBinding foundProblem = null;
    boolean foundProblemVisible = false;
    Scope scope = this;
    int depth = 0;
    // in 1.4 mode (inherited visible shadows enclosing)
    CompilerOptions options;
    boolean inheritedHasPrecedence = (options = 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;
            insideStaticContext |= methodScope.isStatic;
            insideConstructorCall |= methodScope.isConstructorCall;
            insideTypeAnnotation = methodScope.insideTypeAnnotation;
            break;
        case CLASS_SCOPE:
            ClassScope classScope = (ClassScope) scope;
            ReferenceBinding receiverType = classScope.enclosingReceiverType();
            if (!insideTypeAnnotation) {
                // retrieve an exact visible match (if possible)
                // compilationUnitScope().recordTypeReference(receiverType);   not needed since receiver is the source type
                MethodBinding methodBinding = classScope.findExactMethod(receiverType, selector, argumentTypes,
                        invocationSite);
                if (methodBinding == null)
                    methodBinding = classScope.findMethod(receiverType, selector, argumentTypes,
                            invocationSite);
                if (methodBinding != null) { // skip it if we did not find anything
                    if (foundMethod == null) {
                        if (methodBinding.isValidBinding()) {
                            if (!methodBinding.isStatic() && (insideConstructorCall || insideStaticContext)) {
                                if (foundProblem != null
                                        && foundProblem.problemId() != ProblemReasons.NotVisible)
                                    return foundProblem; // takes precedence
                                return new ProblemMethodBinding(methodBinding, // closest match
                                        methodBinding.selector, methodBinding.parameters,
                                        insideConstructorCall
                                                ? ProblemReasons.NonStaticReferenceInConstructorInvocation
                                                : ProblemReasons.NonStaticReferenceInStaticContext);
                            }
                            if (inheritedHasPrecedence || receiverType == methodBinding.declaringClass
                                    || (receiverType.getMethods(selector)) != Binding.NO_METHODS) {
                                // found a valid method in the 'immediate' scope (i.e. not inherited)
                                // OR in 1.4 mode (inherited visible shadows enclosing)
                                // OR the receiverType implemented a method with the correct name
                                // return the methodBinding if it is not declared in a superclass of the scope's binding (that is, inherited)
                                if (foundProblemVisible) {
                                    return foundProblem;
                                }
                                if (depth > 0) {
                                    invocationSite.setDepth(depth);
                                    invocationSite.setActualReceiverType(receiverType);
                                }
                                // special treatment for Object.getClass() in 1.5 mode (substitute parameterized return type)
                                if (argumentTypes == Binding.NO_PARAMETERS
                                        && CharOperation.equals(selector, TypeConstants.GETCLASS)
                                        && methodBinding.returnType.isParameterizedType()/*1.5*/) {
                                    return environment().createGetClassMethod(receiverType, methodBinding,
                                            this);
                                }
                                return methodBinding;
                            }

                            if (foundProblem == null || foundProblem.problemId() == ProblemReasons.NotVisible) {
                                if (foundProblem != null)
                                    foundProblem = null;
                                // only remember the methodBinding if its the first one found
                                // remember that private methods are visible if defined directly by an enclosing class
                                if (depth > 0) {
                                    invocationSite.setDepth(depth);
                                    invocationSite.setActualReceiverType(receiverType);
                                }
                                foundMethod = methodBinding;
                            }
                        } else { // methodBinding is a problem method
                            if (methodBinding.problemId() != ProblemReasons.NotVisible
                                    && methodBinding.problemId() != ProblemReasons.NotFound)
                                return methodBinding; // return the error now
                            if (foundProblem == null) {
                                foundProblem = methodBinding; // hold onto the first not visible/found error and keep the second not found if first is not visible
                            }
                            if (!foundProblemVisible && methodBinding.problemId() == ProblemReasons.NotFound) {
                                MethodBinding closestMatch = ((ProblemMethodBinding) methodBinding).closestMatch;
                                if (closestMatch != null
                                        && closestMatch.canBeSeenBy(receiverType, invocationSite, this)) {
                                    foundProblem = methodBinding; // hold onto the first not visible/found error and keep the second not found if first is not visible
                                    foundProblemVisible = true;
                                }
                            }
                        }
                    } else { // found a valid method so check to see if this is a hiding case
                        if (methodBinding.problemId() == ProblemReasons.Ambiguous
                                || (foundMethod.declaringClass != methodBinding.declaringClass
                                        && (receiverType == methodBinding.declaringClass
                                                || receiverType.getMethods(selector) != Binding.NO_METHODS)))
                            // ambiguous case -> must qualify the method (javac generates an ambiguous error instead)
                            // otherwise if a method was found, complain when another is found in an 'immediate' enclosing type (that is, not inherited)
                            // NOTE: Unlike fields, a non visible method hides a visible method
                            return new ProblemMethodBinding(methodBinding, // closest match
                                    selector, argumentTypes, ProblemReasons.InheritedNameHidesEnclosingName);
                    }
                }
            }
            insideTypeAnnotation = false;
            depth++;
            insideStaticContext |= receiverType.isStatic();
            // 1EX5I8Z - accessing outer fields within a constructor call is permitted
            // in order to do so, we change the flag as we exit from the type, not the method
            // itself, because the class scope is used to retrieve the fields.
            MethodScope enclosingMethodScope = scope.methodScope();
            insideConstructorCall = enclosingMethodScope == null ? false
                    : enclosingMethodScope.isConstructorCall;
            break;
        case COMPILATION_UNIT_SCOPE:
            break done;
        }
        scope = scope.parent;
    }

    if (insideStaticContext && options.sourceLevel >= ClassFileConstants.JDK1_5) {
        if (foundProblem != null) {
            if (foundProblem.declaringClass != null
                    && foundProblem.declaringClass.id == TypeIds.T_JavaLangObject)
                return foundProblem; // static imports lose to methods from Object
            if (foundProblem.problemId() == ProblemReasons.NotFound && foundProblemVisible) {
                return foundProblem; // visible method selectors take precedence
            }
        }

        // at this point the scope is a compilation unit scope & need to check for imported static methods
        CompilationUnitScope unitScope = (CompilationUnitScope) scope;
        unitScope.faultInImports(); // field constants can cause static imports to be accessed before they're resolved
        ImportBinding[] imports = unitScope.imports;
        if (imports != null) {
            ObjectVector visible = null;
            boolean skipOnDemand = false; // set to true when matched static import of method name so stop looking for on demand methods
            for (int i = 0, length = imports.length; i < length; i++) {
                ImportBinding importBinding = imports[i];
                if (importBinding.isStatic()) {
                    Binding resolvedImport = importBinding.resolvedImport;
                    MethodBinding possible = null;
                    if (importBinding.onDemand) {
                        if (!skipOnDemand && resolvedImport instanceof ReferenceBinding)
                            // answers closest approximation, may not check argumentTypes or visibility
                            possible = findMethod((ReferenceBinding) resolvedImport, selector, argumentTypes,
                                    invocationSite, true);
                    } else {
                        if (resolvedImport instanceof MethodBinding) {
                            MethodBinding staticMethod = (MethodBinding) resolvedImport;
                            if (CharOperation.equals(staticMethod.selector, selector))
                                // answers closest approximation, may not check argumentTypes or visibility
                                possible = findMethod(staticMethod.declaringClass, selector, argumentTypes,
                                        invocationSite, true);
                        } else if (resolvedImport instanceof FieldBinding) {
                            // check to see if there are also methods with the same name
                            FieldBinding staticField = (FieldBinding) resolvedImport;
                            if (CharOperation.equals(staticField.name, selector)) {
                                // must find the importRef's type again since the field can be from an inherited type
                                char[][] importName = importBinding.reference.tokens;
                                TypeBinding referencedType = getType(importName, importName.length - 1);
                                if (referencedType != null)
                                    // answers closest approximation, may not check argumentTypes or visibility
                                    possible = findMethod((ReferenceBinding) referencedType, selector,
                                            argumentTypes, invocationSite, true);
                            }
                        }
                    }
                    if (possible != null && possible != foundProblem) {
                        if (!possible.isValidBinding()) {
                            if (foundProblem == null)
                                foundProblem = possible; // answer as error case match
                        } else if (possible.isStatic()) {
                            MethodBinding compatibleMethod = computeCompatibleMethod(possible, argumentTypes,
                                    invocationSite);
                            if (compatibleMethod != null) {
                                if (compatibleMethod.isValidBinding()) {
                                    if (compatibleMethod.canBeSeenBy(unitScope.fPackage)) {
                                        if (visible == null || !visible.contains(compatibleMethod)) {
                                            ImportReference importReference = importBinding.reference;
                                            if (importReference != null) {
                                                importReference.bits |= ASTNode.Used;
                                            }
                                            if (!skipOnDemand && !importBinding.onDemand) {
                                                visible = null; // forget previous matches from on demand imports
                                                skipOnDemand = true;
                                            }
                                            if (visible == null)
                                                visible = new ObjectVector(3);
                                            visible.add(compatibleMethod);
                                        }
                                    } else if (foundProblem == null) {
                                        foundProblem = new ProblemMethodBinding(compatibleMethod, selector,
                                                compatibleMethod.parameters, ProblemReasons.NotVisible);
                                    }
                                } else if (foundProblem == null) {
                                    foundProblem = compatibleMethod;
                                }
                            } else if (foundProblem == null) {
                                foundProblem = new ProblemMethodBinding(possible, selector, argumentTypes,
                                        ProblemReasons.NotFound);
                            }
                        }
                    }
                }
            }
            if (visible != null) {
                MethodBinding[] temp = new MethodBinding[visible.size];
                visible.copyInto(temp);
                foundMethod = mostSpecificMethodBinding(temp, temp.length, argumentTypes, invocationSite, null);
            }
        }
    }

    if (foundMethod != null) {
        invocationSite.setActualReceiverType(foundMethod.declaringClass);
        return foundMethod;
    }
    if (foundProblem != null)
        return foundProblem;

    return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound);
}

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 2s.co  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.lifting.DeclaredLifting.java

License:Open Source License

/**
 * Copy a team constructor such that the copy is suitable for chaining
 * previous super calls through a chain of tsuper-calls. This enables
 * a team to insert lifting calls at all required locations.
 *
 * In a subteam where the role is bound, the role parameter has to be replaced
 * with the bound base class (signature & selfcall).
 *
 * @param scope          scope of location triggering this copy operation
 * @param superTeamCtor constructor to be copied
 * @param providedArgs  this are the types of arguments passed by the ExplicitConstructorCall
 * @param needsLifting  has the context (initiating constructor decl) declared lifting?
 *///from   www. j  av a 2s. co  m
public static MethodBinding copyTeamConstructorForDeclaredLifting(Scope scope, MethodBinding superTeamCtor,
        TypeBinding[] providedArgs, boolean needsLifting) {
    TypeDeclaration teamDecl = scope.referenceType();
    AstGenerator gen = new AstGenerator(scope.methodScope().referenceMethod().sourceStart,
            scope.methodScope().referenceMethod().sourceEnd);

    if (scope.isOrgObjectteamsTeam(superTeamCtor.declaringClass))
        return maybeCreateTurningCtor(teamDecl, superTeamCtor, gen);

    // Parameter list with marker arg
    TypeBinding[] providedWithMarker = providedArgs;
    if (providedArgs.length == 0 || !TSuperHelper.isMarkerInterface(providedArgs[providedArgs.length - 1])) {
        // need to extend the param list
        TypeBinding lastParam = null;
        if (superTeamCtor.parameters.length > 0)
            lastParam = superTeamCtor.parameters[superTeamCtor.parameters.length - 1];
        TypeBinding marker = (lastParam != null && TSuperHelper.isMarkerInterface(lastParam)) ? // prefer existing marker
                lastParam : TSuperHelper.getMarkerInterface(scope, superTeamCtor.declaringClass);

        providedWithMarker = AstEdit.extendTypeArray(providedArgs, marker);
    }

    // Inner self call:
    MethodBinding selfcall = null;
    AbstractMethodDeclaration src = superTeamCtor.sourceMethod();
    if (src != null) {
        if (src.ignoreFurtherInvestigation)
            return null; // can't create ctor

        // src means: look in the AST
        ConstructorDeclaration srcCtor = (ConstructorDeclaration) src;
        if (src.isCopied) {
            if (src.model != null)
                selfcall = src.model.adjustedSelfcall;
        } else if (srcCtor.constructorCall != null) {
            Dependencies.ensureTeamState(superTeamCtor.declaringClass.getTeamModel(),
                    ITranslationStates.STATE_RESOLVED);
            selfcall = srcCtor.constructorCall.binding;
        } else {
            if (!src.scope.compilationUnitScope().referenceContext.parseMethodBodies) {
                // that's why we have no constructorCall: CU is on diet (parse); use a fake (see Trac #142):
                MethodBinding result = new MethodBinding(ClassFileConstants.AccPublic, providedArgs, null,
                        superTeamCtor.declaringClass);
                return result;
            }
            selfcall = superTeamCtor.declaringClass.superclass().getExactConstructor(Binding.NO_PARAMETERS);
        }
    } else if (superTeamCtor.bytecodeMissing || superTeamCtor.model == null) {
        return null; // can't create ctor.
    } else {
        // no src means: peek the byte code:
        selfcall = (new BytecodeTransformer()).peekConstructorCall(teamDecl.getTeamModel(), superTeamCtor.model,
                scope.environment());
    }
    MethodBinding adjustedSelfcall = null;
    if (selfcall == null) {
        if (!superTeamCtor.bytecodeMissing) // may have been set by peedConstructorCall above
            scope.problemReporter().unsupportedRoleDataflow(scope.methodScope().referenceMethod(),
                    superTeamCtor);
        // be sure to continue below, because client needs the new ctor.
    } else {

        TypeBinding[] selfCallProvidedArgs = providedWithMarker;// TODO(SH): fetch argument order from bytecode

        adjustedSelfcall = maybeCopyCtorForSelfCall(scope, selfcall, selfCallProvidedArgs, needsLifting, gen);

        // Check for presence of desired constructor:
        MethodBinding existingConstructor = teamDecl.binding.getExactConstructor(providedWithMarker);
        if (existingConstructor != null) {
            if (adjustedSelfcall != null) {
                MethodModel model = MethodModel.getModel(existingConstructor);
                model.adjustSelfcall(selfcall, adjustedSelfcall);
            }
            return existingConstructor;
        }
    }

    // Create new constructor:
    ConstructorDeclaration newCtor = gen.constructor(teamDecl.compilationResult, ClassFileConstants.AccPublic,
            teamDecl.name, AstConverter.createArgumentsFromParameters(providedWithMarker, gen));

    // adjust argument-anchored types in this signature:
    for (int i = 0; i < superTeamCtor.parameters.length; i++)
        if (RoleTypeBinding.isRoleWithExplicitAnchor(superTeamCtor.parameters[i])) {
            RoleTypeBinding requiredRTB = (RoleTypeBinding) superTeamCtor.parameters[i];
            if (requiredRTB._argumentPosition > -1) {
                // we have an arg-anchored type, adjust the anchor within this signature:
                Argument newArgument = newCtor.arguments[requiredRTB._argumentPosition]; // argument positions from the declared (super) ctor.
                newArgument.modifiers |= ClassFileConstants.AccFinal;
                newArgument.name = ((RoleTypeBinding) providedArgs[i])._teamAnchor.internalName(); // argument names from the provided types/arguments
            }
        }

    newCtor.isTSuper = true; // ??
    newCtor.isCopied = true;
    AstEdit.addMethod(teamDecl, newCtor, false /*not synthetic*/, false/*addToFront*/, superTeamCtor); // incl. resolve
    MethodModel model = MethodModel.getModel(newCtor); // already connect binding.
    if (needsLifting)
        model.liftedParams = superTeamCtor.parameters; // instructions for BytecodeTransformer
    if (adjustedSelfcall != null)
        model.adjustSelfcall(selfcall, adjustedSelfcall); // be it only strengthening
    newCtor.binding.copiedInContext = teamDecl.binding;
    newCtor.sourceMethodBinding = superTeamCtor;

    return newCtor.binding;
}

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// w  w  w  . j  a  va  2 s .c  o  m
* @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());
}