diff options
author | Tomasz Zarna | 2012-08-14 00:34:34 +0000 |
---|---|---|
committer | Stephan Herrmann | 2012-08-20 19:51:53 +0000 |
commit | 14351256ec850a5193ed6efb0200d1f684a2a593 (patch) | |
tree | c0767040a93f75beac4836e80fc2f6a4ec98a329 | |
parent | 41f7d0ff387fdc5f8ae66df5a4d98e066bb11be4 (diff) | |
download | eclipse.jdt.core-14351256ec850a5193ed6efb0200d1f684a2a593.tar.gz eclipse.jdt.core-14351256ec850a5193ed6efb0200d1f684a2a593.tar.xz eclipse.jdt.core-14351256ec850a5193ed6efb0200d1f684a2a593.zip |
Fixed bug 297825: [search] Rename refactoring doesn't update enclosing
type
10 files changed, 271 insertions, 7 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java index 922907141f..15b8c2580e 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java @@ -456,7 +456,172 @@ public class JavaSearchBugsTests2 extends AbstractJavaSearchTests { deleteProject(project); } } + /** + * @bug 297825: [search] Rename refactoring doesn't update enclosing type + * @test Search for references for enclosing type's subclass should return a match. + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=297825" + */ + public void testBug297825a() throws CoreException { + try { + IJavaProject p = createJavaProject("P", new String[] { "src" }, + new String[] {"JCL_LIB"}, "bin"); + createFolder("/P/src/b297825"); + createFile("/P/src/b297825/_Foo.java", + "package b297825;\n" + + "public class _Foo {\n" + + " public static class Bar {\n" + + " }\n" + + "}" + ); + createFile("/P/src/b297825/Foo.java", + "package b297825;\n" + + "public class Foo extends _Foo {\n" + + "}\n" + ); + createFile("/P/src/b297825/Main.java", + "package b297825;\n" + + "public class Main {\n" + + " public static void main(String[] args) {\n" + + " new Foo.Bar();\n" + + " }\n" + + "}" + ); + waitUntilIndexesReady(); + IType type = getCompilationUnit("/P/src/b297825/Foo.java").getType("Foo"); + IJavaSearchScope scope = SearchEngine + .createJavaSearchScope(new IJavaElement[] { p }, IJavaSearchScope.SOURCES); + + search(type, REFERENCES, scope, this.resultCollector); + + assertSearchResults("src/b297825/Main.java void b297825.Main.main(String[]) [Foo] EXACT_MATCH"); + } finally { + deleteProject("P"); + } + } + /** + * @bug 297825: [search] Rename refactoring doesn't update enclosing type + * @test Verify there is no AIOOB when searching for references for a type. + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=297825" + */ + public void testBug297825b() throws CoreException { + try { + IJavaProject p = createJavaProject("P", new String[] { "src" }, + new String[] {"JCL_LIB"}, "bin"); + createFile("/P/src/Foo.java", + "class _Foo {\n" + + " public static class Bar {\n" + + " }\n" + + "}" + + "public class Foo extends _Foo {\n" + + " public static class FooBar {\n" + + " }\n" + + "}" + + "class Main {\n" + + " public static void main(String[] args) {\n" + + " new Foo.Bar();\n" + + " new Foo.FooBar();\n" + + " }\n" + + "}" + ); + waitUntilIndexesReady(); + IType type = getCompilationUnit("/P/src/Foo.java").getType("Foo"); + IJavaSearchScope scope = SearchEngine + .createJavaSearchScope(new IJavaElement[] { p }, IJavaSearchScope.SOURCES); + + search(type, REFERENCES, scope, this.resultCollector); + + assertSearchResults("src/Foo.java void Main.main(String[]) [Foo] EXACT_MATCH\n" + + "src/Foo.java void Main.main(String[]) [Foo] EXACT_MATCH"); + } finally { + deleteProject("P"); + } + } + /** + * @bug 297825: [search] Rename refactoring doesn't update enclosing type + * @test Search for references for the top level type Foo should report no match. "new _Foo.Bar.Foo()" refers to a different type. + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=297825" + */ + public void testBug297825c() throws CoreException { + try { + IJavaProject p = createJavaProject("P", new String[] { "src" }, + new String[] {"JCL_LIB"}, "bin"); + createFolder("/P/src/b297825"); + createFile("/P/src/b297825/_Foo.java", + "package b297825;\n" + + "public class _Foo {\n" + + " public static class Bar {\n" + + " public static class Foo {\n" + + " }\n" + + " }\n" + + "}" + ); + createFile("/P/src/b297825/Foo.java", + "package b297825;\n" + + "public class Foo extends _Foo {\n" + + "}" + ); + createFile("/P/src/b297825/Main.java", + "package b297825;\n" + + "class Main {\n" + + " public static void main(String[] args) {\n" + + " new _Foo.Bar.Foo();\n" + + " }\n" + + "}" + ); + waitUntilIndexesReady(); + IType type = getCompilationUnit("/P/src/b297825/Foo.java").getType("Foo"); + IJavaSearchScope scope = SearchEngine + .createJavaSearchScope(new IJavaElement[] { p }, IJavaSearchScope.SOURCES); + + search(type, REFERENCES, scope, this.resultCollector); + assertSearchResults(""); + } finally { + deleteProject("P"); + } + } + /** + * @bug 297825: [search] Rename refactoring doesn't update enclosing type + * @test Search for references for enclosing type's subclass should return a match. The inner type is parameterized. + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=297825" + */ + public void testBug297825d() throws CoreException { + try { + IJavaProject p = createJavaProject("P", new String[] { "src" }, + new String[] {"JCL_LIB"}, "bin"); + createFolder("/P/src/b297825"); + createFile("/P/src/b297825/_Foo.java", + "package b297825;\n" + + "public class _Foo {\n" + + " public static class Bar<T> {\n" + + " }\n" + + "}" + ); + createFile("/P/src/b297825/Foo.java", + "package b297825;\n" + + "public class Foo extends _Foo {\n" + + "}\n" + ); + createFile("/P/src/b297825/Main.java", + "package b297825;\n" + + "public class Main {\n" + + " public static void main(String[] args) {\n" + + " new Foo.Bar<String>();\n" + + " }\n" + + "}" + ); + waitUntilIndexesReady(); + IType type = getCompilationUnit("/P/src/b297825/Foo.java").getType("Foo"); + IJavaSearchScope scope = SearchEngine + .createJavaSearchScope(new IJavaElement[] { p }, IJavaSearchScope.SOURCES); + + search(type, REFERENCES, scope, this.resultCollector); + + assertSearchResults("src/b297825/Main.java void b297825.Main.main(String[]) [Foo] EXACT_MATCH"); + } finally { + deleteProject("P"); + } + } /** * @bug 342393: Anonymous class' occurrence count is incorrect when two methods in a class have the same name. * @test Search for Enumerators with anonymous types diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java index 0d322a1927..ebe6eb7e1d 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java @@ -318,6 +318,7 @@ public class ParameterizedQualifiedTypeReference extends ArrayQualifiedTypeRefer if (isTypeUseDeprecated(qualifyingType, scope)) reportDeprecatedType(qualifyingType, scope, i); this.resolvedType = qualifyingType; + recordResolution(scope.environment(), this.resolvedType); } return this.resolvedType; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java index 33cb1f2542..aea88c0d14 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java @@ -126,11 +126,19 @@ public class QualifiedTypeReference extends TypeReference { } else { qualifiedType = currentType.isGenericType() ? (ReferenceBinding)scope.environment().convertToRawType(currentType, false /*do not force conversion of enclosing types*/) : currentType; } + recordResolution(scope.environment(), qualifiedType); } this.resolvedType = qualifiedType; return this.resolvedType; } + void recordResolution(LookupEnvironment env, TypeBinding typeFound) { + if (typeFound != null && typeFound.isValidBinding()) + for (int i = 0; i < env.resolutionListeners.length; i++) { + env.resolutionListeners[i].recordResolution(this, typeFound); + } + } + public char[][] getTypeName(){ return this.tokens; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IQualifiedTypeResolutionListener.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IQualifiedTypeResolutionListener.java new file mode 100644 index 0000000000..273fda2b67 --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IQualifiedTypeResolutionListener.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2012 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.compiler.lookup; + +import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; + +/** + * A listener, which gets notified when a type binding has been discovered. + * <p> + * This interface may be implemented by clients. + * </p> + */ +public interface IQualifiedTypeResolutionListener { + + /** + * Notifies that the given resolution has been found for the given type reference. Some of the bindings are + * intermediate types i.e. qualifying types. + * + * @param typeReference + * the type reference + * @param resolution + * the resolution found + */ + public void recordResolution(QualifiedTypeReference typeReference, TypeBinding resolution); +} diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java index bbd66c614f..16eaba3b95 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java @@ -1529,4 +1529,17 @@ void updateCaches(UnresolvedReferenceBinding unresolvedType, ReferenceBinding re } } } + +public IQualifiedTypeResolutionListener[] resolutionListeners = new IQualifiedTypeResolutionListener[0]; + +public void addResolutionListener(IQualifiedTypeResolutionListener resolutionListener) { + int length = this.resolutionListeners.length; + for (int i = 0; i < length; i++){ + if (this.resolutionListeners[i].equals(resolutionListener)) + return; + } + System.arraycopy(this.resolutionListeners, 0, + this.resolutionListeners = new IQualifiedTypeResolutionListener[length + 1], 0, length); + this.resolutionListeners[length] = resolutionListener; +} } diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndLocator.java index e026c7f592..9e9b2aa857 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndLocator.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndLocator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 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 @@ -23,11 +23,13 @@ import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; import org.eclipse.jdt.internal.compiler.ast.MemberValuePair; import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; +import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.Reference; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeParameter; import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.lookup.Binding; +import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; public class AndLocator extends PatternLocator { @@ -263,5 +265,9 @@ void setFlavors(int flavors) { this.patternLocators[i].setFlavors(flavors); } } - +public void recordResolution(QualifiedTypeReference typeReference, TypeBinding resolution) { + for (int i = 0, length = this.patternLocators.length; i < length; i++) { + this.patternLocators[i].recordResolution(typeReference, resolution); + } +} } diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java index ccd1838629..5585ae9fa4 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java @@ -1061,6 +1061,8 @@ public void initialize(JavaProject project, int possibleMatchSize) throws JavaMo // initialize queue of units this.numberOfMatches = 0; this.matchesToProcess = new PossibleMatch[possibleMatchSize]; + + this.lookupEnvironment.addResolutionListener(this.patternLocator); } protected void locateMatches(JavaProject javaProject, PossibleMatch[] possibleMatches, int start, int length) throws CoreException { initialize(javaProject, length); diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java index 9876b7ce60..f435ac755d 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 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 @@ -24,6 +24,7 @@ import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; import org.eclipse.jdt.internal.compiler.ast.MemberValuePair; import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; +import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.Reference; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeParameter; @@ -32,6 +33,7 @@ import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; import org.eclipse.jdt.internal.compiler.lookup.MemberTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; +import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; public class OrLocator extends PatternLocator { @@ -315,5 +317,9 @@ void setFlavors(int flavors) { this.patternLocators[i].setFlavors(flavors); } } - +public void recordResolution(QualifiedTypeReference typeReference, TypeBinding resolution) { + for (int i = 0, length = this.patternLocators.length; i < length; i++) { + this.patternLocators[i].recordResolution(typeReference, resolution); + } +} } diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java index 6cb561f44d..7992580ac5 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java @@ -18,7 +18,7 @@ import org.eclipse.jdt.internal.compiler.ast.*; import org.eclipse.jdt.internal.compiler.lookup.*; import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants; -public abstract class PatternLocator implements IIndexConstants { +public abstract class PatternLocator implements IIndexConstants, IQualifiedTypeResolutionListener { // store pattern info protected int matchMode; @@ -970,4 +970,7 @@ protected int resolveLevelForType (char[] simpleNamePattern, public String toString(){ return "SearchPattern"; //$NON-NLS-1$ } +public void recordResolution(QualifiedTypeReference typeReference, TypeBinding resolution) { + // noop by default +} } diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java index 137c9c85fa..ddea928667 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2012 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 @@ -10,6 +10,12 @@ *******************************************************************************/ package org.eclipse.jdt.internal.core.search.matching; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.*; import org.eclipse.jdt.core.*; @@ -680,7 +686,7 @@ protected int resolveLevel(TypeReference typeRef) { if (typeRef instanceof SingleTypeReference) { return resolveLevelForType(typeBinding); } else - return resolveLevelForTypeOrEnclosingTypes(this.pattern.simpleName, this.pattern.qualification, typeBinding); + return resolveLevelForTypeOrQualifyingTypes(typeRef, typeBinding); } /* (non-Javadoc) * Resolve level for type with a given binding. @@ -742,6 +748,27 @@ protected int resolveLevelForTypeOrEnclosingTypes(char[] simpleNamePattern, char } return IMPOSSIBLE_MATCH; } +private Map/*<QualifiedTypeReference, List<TypeBinding>>*/ recordedResolutions = new HashMap(); +int resolveLevelForTypeOrQualifyingTypes(TypeReference typeRef, TypeBinding typeBinding) { + if (typeBinding == null || !typeBinding.isValidBinding()) return INACCURATE_MATCH; + List resolutionsList = (List) this.recordedResolutions.get(typeRef); + if (resolutionsList != null) { + for (Iterator i = resolutionsList.iterator(); i.hasNext();) { + TypeBinding resolution = (TypeBinding) i.next(); + int level = resolveLevelForType(resolution); + if (level != IMPOSSIBLE_MATCH) return level; + } + } + return IMPOSSIBLE_MATCH; +} +public void recordResolution(QualifiedTypeReference typeReference, TypeBinding resolution) { + List/*<TypeBinding>*/ resolutionsForTypeReference = (List) this.recordedResolutions.get(typeReference); + if (resolutionsForTypeReference == null) { + resolutionsForTypeReference = new ArrayList(); + } + resolutionsForTypeReference.add(resolution); + this.recordedResolutions.put(typeReference, resolutionsForTypeReference); +} public String toString() { return "Locator for " + this.pattern.toString(); //$NON-NLS-1$ } |