### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java,v retrieving revision 1.56 diff -u -r1.56 ASTModelBridgeTests.java --- src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java 14 May 2008 20:49:17 -0000 1.56 +++ src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java 22 May 2008 14:45:28 -0000 @@ -1393,6 +1393,29 @@ } /* + * Ensures that the IJavaElement of an IBinding representing a local variable in an initializer is correct. + * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=217287 ) + */ + public void testLocalVariable5() throws JavaModelException { + ASTNode node = buildAST( + "public class X {\n" + + " {\n" + + " int /*start*/local/*end*/;\n" + + " }\n" + + "}" + ); + IBinding binding = ((VariableDeclaration) node).resolveBinding(); + assertNotNull("No binding", binding); + IJavaElement element = binding.getJavaElement(); + IJavaElement expected = getLocalVariable(this.workingCopy, "local", "local"); + assertEquals( + "Unexpected Java element", + expected, + element + ); + } + + /* * Ensures that the IJavaElement of an IBinding representing a member type is correct. */ public void testMemberType() throws JavaModelException { #P org.eclipse.jdt.core Index: model/org/eclipse/jdt/internal/core/util/Util.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java,v retrieving revision 1.118 diff -u -r1.118 Util.java --- model/org/eclipse/jdt/internal/core/util/Util.java 24 Apr 2008 08:53:05 -0000 1.118 +++ model/org/eclipse/jdt/internal/core/util/Util.java 22 May 2008 14:45:31 -0000 @@ -1291,6 +1291,31 @@ } /** + * Returns the IInitializer that contains the given local variable in the given type + */ + public static JavaElement getUnresolvedJavaElement(int localSourceStart, int localSourceEnd, JavaElement type) { + try { + if (!(type instanceof IType)) + return null; + IInitializer[] initializers = ((IType) type).getInitializers(); + for (int i = 0; i < initializers.length; i++) { + IInitializer initializer = initializers[i]; + ISourceRange sourceRange = initializer.getSourceRange(); + if (sourceRange != null) { + int initializerStart = sourceRange.getOffset(); + int initializerEnd = initializerStart + sourceRange.getLength(); + if (initializerStart <= localSourceStart && localSourceEnd <= initializerEnd) { + return (JavaElement) initializer; + } + } + } + return null; + } catch (JavaModelException e) { + return null; + } + } + + /** * Return the java element corresponding to the given compiler binding. */ public static JavaElement getUnresolvedJavaElement(MethodBinding methodBinding, WorkingCopyOwner workingCopyOwner, BindingsToNodesMap bindingsToNodes) { Index: dom/org/eclipse/jdt/core/dom/VariableBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java,v retrieving revision 1.59 diff -u -r1.59 VariableBinding.java --- dom/org/eclipse/jdt/core/dom/VariableBinding.java 6 Mar 2008 15:31:31 -0000 1.59 +++ dom/org/eclipse/jdt/core/dom/VariableBinding.java 22 May 2008 14:45:31 -0000 @@ -13,8 +13,10 @@ import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.util.IModifierConstants; +import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.impl.Constant; +import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; import org.eclipse.jdt.internal.compiler.lookup.TagBits; @@ -212,10 +214,6 @@ } } // local variable - IMethodBinding declaringMethod = getDeclaringMethod(); - if (declaringMethod == null) return null; - JavaElement method = (JavaElement) declaringMethod.getJavaElement(); - if (method == null) return null; if (!(this.resolver instanceof DefaultBindingResolver)) return null; VariableDeclaration localVar = (VariableDeclaration) ((DefaultBindingResolver) this.resolver).bindingsToAstNodes.get(this); if (localVar == null) return null; @@ -236,8 +234,34 @@ sourceStart = node.getStartPosition(); sourceLength = node.getLength(); } + int sourceEnd = sourceStart+sourceLength-1; char[] typeSig = this.binding.type.genericTypeSignature(); - return new LocalVariable(method, localVar.getName().getIdentifier(), sourceStart, sourceStart+sourceLength-1, nameStart, nameStart+nameLength-1, new String(typeSig), ((LocalVariableBinding) this.binding).declaration.annotations); + JavaElement parent = null; + IMethodBinding declaringMethod = getDeclaringMethod(); + if (declaringMethod == null) { + ReferenceContext referenceContext = ((LocalVariableBinding) binding).declaringScope.referenceContext(); + if (referenceContext instanceof TypeDeclaration){ + // Local variable is declared inside an initializer + TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext; + JavaElement typeHandle = null; + if (this.resolver instanceof DefaultBindingResolver) { + DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver; + typeHandle = Util.getUnresolvedJavaElement( + typeDeclaration.binding, + defaultBindingResolver.workingCopyOwner, + defaultBindingResolver.getBindingsToNodesMap()); + } else { + typeHandle = Util.getUnresolvedJavaElement(typeDeclaration.binding, null, null); + } + parent = Util.getUnresolvedJavaElement(sourceStart, sourceEnd, typeHandle); + } else { + return null; + } + } else { + parent = (JavaElement) declaringMethod.getJavaElement(); + } + if (parent == null) return null; + return new LocalVariable(parent, localVar.getName().getIdentifier(), sourceStart, sourceEnd, nameStart, nameStart+nameLength-1, new String(typeSig), ((LocalVariableBinding) this.binding).declaration.annotations); } /* Index: codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java,v retrieving revision 1.4 diff -u -r1.4 InternalExtendedCompletionContext.java --- codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java 12 May 2008 15:25:57 -0000 1.4 +++ codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java 22 May 2008 14:45:31 -0000 @@ -14,10 +14,7 @@ import java.util.Map; import org.eclipse.jdt.core.ICompilationUnit; -import org.eclipse.jdt.core.IInitializer; import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.ISourceRange; -import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeRoot; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.WorkingCopyOwner; @@ -227,29 +224,8 @@ // Local variable is declared inside an initializer TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext; - IType type = (IType)this.getJavaElementOfCompilationUnit(typeDeclaration, typeDeclaration.binding); - if (type != null) { - try { - IInitializer[] initializers = type.getInitializers(); - if (initializers != null) { - done : for (int i = 0; i < initializers.length; i++) { - IInitializer initializer = initializers[i]; - ISourceRange sourceRange = initializer.getSourceRange(); - if (sourceRange != null) { - int initializerStart = sourceRange.getOffset(); - int initializerEnd = initializerStart + sourceRange.getLength(); - if (initializerStart <= local.sourceStart && - local.sourceEnd <= initializerEnd) { - parent = (JavaElement)initializer; - break done; - } - } - } - } - } catch (JavaModelException e) { - return null; - } - } + JavaElement type = this.getJavaElementOfCompilationUnit(typeDeclaration, typeDeclaration.binding); + parent = Util.getUnresolvedJavaElement(local.sourceStart, local.sourceEnd, type); } if (parent == null) return null; @@ -263,7 +239,7 @@ Util.typeSignature(local.type), binding.declaration.annotations); } - + private JavaElement getJavaElementOfCompilationUnit(Binding binding) { if (!this.hasComputedEnclosingJavaElements) { computeEnclosingJavaElements();