Example usage for org.eclipse.jdt.internal.compiler.lookup TagBits HasMissingType

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

Introduction

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

Prototype

long HasMissingType

To view the source code for org.eclipse.jdt.internal.compiler.lookup TagBits HasMissingType.

Click Source Link

Usage

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

License:Open Source License

public FieldBinding findField(TypeBinding receiverType, char[] fieldName, InvocationSite invocationSite,
        boolean needResolve, boolean invisibleFieldsOk) {

    CompilationUnitScope unitScope = compilationUnitScope();
    unitScope.recordTypeReference(receiverType);

    checkArrayField: {/*from ww  w .  j  a  v a2 s. c  o  m*/
        TypeBinding leafType;
        switch (receiverType.kind()) {
        case Binding.BASE_TYPE:
            return null;
        case Binding.WILDCARD_TYPE:
        case Binding.INTERSECTION_TYPE:
        case Binding.TYPE_PARAMETER: // capture
            TypeBinding receiverErasure = receiverType.erasure();
            if (!receiverErasure.isArrayType())
                break checkArrayField;
            leafType = receiverErasure.leafComponentType();
            break;
        case Binding.ARRAY_TYPE:
            leafType = receiverType.leafComponentType();
            break;
        default:
            break checkArrayField;
        }
        if (leafType instanceof ReferenceBinding)
            if (!((ReferenceBinding) leafType).canBeSeenBy(this))
                return new ProblemFieldBinding((ReferenceBinding) leafType, fieldName,
                        ProblemReasons.ReceiverTypeNotVisible);
        if (CharOperation.equals(fieldName, TypeConstants.LENGTH)) {
            if ((leafType.tagBits & TagBits.HasMissingType) != 0) {
                return new ProblemFieldBinding(ArrayBinding.ArrayLength, null, fieldName,
                        ProblemReasons.NotFound);
            }
            return ArrayBinding.ArrayLength;
        }
        return null;
    }

    ReferenceBinding currentType = (ReferenceBinding) receiverType;
    if (!currentType.canBeSeenBy(this))
        return new ProblemFieldBinding(currentType, fieldName, ProblemReasons.ReceiverTypeNotVisible);

    currentType.initializeForStaticImports();
    FieldBinding field = currentType.getField(fieldName, needResolve);
    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=316456
    boolean insideTypeAnnotations = this instanceof MethodScope && ((MethodScope) this).insideTypeAnnotation;
    if (field != null) {
        if (invisibleFieldsOk) {
            return field;
        }
        if (invocationSite == null || insideTypeAnnotations ? field.canBeSeenBy(getCurrentPackage())
                : field.canBeSeenBy(currentType, invocationSite, this))
            return field;
        return new ProblemFieldBinding(field /* closest match*/, field.declaringClass, fieldName,
                ProblemReasons.NotVisible);
    }
    // collect all superinterfaces of receiverType until the field is found in a supertype
    ReferenceBinding[] interfacesToVisit = null;
    int nextPosition = 0;
    FieldBinding visibleField = null;
    boolean keepLooking = true;
    FieldBinding notVisibleField = null;
    // we could hold onto the not visible field for extra error reporting
    while (keepLooking) {
        ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
        if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
            if (interfacesToVisit == null) {
                interfacesToVisit = itsInterfaces;
                nextPosition = interfacesToVisit.length;
            } else {
                int itsLength = itsInterfaces.length;
                if (nextPosition + itsLength >= interfacesToVisit.length)
                    System.arraycopy(interfacesToVisit, 0,
                            interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0,
                            nextPosition);
                nextInterface: for (int a = 0; a < itsLength; a++) {
                    ReferenceBinding next = itsInterfaces[a];
                    for (int b = 0; b < nextPosition; b++)
                        if (next == interfacesToVisit[b])
                            continue nextInterface;
                    interfacesToVisit[nextPosition++] = next;
                }
            }
        }
        if ((currentType = currentType.superclass()) == null)
            break;

        unitScope.recordTypeReference(currentType);
        currentType.initializeForStaticImports();
        currentType = (ReferenceBinding) currentType.capture(this,
                invocationSite == null ? 0 : invocationSite.sourceEnd());
        if ((field = currentType.getField(fieldName, needResolve)) != null) {
            if (invisibleFieldsOk) {
                return field;
            }
            keepLooking = false;
            if (field.canBeSeenBy(receiverType, invocationSite, this)) {
                if (visibleField == null)
                    visibleField = field;
                else
                    return new ProblemFieldBinding(visibleField /* closest match*/, visibleField.declaringClass,
                            fieldName, ProblemReasons.Ambiguous);
            } else {
                if (notVisibleField == null)
                    notVisibleField = field;
            }
        }
    }

    // walk all visible interfaces to find ambiguous references
    if (interfacesToVisit != null) {
        ProblemFieldBinding ambiguous = null;
        done: for (int i = 0; i < nextPosition; i++) {
            ReferenceBinding anInterface = interfacesToVisit[i];
            unitScope.recordTypeReference(anInterface);
            // no need to capture rcv interface, since member field is going to be static anyway
            if ((field = anInterface.getField(fieldName, true /*resolve*/)) != null) {
                if (invisibleFieldsOk) {
                    return field;
                }
                if (visibleField == null) {
                    visibleField = field;
                } else {
                    ambiguous = new ProblemFieldBinding(visibleField /* closest match*/,
                            visibleField.declaringClass, fieldName, ProblemReasons.Ambiguous);
                    break done;
                }
            } else {
                ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
                if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
                    int itsLength = itsInterfaces.length;
                    if (nextPosition + itsLength >= interfacesToVisit.length)
                        System.arraycopy(interfacesToVisit, 0,
                                interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0,
                                nextPosition);
                    nextInterface: for (int a = 0; a < itsLength; a++) {
                        ReferenceBinding next = itsInterfaces[a];
                        for (int b = 0; b < nextPosition; b++)
                            if (next == interfacesToVisit[b])
                                continue nextInterface;
                        interfacesToVisit[nextPosition++] = next;
                    }
                }
            }
        }
        if (ambiguous != null)
            return ambiguous;
    }

    if (visibleField != null)
        return visibleField;
    if (notVisibleField != null) {
        return new ProblemFieldBinding(notVisibleField, currentType, fieldName, ProblemReasons.NotVisible);
    }
    return null;
}

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;/*from ww  w.j a v  a2 s  .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.jdt.internal.compiler.lookup.SourceTypeBinding.java

License:Open Source License

public FieldBinding resolveTypeFor(FieldBinding field) {
    if ((field.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
        return field;

    if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
        if ((field.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0)
            field.modifiers |= ClassFileConstants.AccDeprecated;
    }//from w  ww. j  ava  2s .  com
    if (isViewedAsDeprecated() && !field.isDeprecated())
        field.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
    if (hasRestrictedAccess())
        field.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
    FieldDeclaration[] fieldDecls = this.scope.referenceContext.fields;
    int length = fieldDecls == null ? 0 : fieldDecls.length;
    for (int f = 0; f < length; f++) {
        if (fieldDecls[f].binding != field)
            continue;

        MethodScope initializationScope = field.isStatic() ? this.scope.referenceContext.staticInitializerScope
                : this.scope.referenceContext.initializerScope;
        FieldBinding previousField = initializationScope.initializedField;
        try {
            initializationScope.initializedField = field;
            FieldDeclaration fieldDecl = fieldDecls[f];
            TypeBinding fieldType = fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT
                    ? initializationScope.environment().convertToRawType(this,
                            false /*do not force conversion of enclosing types*/) // enum constant is implicitly of declaring enum type
                    : fieldDecl.type.resolveType(initializationScope, true /* check bounds*/);
            field.type = fieldType;
            field.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
            if (fieldType == null) {
                fieldDecl.binding = null;
                return null;
            }
            if (fieldType == TypeBinding.VOID) {
                this.scope.problemReporter().variableTypeCannotBeVoid(fieldDecl);
                fieldDecl.binding = null;
                return null;
            }
            if (fieldType.isArrayType() && ((ArrayBinding) fieldType).leafComponentType == TypeBinding.VOID) {
                this.scope.problemReporter().variableTypeCannotBeVoidArray(fieldDecl);
                fieldDecl.binding = null;
                return null;
            }
            if ((fieldType.tagBits & TagBits.HasMissingType) != 0) {
                field.tagBits |= TagBits.HasMissingType;
            }
            TypeBinding leafType = fieldType.leafComponentType();
            if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers
                    & ExtraCompilerModifiers.AccGenericSignature) != 0) {
                field.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
            }
        } finally {
            initializationScope.initializedField = previousField;
        }
        return field;
    }
    return null; // should never reach this point
}

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

