List of usage examples for org.eclipse.jdt.internal.compiler.lookup InvocationSite setDepth
void setDepth(int depth);
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 {//ww w . ja va 2s . com 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 w w . j a v a 2 s. c om*/ 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.util.Protections.java
License:Open Source License
/** * Visibility control for role fields/methods. The public case is already handled outside. *///from ww w.j a v a 2 s.com public static boolean canBeSeenBy(IProtectable binding, TypeBinding receiverType, InvocationSite invocationSite, Scope scope) { // never legal for non-public features: if (RoleTypeBinding.isRoleWithExplicitAnchor(receiverType)) return false; // callin methods are not subject to visibility control: if ((binding.modifiers() & ExtraCompilerModifiers.AccCallin) != 0) return true; ReferenceBinding declaringClass = (ReferenceBinding) binding.getDeclaringClass().getRealClass().erasure(); ReferenceBinding invocationType = scope.enclosingSourceType(); // special privilege for tsuper calls: if (invocationSite instanceof TSuperMessageSend && invocationType.isRole()) { // check all tsupers, but not mixing with explicit supers if (invocationType.roleModel.hasTSuperRole(declaringClass)) return true; } if (binding.isProtected()) { // answer true if the invocationType is the declaringClass or they are in the same package // OR the invocationType is a subclass of the declaringClass // AND the receiverType is the invocationType or its subclass // OR the method is a static method accessed directly through a type // OR previous assertions are true for one of the enclosing type if (TypeBinding.equalsEquals(invocationType, declaringClass)) return true; // instead of package investigate the enclosing team. if (receiverType instanceof ReferenceBinding) { // strengthen all role types relative to the receiver type. ReferenceBinding receiver = (ReferenceBinding) receiverType; declaringClass = (ReferenceBinding) TeamModel.strengthenRoleType(receiver, declaringClass); if (invocationType.isRole()) invocationType = (ReferenceBinding) TeamModel.strengthenRoleType(receiver, invocationType); } // START orig code from FieldBinding: ReferenceBinding currentType = invocationType; int depth = 0; do { /*OT:*/ if (TeamModel.isTeamContainingRole(currentType, declaringClass)) /*OT:*/ return true; if (declaringClass.isSuperclassOf(currentType)) { if (invocationSite.isSuperAccess()) { return true; } // receiverType can be an array binding in one case... see if you can change it if (receiverType instanceof ArrayBinding) { return false; } if (binding.isStatic()) { if (depth > 0) invocationSite.setDepth(depth); return true; // see 1FMEPDL - return invocationSite.isTypeAccess(); } if (TypeBinding.equalsEquals(currentType, receiverType) || currentType.isSuperclassOf((ReferenceBinding) receiverType)) { if (depth > 0) invocationSite.setDepth(depth); return true; } } depth++; currentType = currentType.enclosingType(); } while (currentType != null); return false; } // END orig code // default and private can be accessed from any nested class: // only invocationType is allowed to be nested within declaringClass, // not vice versa: ReferenceBinding currentInvocationType = invocationType; while (currentInvocationType != null) { if (TypeBinding.equalsEquals(currentInvocationType, declaringClass)) return true; currentInvocationType = currentInvocationType.enclosingType(); } // no more hope for private if (binding.isPrivate()) return false; // default visibility (similar to FieldBinding.canBeSeenBy, whith less emphasis on packages): // receiverType can be an array binding in one case... see if you can change it if (receiverType instanceof ArrayBinding) return false; // have access to all super features: // (implicit inheritance is already dealt with by copy inheritance ;-) ) if (invocationSite.isSuperAccess()) invocationType = invocationType.superclass(); ReferenceBinding currentType = (ReferenceBinding) (invocationType.isInterface() ? ((ReferenceBinding) receiverType).getRealType().erasure() : ((ReferenceBinding) receiverType).getRealClass().erasure()); PackageBinding declaringPackage = declaringClass.fPackage; do { if (TypeBinding.equalsEquals(invocationType, currentType)) return true; if (!currentType.isRole() // when leaving team contexts ... && declaringPackage != currentType.fPackage) // ... compare the packages instead. return false; } while ((currentType = currentType.superclass()) != null); return false; }