/******************************************************************************* * Copyright (c) 2008, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.codeassist; import java.util.HashMap; import java.util.Map; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.ITypeRoot; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.WorkingCopyOwner; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.codeassist.complete.CompletionNodeDetector; import org.eclipse.jdt.internal.codeassist.complete.CompletionParser; import org.eclipse.jdt.internal.codeassist.impl.AssistCompilationUnit; import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.Initializer; import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeParameter; import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; import org.eclipse.jdt.internal.compiler.lookup.ClassScope; import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; import org.eclipse.jdt.internal.compiler.lookup.ImportBinding; import org.eclipse.jdt.internal.compiler.lookup.InvocationSite; import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment; import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; import org.eclipse.jdt.internal.compiler.lookup.MethodScope; import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; import org.eclipse.jdt.internal.compiler.lookup.Scope; import org.eclipse.jdt.internal.compiler.lookup.SignatureWrapper; import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; import org.eclipse.jdt.internal.compiler.util.ObjectVector; import org.eclipse.jdt.internal.core.CompilationUnitElementInfo; import org.eclipse.jdt.internal.core.JavaElement; import org.eclipse.jdt.internal.core.LocalVariable; import org.eclipse.jdt.internal.core.util.Util; public class InternalExtendedCompletionContext { private static Util.BindingsToNodesMap EmptyNodeMap = new Util.BindingsToNodesMap() { public ASTNode get(Binding binding) { return null; } }; private InternalCompletionContext completionContext; // static data private ITypeRoot typeRoot; private CompilationUnitDeclaration compilationUnitDeclaration; private LookupEnvironment lookupEnvironment; private Scope assistScope; private ASTNode assistNode; private WorkingCopyOwner owner; private CompletionParser parser; // computed data private boolean hasComputedVisibleElementBindings; private ObjectVector visibleLocalVariables; private ObjectVector visibleFields; private ObjectVector visibleMethods; private boolean hasComputedEnclosingJavaElements; private Map bindingsToHandles; private Map nodesWithProblemsToHandles; private ICompilationUnit compilationUnit; public InternalExtendedCompletionContext( InternalCompletionContext completionContext, ITypeRoot typeRoot, CompilationUnitDeclaration compilationUnitDeclaration, LookupEnvironment lookupEnvironment, Scope assistScope, ASTNode assistNode, WorkingCopyOwner owner, CompletionParser parser) { this.completionContext = completionContext; this.typeRoot = typeRoot; this.compilationUnitDeclaration = compilationUnitDeclaration; this.lookupEnvironment = lookupEnvironment; this.assistScope = assistScope; this.assistNode = assistNode; this.owner = owner; this.parser = parser; } private void computeEnclosingJavaElements() { this.hasComputedEnclosingJavaElements = true; if (this.typeRoot == null) return; if (this.typeRoot.getElementType() == IJavaElement.COMPILATION_UNIT) { ICompilationUnit original = (org.eclipse.jdt.core.ICompilationUnit)this.typeRoot; HashMap handleToBinding = new HashMap(); HashMap bindingToHandle = new HashMap(); HashMap nodeWithProblemToHandle = new HashMap(); HashMap handleToInfo = new HashMap(); org.eclipse.jdt.core.ICompilationUnit handle = new AssistCompilationUnit(original, this.owner, handleToBinding, handleToInfo); CompilationUnitElementInfo info = new CompilationUnitElementInfo(); handleToInfo.put(handle, info); CompletionUnitStructureRequestor structureRequestor = new CompletionUnitStructureRequestor( handle, info, this.parser, this.assistNode, handleToBinding, bindingToHandle, nodeWithProblemToHandle, handleToInfo); CompletionElementNotifier notifier = new CompletionElementNotifier( structureRequestor, true, this.assistNode); notifier.notifySourceElementRequestor( this.compilationUnitDeclaration, this.compilationUnitDeclaration.sourceStart, this.compilationUnitDeclaration.sourceEnd, false, this.parser.sourceEnds, new HashMap()); this.bindingsToHandles = bindingToHandle; this.nodesWithProblemsToHandles = nodeWithProblemToHandle; this.compilationUnit = handle; } } private void computeVisibleElementBindings() { CompilationUnitDeclaration previousUnitBeingCompleted = this.lookupEnvironment.unitBeingCompleted; this.lookupEnvironment.unitBeingCompleted = this.compilationUnitDeclaration; try { this.hasComputedVisibleElementBindings = true; Scope scope = this.assistScope; ASTNode astNode = this.assistNode; boolean notInJavadoc = this.completionContext.javadoc == 0; this.visibleLocalVariables = new ObjectVector(); this.visibleFields = new ObjectVector(); this.visibleMethods = new ObjectVector(); ReferenceContext referenceContext = scope.referenceContext(); if (referenceContext instanceof AbstractMethodDeclaration) { // completion is inside a method body searchVisibleVariablesAndMethods(scope, this.visibleLocalVariables, this.visibleFields, this.visibleMethods, notInJavadoc); } else if (referenceContext instanceof TypeDeclaration) { TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext; FieldDeclaration[] fields = typeDeclaration.fields; if (fields != null) { done : for (int i = 0; i < fields.length; i++) { if (fields[i] instanceof Initializer) { Initializer initializer = (Initializer) fields[i]; if (initializer.block.sourceStart <= astNode.sourceStart && astNode.sourceStart < initializer.bodyEnd) { // completion is inside an initializer searchVisibleVariablesAndMethods(scope, this.visibleLocalVariables, this.visibleFields, this.visibleMethods, notInJavadoc); break done; } } else { FieldDeclaration fieldDeclaration = fields[i]; if (fieldDeclaration.initialization != null) { boolean isInsideInitializer = false; if (fieldDeclaration.initialization.sourceEnd > 0) { if (fieldDeclaration.initialization.sourceStart <= astNode.sourceStart && astNode.sourceEnd <= fieldDeclaration.initialization.sourceEnd) { // completion is inside a field initializer isInsideInitializer = true; } } else { // The sourceEnd may not yet be set CompletionNodeDetector detector = new CompletionNodeDetector(this.assistNode, fieldDeclaration.initialization); if (detector.containsCompletionNode()) { // completion is inside a field initializer isInsideInitializer = true; } } if (isInsideInitializer) { searchVisibleVariablesAndMethods(scope, this.visibleLocalVariables, this.visibleFields, this.visibleMethods, notInJavadoc); // remove this field from visibleFields list because completion is being asked in its // intialization and so this has not yet been declared successfully. if (this.visibleFields.size > 0 && this.visibleFields.contains(fieldDeclaration.binding)) { this.visibleFields.remove(fieldDeclaration.binding); } int count = 0; while (count < this.visibleFields.size) { FieldBinding visibleField = (FieldBinding)this.visibleFields.elementAt(count); if (visibleField.id > fieldDeclaration.binding.id) { this.visibleFields.remove(visibleField); continue; } count++; } break done; } } } } } } } finally { this.lookupEnvironment.unitBeingCompleted = previousUnitBeingCompleted; } } public IJavaElement getEnclosingElement() { try { if (!this.hasComputedEnclosingJavaElements) { computeEnclosingJavaElements(); } if (this.compilationUnit == null) return null; IJavaElement enclosingElement = this.compilationUnit.getElementAt(this.completionContext.offset); return enclosingElement == null ? this.compilationUnit : enclosingElement; } catch (JavaModelException e) { Util.log(e, "Cannot compute enclosing element"); //$NON-NLS-1$ return null; } } private JavaElement getJavaElement(LocalVariableBinding binding) { LocalDeclaration local = binding.declaration; JavaElement parent = null; ReferenceContext referenceContext = binding.declaringScope.referenceContext(); if (referenceContext instanceof AbstractMethodDeclaration) { AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) referenceContext; parent = this.getJavaElementOfCompilationUnit(methodDeclaration, methodDeclaration.binding); } else if (referenceContext instanceof TypeDeclaration){ // Local variable is declared inside an initializer TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext; JavaElement type = this.getJavaElementOfCompilationUnit(typeDeclaration, typeDeclaration.binding); parent = Util.getUnresolvedJavaElement(local.sourceStart, local.sourceEnd, type); } if (parent == null) return null; return new LocalVariable( parent, new String(local.name), local.declarationSourceStart, local.declarationSourceEnd, local.sourceStart, local.sourceEnd, Util.typeSignature(local.type), binding.declaration.annotations, local.modifiers, local.getKind() == AbstractVariableDeclaration.PARAMETER); } private JavaElement getJavaElementOfCompilationUnit(Binding binding) { if (!this.hasComputedEnclosingJavaElements) { computeEnclosingJavaElements(); } if (this.bindingsToHandles == null) return null; return (JavaElement)this.bindingsToHandles.get(binding); } private JavaElement getJavaElementOfCompilationUnit(ASTNode node, Binding binding) { if (!this.hasComputedEnclosingJavaElements) { computeEnclosingJavaElements(); } if (binding != null) { if (this.bindingsToHandles == null) return null; return (JavaElement)this.bindingsToHandles.get(binding); } else { if (this.nodesWithProblemsToHandles == null) return null; return (JavaElement)this.nodesWithProblemsToHandles.get(node); } } private TypeBinding getTypeFromSignature(String typeSignature, Scope scope) { TypeBinding assignableTypeBinding = null; TypeVariableBinding[] typeVariables = Binding.NO_TYPE_VARIABLES; ReferenceContext referenceContext = scope.referenceContext(); if (referenceContext instanceof AbstractMethodDeclaration) { AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) referenceContext; TypeParameter[] typeParameters = methodDeclaration.typeParameters(); if (typeParameters != null && typeParameters.length > 0) { int length = typeParameters.length; int count = 0; typeVariables = new TypeVariableBinding[length]; for (int i = 0; i < length; i++) { if (typeParameters[i].binding != null) { typeVariables[count++] = typeParameters[i].binding; } } if (count != length) { System.arraycopy(typeVariables, 0, typeVariables = new TypeVariableBinding[count], 0, count); } } } CompilationUnitDeclaration previousUnitBeingCompleted = this.lookupEnvironment.unitBeingCompleted; this.lookupEnvironment.unitBeingCompleted = this.compilationUnitDeclaration; try { SignatureWrapper wrapper = new SignatureWrapper(replacePackagesDot(typeSignature.toCharArray())); assignableTypeBinding = this.lookupEnvironment.getTypeFromTypeSignature(wrapper, typeVariables, this.assistScope.enclosingClassScope().referenceContext.binding, null); assignableTypeBinding = BinaryTypeBinding.resolveType(assignableTypeBinding, this.lookupEnvironment, true); } catch (AbortCompilation e) { assignableTypeBinding = null; } finally { this.lookupEnvironment.unitBeingCompleted = previousUnitBeingCompleted; } return assignableTypeBinding; } private char[] replacePackagesDot(char[] signature) { boolean replace = true; int length = signature.length; for (int i = 0; i < length; i++) { switch (signature[i]) { case '.': if (replace) signature[i] = '/'; break; case '<': replace = true; break; case '>': replace = false; break; } } return signature; } public IJavaElement[] getVisibleElements(String typeSignature) { if (this.assistScope == null) return new IJavaElement[0]; if (!this.hasComputedVisibleElementBindings) { computeVisibleElementBindings(); } TypeBinding assignableTypeBinding = null; if (typeSignature != null) { assignableTypeBinding = getTypeFromSignature(typeSignature, this.assistScope); if (assignableTypeBinding == null) return new IJavaElement[0]; } int length = this.visibleLocalVariables.size() + this.visibleFields.size() + this.visibleMethods.size(); if (length == 0) return new IJavaElement[0]; IJavaElement[] result = new IJavaElement[length]; int elementCount = 0; int size = this.visibleLocalVariables.size(); if (size > 0) { next : for (int i = 0; i < size; i++) { try { LocalVariableBinding binding = (LocalVariableBinding) this.visibleLocalVariables.elementAt(i); if (binding.type == null || (assignableTypeBinding != null && !binding.type.isCompatibleWith(assignableTypeBinding))) continue next; JavaElement localVariable = getJavaElement(binding); if (localVariable != null) result[elementCount++] = localVariable; } catch(AbortCompilation e) { // log the exception and proceed Util.logRepeatedMessage(e.getKey(), e); } } } size = this.visibleFields.size(); if (size > 0) { next : for (int i = 0; i < size; i++) { try { FieldBinding binding = (FieldBinding) this.visibleFields.elementAt(i); if (assignableTypeBinding != null && !binding.type.isCompatibleWith(assignableTypeBinding)) continue next; if (this.assistScope.isDefinedInSameUnit(binding.declaringClass)) { JavaElement field = getJavaElementOfCompilationUnit(binding); if (field != null) result[elementCount++] = field; } else { JavaElement field = Util.getUnresolvedJavaElement(binding, this.owner, EmptyNodeMap); if (field != null) result[elementCount++] = field.resolved(binding); } } catch(AbortCompilation e) { // log the exception and proceed Util.logRepeatedMessage(e.getKey(), e); } } } size = this.visibleMethods.size(); if (size > 0) { next : for (int i = 0; i < size; i++) { try { MethodBinding binding = (MethodBinding) this.visibleMethods.elementAt(i); if (assignableTypeBinding != null && !binding.returnType.isCompatibleWith(assignableTypeBinding)) continue next; if (this.assistScope.isDefinedInSameUnit(binding.declaringClass)) { JavaElement method = getJavaElementOfCompilationUnit(binding); if (method != null) result[elementCount++] = method; } else { JavaElement method = Util.getUnresolvedJavaElement(binding, this.owner, EmptyNodeMap); if (method != null) result[elementCount++] = method.resolved(binding); } } catch(AbortCompilation e) { // log the exception and proceed Util.logRepeatedMessage(e.getKey(), e); } } } if (elementCount != result.length) { System.arraycopy(result, 0, result = new IJavaElement[elementCount], 0, elementCount); } return result; } private void searchVisibleFields( FieldBinding[] fields, ReferenceBinding receiverType, Scope scope, InvocationSite invocationSite, Scope invocationScope, boolean onlyStaticFields, ObjectVector localsFound, ObjectVector fieldsFound) { ObjectVector newFieldsFound = new ObjectVector(); // Inherited fields which are hidden by subclasses are filtered out // No visibility checks can be performed without the scope & invocationSite next : for (int f = fields.length; --f >= 0;) { FieldBinding field = fields[f]; if (field.isSynthetic()) continue next; if (onlyStaticFields && !field.isStatic()) continue next; if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next; for (int i = fieldsFound.size; --i >= 0;) { FieldBinding otherField = (FieldBinding) fieldsFound.elementAt(i); if (CharOperation.equals(field.name, otherField.name, true)) { continue next; } } for (int l = localsFound.size; --l >= 0;) { LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l); if (CharOperation.equals(field.name, local.name, true)) { continue next; } } newFieldsFound.add(field); } fieldsFound.addAll(newFieldsFound); } private void searchVisibleFields( ReferenceBinding receiverType, Scope scope, InvocationSite invocationSite, Scope invocationScope, boolean onlyStaticFields, boolean notInJavadoc, ObjectVector localsFound, ObjectVector fieldsFound) { ReferenceBinding currentType = receiverType; ReferenceBinding[] interfacesToVisit = null; int nextPosition = 0; do { ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); if (notInJavadoc && 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; } } } FieldBinding[] fields = currentType.availableFields(); if(fields != null && fields.length > 0) { searchVisibleFields( fields, receiverType, scope, invocationSite, invocationScope, onlyStaticFields, localsFound, fieldsFound); } currentType = currentType.superclass(); } while (notInJavadoc && currentType != null); if (notInJavadoc && interfacesToVisit != null) { for (int i = 0; i < nextPosition; i++) { ReferenceBinding anInterface = interfacesToVisit[i]; FieldBinding[] fields = anInterface.availableFields(); if(fields != null) { searchVisibleFields( fields, receiverType, scope, invocationSite, invocationScope, onlyStaticFields, localsFound, fieldsFound); } ReferenceBinding[] itsInterfaces = anInterface.superInterfaces(); if (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; } } } } } private void searchVisibleInterfaceMethods( ReferenceBinding[] itsInterfaces, ReferenceBinding receiverType, Scope scope, InvocationSite invocationSite, Scope invocationScope, boolean onlyStaticMethods, ObjectVector methodsFound) { if (itsInterfaces != Binding.NO_SUPERINTERFACES) { ReferenceBinding[] interfacesToVisit = itsInterfaces; int nextPosition = interfacesToVisit.length; for (int i = 0; i < nextPosition; i++) { ReferenceBinding currentType = interfacesToVisit[i]; MethodBinding[] methods = currentType.availableMethods(); if(methods != null) { searchVisibleLocalMethods( methods, receiverType, scope, invocationSite, invocationScope, onlyStaticMethods, methodsFound); } itsInterfaces = currentType.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; } } } } } private void searchVisibleLocalMethods( MethodBinding[] methods, ReferenceBinding receiverType, Scope scope, InvocationSite invocationSite, Scope invocationScope, boolean onlyStaticMethods, ObjectVector methodsFound) { ObjectVector newMethodsFound = new ObjectVector(); // Inherited methods which are hidden by subclasses are filtered out // No visibility checks can be performed without the scope & invocationSite next : for (int f = methods.length; --f >= 0;) { MethodBinding method = methods[f]; if (method.isSynthetic()) continue next; if (method.isDefaultAbstract()) continue next; if (method.isConstructor()) continue next; if (onlyStaticMethods && !method.isStatic()) continue next; if (!method.canBeSeenBy(receiverType, invocationSite, scope)) continue next; for (int i = methodsFound.size; --i >= 0;) { MethodBinding otherMethod = (MethodBinding) methodsFound.elementAt(i); if (method == otherMethod) continue next; if (CharOperation.equals(method.selector, otherMethod.selector, true)) { if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) { continue next; } } } newMethodsFound.add(method); } methodsFound.addAll(newMethodsFound); } private void searchVisibleMethods( ReferenceBinding receiverType, Scope scope, InvocationSite invocationSite, Scope invocationScope, boolean onlyStaticMethods, boolean notInJavadoc, ObjectVector methodsFound) { ReferenceBinding currentType = receiverType; if (notInJavadoc) { if (receiverType.isInterface()) { searchVisibleInterfaceMethods( new ReferenceBinding[]{currentType}, receiverType, scope, invocationSite, invocationScope, onlyStaticMethods, methodsFound); currentType = scope.getJavaLangObject(); } } boolean hasPotentialDefaultAbstractMethods = true; while (currentType != null) { MethodBinding[] methods = currentType.availableMethods(); if (methods != null) { searchVisibleLocalMethods( methods, receiverType, scope, invocationSite, invocationScope, onlyStaticMethods, methodsFound); } if (notInJavadoc && hasPotentialDefaultAbstractMethods && (currentType.isAbstract() || currentType.isTypeVariable() || currentType.isIntersectionType() || currentType.isEnum())){ ReferenceBinding[] superInterfaces = currentType.superInterfaces(); if (superInterfaces != null && currentType.isIntersectionType()) { for (int i = 0; i < superInterfaces.length; i++) { superInterfaces[i] = (ReferenceBinding)superInterfaces[i].capture(invocationScope, invocationSite.sourceEnd()); } } searchVisibleInterfaceMethods( superInterfaces, receiverType, scope, invocationSite, invocationScope, onlyStaticMethods, methodsFound); } else { hasPotentialDefaultAbstractMethods = false; } if(currentType.isParameterizedType()) { currentType = ((ParameterizedTypeBinding)currentType).genericType().superclass(); } else { currentType = currentType.superclass(); } } } private void searchVisibleVariablesAndMethods( Scope scope, ObjectVector localsFound, ObjectVector fieldsFound, ObjectVector methodsFound, boolean notInJavadoc) { InvocationSite invocationSite = CompletionEngine.FakeInvocationSite; boolean staticsOnly = false; // need to know if we're in a static context (or inside a constructor) Scope currentScope = scope; done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found switch (currentScope.kind) { case Scope.METHOD_SCOPE : // handle the error case inside an explicit constructor call (see MethodScope>>findField) MethodScope methodScope = (MethodScope) currentScope; staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall; //$FALL-THROUGH$ case Scope.BLOCK_SCOPE : BlockScope blockScope = (BlockScope) currentScope; next : for (int i = 0, length = blockScope.locals.length; i < length; i++) { LocalVariableBinding local = blockScope.locals[i]; if (local == null) break next; if (local.isSecret()) continue next; // If the local variable declaration's initialization statement itself has the completion, // then don't propose the local variable if (local.declaration.initialization != null) { /*(use this if-else block if it is found that local.declaration.initialization != null is not sufficient to guarantee that proposal is being asked inside a local variable declaration's initializer) if(local.declaration.initialization.sourceEnd > 0) { if (this.assistNode.sourceEnd <= local.declaration.initialization.sourceEnd && this.assistNode.sourceStart >= local.declaration.initialization.sourceStart) { continue next; } } else { CompletionNodeDetector detector = new CompletionNodeDetector( this.assistNode, local.declaration.initialization); if (detector.containsCompletionNode()) { continue next; } }*/ continue next; } for (int f = 0; f < localsFound.size; f++) { LocalVariableBinding otherLocal = (LocalVariableBinding) localsFound.elementAt(f); if (CharOperation.equals(otherLocal.name, local.name, true)) continue next; } localsFound.add(local); } break; case Scope.COMPILATION_UNIT_SCOPE : break done1; } currentScope = currentScope.parent; } staticsOnly = false; currentScope = scope; done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found switch (currentScope.kind) { case Scope.METHOD_SCOPE : // handle the error case inside an explicit constructor call (see MethodScope>>findField) MethodScope methodScope = (MethodScope) currentScope; staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall; break; case Scope.CLASS_SCOPE : ClassScope classScope = (ClassScope) currentScope; SourceTypeBinding enclosingType = classScope.referenceContext.binding; searchVisibleFields( enclosingType, classScope, invocationSite, scope, staticsOnly, notInJavadoc, localsFound, fieldsFound); searchVisibleMethods( enclosingType, classScope, invocationSite, scope, staticsOnly, notInJavadoc, methodsFound); staticsOnly |= enclosingType.isStatic(); break; case Scope.COMPILATION_UNIT_SCOPE : break done2; } currentScope = currentScope.parent; } // search in static import ImportBinding[] importBindings = scope.compilationUnitScope().imports; for (int i = 0; i < importBindings.length; i++) { ImportBinding importBinding = importBindings[i]; if(importBinding.isValidBinding() && importBinding.isStatic()) { Binding binding = importBinding.resolvedImport; if(binding != null && binding.isValidBinding()) { if(importBinding.onDemand) { if((binding.kind() & Binding.TYPE) != 0) { searchVisibleFields( (ReferenceBinding)binding, scope, invocationSite, scope, staticsOnly, notInJavadoc, localsFound, fieldsFound); searchVisibleMethods( (ReferenceBinding)binding, scope, invocationSite, scope, staticsOnly, notInJavadoc, methodsFound); } } else { if ((binding.kind() & Binding.FIELD) != 0) { searchVisibleFields( new FieldBinding[]{(FieldBinding)binding}, ((FieldBinding)binding).declaringClass, scope, invocationSite, scope, staticsOnly, localsFound, fieldsFound); } else if ((binding.kind() & Binding.METHOD) != 0) { MethodBinding methodBinding = (MethodBinding)binding; searchVisibleLocalMethods( methodBinding.declaringClass.getMethods(methodBinding.selector), methodBinding.declaringClass, scope, invocationSite, scope, true, methodsFound); } } } } } } }