License:Open Source License

public MethodBinding resolveTypesFor(MethodBinding method) {
    if ((method.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
        return method;

    if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
        if ((method.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0)
            method.modifiers |= ClassFileConstants.AccDeprecated;
    }//from w w  w. jav a  2 s  . c  o m
    if (isViewedAsDeprecated() && !method.isDeprecated())
        method.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
    if (hasRestrictedAccess())
        method.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;

    AbstractMethodDeclaration methodDecl = method.sourceMethod();
    // GROOVY
    /* old {
    if (methodDecl == null) return null; // method could not be resolved in previous iteration
     } new*/
    if (methodDecl == null) {
        if (method instanceof LazilyResolvedMethodBinding) {
            LazilyResolvedMethodBinding lrMethod = (LazilyResolvedMethodBinding) method;
            // the rest is a copy of the code below but doesn't depend on the method declaration
            // nothing to do for method type parameters (there are none)
            // nothing to do for method exceptions (there are none)
            TypeBinding ptb = lrMethod.getParameterTypeBinding();
            if (ptb == null) {
                method.parameters = Binding.NO_PARAMETERS;
            } else {
                method.parameters = new TypeBinding[] { ptb };
            }
            method.returnType = lrMethod.getReturnTypeBinding();
            method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
            return method;
        }
        // returning null is what this clause would have done anyway
        return null;
    }
    // FIXASC - end

    TypeParameter[] typeParameters = methodDecl.typeParameters();
    if (typeParameters != null) {
        methodDecl.scope.connectTypeVariables(typeParameters, true);
        // Perform deferred bound checks for type variables (only done after type variable hierarchy is connected)
        for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++)
            typeParameters[i].checkBounds(methodDecl.scope);
    }
    TypeReference[] exceptionTypes = methodDecl.thrownExceptions;
    if (exceptionTypes != null) {
        int size = exceptionTypes.length;
        method.thrownExceptions = new ReferenceBinding[size];
        int count = 0;
        ReferenceBinding resolvedExceptionType;
        for (int i = 0; i < size; i++) {
            resolvedExceptionType = (ReferenceBinding) exceptionTypes[i].resolveType(methodDecl.scope,
                    true /* check bounds*/);
            if (resolvedExceptionType == null)
                continue;
            if (resolvedExceptionType.isBoundParameterizedType()) {
                methodDecl.scope.problemReporter().invalidParameterizedExceptionType(resolvedExceptionType,
                        exceptionTypes[i]);
                continue;
            }
            if (resolvedExceptionType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
                if (resolvedExceptionType.isValidBinding()) {
                    methodDecl.scope.problemReporter().cannotThrowType(exceptionTypes[i],
                            resolvedExceptionType);
                    continue;
                }
            }
            if ((resolvedExceptionType.tagBits & TagBits.HasMissingType) != 0) {
                method.tagBits |= TagBits.HasMissingType;
            }
            method.modifiers |= (resolvedExceptionType.modifiers & ExtraCompilerModifiers.AccGenericSignature);
            method.thrownExceptions[count++] = resolvedExceptionType;
        }
        if (count < size)
            System.arraycopy(method.thrownExceptions, 0, method.thrownExceptions = new ReferenceBinding[count],
                    0, count);
    }
    final boolean reportUnavoidableGenericTypeProblems = this.scope
            .compilerOptions().reportUnavoidableGenericTypeProblems;
    boolean foundArgProblem = false;
    Argument[] arguments = methodDecl.arguments;
    if (arguments != null) {
        int size = arguments.length;
        method.parameters = Binding.NO_PARAMETERS;
        TypeBinding[] newParameters = new TypeBinding[size];
        for (int i = 0; i < size; i++) {
            Argument arg = arguments[i];
            if (arg.annotations != null) {
                method.tagBits |= TagBits.HasParameterAnnotations;
            }
            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=322817
            boolean deferRawTypeCheck = !reportUnavoidableGenericTypeProblems && !method.isConstructor()
                    && (arg.type.bits & ASTNode.IgnoreRawTypeCheck) == 0;
            TypeBinding parameterType;
            if (deferRawTypeCheck) {
                arg.type.bits |= ASTNode.IgnoreRawTypeCheck;
            }
            try {
                parameterType = arg.type.resolveType(methodDecl.scope, true /* check bounds*/);
            } finally {
                if (deferRawTypeCheck) {
                    arg.type.bits &= ~ASTNode.IgnoreRawTypeCheck;
                }
            }

            if (parameterType == null) {
                foundArgProblem = true;
            } else if (parameterType == TypeBinding.VOID) {
                methodDecl.scope.problemReporter().argumentTypeCannotBeVoid(this, methodDecl, arg);
                foundArgProblem = true;
            } else {
                if ((parameterType.tagBits & TagBits.HasMissingType) != 0) {
                    method.tagBits |= TagBits.HasMissingType;
                }
                TypeBinding leafType = parameterType.leafComponentType();
                if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers
                        & ExtraCompilerModifiers.AccGenericSignature) != 0)
                    method.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
                newParameters[i] = parameterType;
                arg.binding = new LocalVariableBinding(arg, parameterType, arg.modifiers, true);
            }
        }
        // only assign parameters if no problems are found
        if (!foundArgProblem) {
            method.parameters = newParameters;
        }
    }

    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=337799
    if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_7) {
        if ((method.tagBits & TagBits.AnnotationSafeVarargs) != 0) {
            if (!method.isVarargs()) {
                methodDecl.scope.problemReporter().safeVarargsOnFixedArityMethod(method);
            } else if (!method.isStatic() && !method.isFinal() && !method.isConstructor()) {
                methodDecl.scope.problemReporter().safeVarargsOnNonFinalInstanceMethod(method);
            }
        } else if (method.parameters != null && method.parameters.length > 0 && method.isVarargs()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=337795
            if (!method.parameters[method.parameters.length - 1].isReifiable()) {
                methodDecl.scope.problemReporter()
                        .possibleHeapPollutionFromVararg(methodDecl.arguments[methodDecl.arguments.length - 1]);
            }
        }
    }

    boolean foundReturnTypeProblem = false;
    if (!method.isConstructor()) {
        TypeReference returnType = methodDecl instanceof MethodDeclaration
                ? ((MethodDeclaration) methodDecl).returnType
                : null;
        if (returnType == null) {
            methodDecl.scope.problemReporter().missingReturnType(methodDecl);
            method.returnType = null;
            foundReturnTypeProblem = true;
        } else {
            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=322817
            boolean deferRawTypeCheck = !reportUnavoidableGenericTypeProblems
                    && (returnType.bits & ASTNode.IgnoreRawTypeCheck) == 0;
            TypeBinding methodType;
            if (deferRawTypeCheck) {
                returnType.bits |= ASTNode.IgnoreRawTypeCheck;
            }
            try {
                methodType = returnType.resolveType(methodDecl.scope, true /* check bounds*/);
            } finally {
                if (deferRawTypeCheck) {
                    returnType.bits &= ~ASTNode.IgnoreRawTypeCheck;
                }
            }
            if (methodType == null) {
                foundReturnTypeProblem = true;
            } else if (methodType.isArrayType()
                    && ((ArrayBinding) methodType).leafComponentType == TypeBinding.VOID) {
                methodDecl.scope.problemReporter().returnTypeCannotBeVoidArray((MethodDeclaration) methodDecl);
                foundReturnTypeProblem = true;
            } else {
                if ((methodType.tagBits & TagBits.HasMissingType) != 0) {
                    method.tagBits |= TagBits.HasMissingType;
                }
                method.returnType = methodType;
                TypeBinding leafType = methodType.leafComponentType();
                if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers
                        & ExtraCompilerModifiers.AccGenericSignature) != 0)
                    method.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
            }
        }
    }
    if (foundArgProblem) {
        methodDecl.binding = null;
        method.parameters = Binding.NO_PARAMETERS; // see 107004
        // nullify type parameter bindings as well as they have a backpointer to the method binding
        // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=81134)
        if (typeParameters != null)
            for (int i = 0, length = typeParameters.length; i < length; i++)
                typeParameters[i].binding = null;
        return null;
    }
    if (foundReturnTypeProblem)
        return method; // but its still unresolved with a null return type & is still connected to its method declaration

    method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
    return method;
}

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

License:Open Source License

/**
 * If 'hasSignature' check the return type of the bound method against the
 * declared return type./*from  ww w. j  a v a2 s  .com*/
 */
public boolean checkBaseReturnType(CallinCalloutScope scope, int bindDir) {
    TypeBinding methodReturn = boundMethodReturnType();
    if (!TypeAnalyzer.isSameType(scope.enclosingSourceType(), this.returnType.resolvedType, methodReturn)) {
        if (RoleTypeCreator.isCompatibleViaBaseAnchor(scope, methodReturn, this.returnType.resolvedType,
                bindDir))
            return true;

        if ((methodReturn.tagBits & TagBits.HasMissingType) == 0)
            scope.problemReporter().differentReturnInMethodSpec(this,
                    ((AbstractMethodMappingDeclaration) scope.referenceContext).isCallout());
        return false;
    }
    return true;
}

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

License:Open Source License

private void initialize(ReferenceBinding roleType, ITeamAnchor teamAnchor) {
    // FIXME(SH): is it OK to strip ParameterizedFields?
    if (teamAnchor instanceof ParameterizedFieldBinding)
        teamAnchor = ((ParameterizedFieldBinding) teamAnchor).original();

    initializeDependentType(teamAnchor, -1); // role type bindings have no explicit value parameters

    // infer argument position.
    ITeamAnchor firstAnchorSegment = teamAnchor.getBestNamePath()[0];
    if (firstAnchorSegment instanceof LocalVariableBinding
            && (((LocalVariableBinding) firstAnchorSegment).tagBits & TagBits.IsArgument) != 0) {
        LocalVariableBinding argumentBinding = (LocalVariableBinding) firstAnchorSegment;
        this._argumentPosition = argumentBinding.resolvedPosition;
        final MethodScope methodScope = argumentBinding.declaringScope.methodScope();
        if (methodScope != null)
            // if scope is a callout, role method may not yet be resolved, defer:
            this._declaringMethod = new IMethodProvider() {
                private MethodBinding binding;

                public MethodBinding getMethod() {
                    if (this.binding == null)
                        this.binding = methodScope.referenceMethodBinding();
                    return this.binding;
                }/*from  ww  w  .j a v a2  s  .c om*/
            };
    }

    // compute the team:
    if (CharOperation.equals(roleType.compoundName, IOTConstants.ORG_OBJECTTEAMS_TEAM_OTCONFINED))
        // the following is needed in order to break the circularity
        // of roles extending the predefined Team.__OT__Confined (see class comment)
        this._staticallyKnownTeam = roleType.enclosingType();
    else if (teamAnchor == NoAnchor)
        this._staticallyKnownTeam = roleType.enclosingType();
    else
        teamAnchor.setStaticallyKnownTeam(this);

    assert (this._staticallyKnownTeam.isTeam());

    // compute role class and role interface (by name manipulation):
    if (RoleSplitter.isClassPartName(roleType.sourceName)) {
        this._staticallyKnownRoleClass = roleType.getRealClass();
        char[] typeName = RoleSplitter.getInterfacePartName(roleType.sourceName);
        this._staticallyKnownRoleType = this._staticallyKnownTeam.getMemberType(typeName);
    } else {
        this._staticallyKnownRoleType = roleType.getRealType();
        char[] className = CharOperation.concat(OT_DELIM_NAME, this._staticallyKnownRoleType.sourceName);
        this._staticallyKnownRoleClass = this._staticallyKnownTeam.getMemberType(className);
        this._staticallyKnownRoleClass = transferTypeArguments(this._staticallyKnownRoleClass);
    }
    this._staticallyKnownRoleType = transferTypeArguments(this._staticallyKnownRoleType);

    this._declaredRoleType = this._staticallyKnownRoleType;
    // keep these consistent with _declaredRoleType:
    this.roleModel = this._declaredRoleType.roleModel;
    this._teamModel = this._declaredRoleType.getTeamModel();

    assert TypeBinding.equalsEquals(this._staticallyKnownTeam.getRealClass(),
            roleType.enclosingType()) : "weakening not using WeakenedTypeBinding"; //$NON-NLS-1$
    // some adjustments after all fields are known:
    if (TypeBinding.notEquals(this._staticallyKnownTeam, roleType.enclosingType()))
        this._staticallyKnownRoleType = this._staticallyKnownTeam.getMemberType(roleType.sourceName);
    if (this._staticallyKnownRoleClass != null)
        this.modifiers = this._staticallyKnownRoleClass.modifiers;
    // after we might have overwritten the modifiers restore some bits in the vein of ParameterizedTypeBinding:
    if (this.arguments != null) {
        this.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
    } else if (this.enclosingType() != null) {
        this.modifiers |= (this.enclosingType().modifiers & ExtraCompilerModifiers.AccGenericSignature);
        this.tagBits |= this.enclosingType().tagBits & (TagBits.HasTypeVariable | TagBits.HasMissingType);
    }

    // record as known role type at teamAnchor and in our own cache
    registerAnchor();
}

From source file:spoon.support.compiler.jdt.JDTTreeBuilderHelper.java

License:Open Source License

private static void handleImplicit(PackageBinding packageBinding, char[][] tokens, int countOfOtherBindings,
        Object qualifiedNameReference, String simpleName, CtTypeReference<?> typeRef) {
    char[][] packageNames = null;
    if (packageBinding != null) {
        packageNames = packageBinding.compoundName;
    }/* w  ww. j av a 2s .c  o m*/
    CtTypeReference<?> originTypeRef = typeRef;
    //get component type of arrays
    while (typeRef instanceof CtArrayTypeReference<?>) {
        typeRef = ((CtArrayTypeReference<?>) typeRef).getComponentType();
    }
    int off = tokens.length - 1;
    off = off - countOfOtherBindings;
    if (off > 0) {
        if (simpleName != null) {
            if (!simpleName.equals(new String(tokens[off]))) {
                throw new SpoonException("Unexpected field reference simple name: \"" + new String(tokens[off])
                        + "\" expected: \"" + simpleName + "\"");
            }
            off--;
        }
        while (off >= 0) {
            String token = new String(tokens[off]);
            if (!typeRef.getSimpleName().equals(token)) {
                /*
                 * Actually it may happen when type reference full qualified name
                 * (e.g. spoon.test.imports.testclasses.internal.SuperClass.InnerClassProtected) doesn't match with access path
                 * (e.g. spoon.test.imports.testclasses.internal.ChildClass.InnerClassProtected)
                 * In such rare case we cannot detect and set implicitness
                 */
                typeRef.getFactory().getEnvironment()
                        .debugMessage("Compiler's type path: " + qualifiedNameReference
                                + " doesn't matches with Spoon qualified type name: " + originTypeRef);
                return;
                //throw new SpoonException("Unexpected type reference simple name: \"" + token + "\" expected: \"" + typeRef.getSimpleName() + "\"");
            }
            CtTypeReference<?> declTypeRef = typeRef.getDeclaringType();
            if (declTypeRef != null) {
                typeRef = declTypeRef;
                off--;
                continue;
            }
            CtPackageReference packageRef = typeRef.getPackage();
            if (packageRef != null) {
                if (packageNames != null && packageNames.length == off) {
                    //there is full package name
                    //keep it explicit
                    return;
                }
                if (off == 0) {
                    //the package name is implicit
                    packageRef.setImplicit(true);
                    return;
                }
                if (packageBinding == null || (packageBinding.tagBits & TagBits.HasMissingType) != 0) {
                    /*
                     * the packageBinding points to unresolved type like: import static daikon.PptRelation.PptRelationType;
                     * where packageBinding is 'daikon.PptRelation'
                     * but it is not clear whether `PptRelation` is type or package.
                     * JDT compiler expects it is package, while Spoon model expects it is type
                     */
                    //keep it explicit
                    return;
                }
                throw new SpoonException("Unexpected QualifiedNameReference tokens " + qualifiedNameReference
                        + " for typeRef: " + originTypeRef);
            }
        }
        typeRef.setImplicit(true);
    }
}