Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 21125 Details for
Bug 79990
[1.5][search] Search for method declaration doesn't find method with instantiated type parameters
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Patch to implement this fix
v01.txt (text/plain), 20.36 KB, created by
Frederic Fusier
on 2005-05-13 12:44:27 EDT
(
hide
)
Description:
Patch to implement this fix
Filename:
MIME Type:
Creator:
Frederic Fusier
Created:
2005-05-13 12:44:27 EDT
Size:
20.36 KB
patch
obsolete
>Index: search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java,v >retrieving revision 1.242 >diff -u -r1.242 MatchLocator.java >--- search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java 11 May 2005 21:08:37 -0000 1.242 >+++ search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java 13 May 2005 16:32:42 -0000 >@@ -38,6 +38,7 @@ > import org.eclipse.jdt.internal.compiler.CompilationResult; > import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; > import org.eclipse.jdt.internal.compiler.ast.*; >+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; > import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException; > import org.eclipse.jdt.internal.compiler.env.*; >@@ -396,36 +397,6 @@ > } > return this.basicParser; > } >-/** >- * Add the possibleMatch to the loop >- * -> build compilation unit declarations, their bindings and record their results. >- */ >-protected void parseAndBuildBindings(PossibleMatch possibleMatch, boolean mustResolve) { >- if (this.progressMonitor != null && this.progressMonitor.isCanceled()) >- throw new OperationCanceledException(); >- >- try { >- if (BasicSearchEngine.VERBOSE) >- System.out.println("Parsing " + possibleMatch.openable.toStringWithAncestors()); //$NON-NLS-1$ >- >- this.parser.nodeSet = possibleMatch.nodeSet; >- CompilationResult unitResult = new CompilationResult(possibleMatch, 1, 1, this.options.maxProblemsPerUnit); >- CompilationUnitDeclaration parsedUnit = this.parser.dietParse(possibleMatch, unitResult); >- if (parsedUnit != null) { >- if (mustResolve && !parsedUnit.isEmpty()) >- this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/); >- >- // add the possibleMatch with its parsedUnit to matchesToProcess >- possibleMatch.parsedUnit = parsedUnit; >- int size = this.matchesToProcess.length; >- if (this.numberOfMatches == size) >- System.arraycopy(this.matchesToProcess, 0, this.matchesToProcess = new PossibleMatch[size == 0 ? 1 : size * 2], 0, this.numberOfMatches); >- this.matchesToProcess[this.numberOfMatches++] = possibleMatch; >- } >- } finally { >- this.parser.nodeSet = null; >- } >-} > /* > * Caches the given binary type in the lookup environment and returns it. > * Returns the existing one if already cached. >@@ -711,7 +682,7 @@ > protected IType getFocusType() { > return this.scope instanceof HierarchyScope ? ((HierarchyScope) this.scope).focusType : null; > } >-protected void getMethodBodies(CompilationUnitDeclaration unit) { >+protected void getMethodBodies(CompilationUnitDeclaration unit, MatchingNodeSet nodeSet) { > if (unit.ignoreMethodBodies) { > unit.ignoreFurtherInvestigation = true; > return; // if initial diet parse did not work, no need to dig into method bodies. >@@ -730,7 +701,7 @@ > char[] contents = compilationResult.compilationUnit.getContents(); > this.parser.javadocParser.scanner.setSource(contents); > } >- this.parser.nodeSet = this.currentPossibleMatch.nodeSet; >+ this.parser.nodeSet = nodeSet; > this.parser.parseBodies(unit); > } finally { > this.parser.nodeSet = null; >@@ -876,22 +847,43 @@ > initialize(javaProject, length); > > // create and resolve binding (equivalent to beginCompilation() in Compiler) >- boolean mustResolve = ((InternalSearchPattern)this.pattern).mustResolve; >+ boolean mustResolvePattern = ((InternalSearchPattern)this.pattern).mustResolve; >+ boolean mustResolve = mustResolvePattern; >+ this.patternLocator.mayBeGeneric = this.options.sourceLevel >= ClassFileConstants.JDK1_5; > boolean bindingsWereCreated = mustResolve; > try { > for (int i = start, maxUnits = start + length; i < maxUnits; i++) { > PossibleMatch possibleMatch = possibleMatches[i]; > try { >- parseAndBuildBindings(possibleMatch, mustResolve); >- if (!mustResolve) { >+ if (!parseAndBuildBindings(possibleMatch, mustResolvePattern)) continue; >+ // Currently we only need to resolve over pattern flag if there's potential parameterized types >+ if (this.patternLocator.mayBeGeneric) { >+ // If pattern does not resolve then rely on possible match node set resolution >+ // which may have been modified while locator was adding possible matches to it >+ if (!mustResolvePattern) { >+ mustResolve = possibleMatch.nodeSet.mustResolve; >+ bindingsWereCreated = mustResolve; >+ } >+ } else { >+ // Reset matching node resolution with pattern one if there's no potential parameterized type >+ // to minimize side effect on previous search behavior >+ possibleMatch.nodeSet.mustResolve = mustResolvePattern; >+ } >+ // possible match node resolution has been merged with pattern one, so rely on it to know >+ // whether we need to process compilation unit now or later >+ if (!possibleMatch.nodeSet.mustResolve) { > if (this.progressMonitor != null) { > this.progressWorked++; > if ((this.progressWorked%this.progressStep)==0) this.progressMonitor.worked(this.progressStep); > } > process(possibleMatch, bindingsWereCreated); >+ if (this.numberOfMatches>0 && this.matchesToProcess[this.numberOfMatches-1] == possibleMatch) { >+ // forget last possible match as it was processed >+ this.numberOfMatches--; >+ } > } > } finally { >- if (!mustResolve) >+ if (!possibleMatch.nodeSet.mustResolve) > possibleMatch.cleanUp(); > } > } >@@ -1073,7 +1065,7 @@ > } > previousJavaProject = javaProject; > } >- matchSet.add(new PossibleMatch(this, resource, openable, searchDocument)); >+ matchSet.add(new PossibleMatch(this, resource, openable, searchDocument, ((InternalSearchPattern) this.pattern).mustResolve)); > } > > // last project >@@ -1112,7 +1104,7 @@ > IJavaElement focus = ((InternalSearchPattern) searchPattern).focus; > if (focus != null) { > SearchDocument document = participant.getDocument(focus.getPath().toString()); >- this.currentPossibleMatch = new PossibleMatch(this, focus.getResource(), null, document); >+ this.currentPossibleMatch = new PossibleMatch(this, focus.getResource(), null, document, ((InternalSearchPattern) searchPattern).mustResolve); > if (encloses(focus)) { > SearchMatch match = newDeclarationMatch(focus.getAncestor(IJavaElement.PACKAGE_FRAGMENT), null/*no binding*/, SearchMatch.A_ACCURATE, -1, -1); > report(match); >@@ -1153,7 +1145,7 @@ > if (resource == null) // case of a file in an external jar > resource = javaProject.getProject(); > SearchDocument document = participant.getDocument(resource.getFullPath().toString()); >- this.currentPossibleMatch = new PossibleMatch(this, resource, null, document); >+ this.currentPossibleMatch = new PossibleMatch(this, resource, null, document, ((InternalSearchPattern) searchPattern).mustResolve); > try { > if (encloses(pkg)) { > SearchMatch match = newDeclarationMatch(pkg, null/*no binding*/, SearchMatch.A_ACCURATE, -1, -1); >@@ -1352,6 +1344,47 @@ > return newTypeReferenceMatch(enclosingElement, enclosingBinding, accuracy, reference.sourceStart, reference.sourceEnd-reference.sourceStart+1, reference); > } > >+/** >+ * Add the possibleMatch to the loop >+ * -> build compilation unit declarations, their bindings and record their results. >+ */ >+protected boolean parseAndBuildBindings(PossibleMatch possibleMatch, boolean mustResolve) throws CoreException { >+ if (this.progressMonitor != null && this.progressMonitor.isCanceled()) >+ throw new OperationCanceledException(); >+ >+ try { >+ if (BasicSearchEngine.VERBOSE) >+ System.out.println("Parsing " + possibleMatch.openable.toStringWithAncestors()); //$NON-NLS-1$ >+ >+ this.parser.nodeSet = possibleMatch.nodeSet; >+ CompilationResult unitResult = new CompilationResult(possibleMatch, 1, 1, this.options.maxProblemsPerUnit); >+ CompilationUnitDeclaration parsedUnit = this.parser.dietParse(possibleMatch, unitResult); >+ if (parsedUnit != null) { >+ if (!parsedUnit.isEmpty()) { >+ if (mustResolve) { >+ this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/); >+ } >+ if (hasAlreadyDefinedType(parsedUnit)) return false; // skip type has it is hidden so not visible >+ getMethodBodies(parsedUnit, possibleMatch.nodeSet); >+ if (this.patternLocator.mayBeGeneric && !mustResolve && possibleMatch.nodeSet.mustResolve) { >+ // special case: possible match node set force resolution although pattern does not >+ // => we need to build types for this compilation unit >+ this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/); >+ } >+ } >+ >+ // add the possibleMatch with its parsedUnit to matchesToProcess >+ possibleMatch.parsedUnit = parsedUnit; >+ int size = this.matchesToProcess.length; >+ if (this.numberOfMatches == size) >+ System.arraycopy(this.matchesToProcess, 0, this.matchesToProcess = new PossibleMatch[size == 0 ? 1 : size * 2], 0, this.numberOfMatches); >+ this.matchesToProcess[this.numberOfMatches++] = possibleMatch; >+ } >+ } finally { >+ this.parser.nodeSet = null; >+ } >+ return true; >+} > /* > * Process a compilation unit already parsed and build. > */ >@@ -1370,9 +1403,10 @@ > } > if (hasAlreadyDefinedType(unit)) return; // skip type has it is hidden so not visible > >- getMethodBodies(unit); >+ // Move getMethodBodies to #parseAndBuildings(...) method to allow possible match resolution management >+ //getMethodBodies(unit); > >- boolean mustResolve = ((InternalSearchPattern)this.pattern).mustResolve; >+ boolean mustResolve = ((InternalSearchPattern)this.pattern).mustResolve || possibleMatch.nodeSet.mustResolve; > if (bindingsWereCreated && mustResolve) { > if (unit.types != null) { > if (BasicSearchEngine.VERBOSE) >@@ -1839,6 +1873,7 @@ > */ > protected void reportMatching(CompilationUnitDeclaration unit, boolean mustResolve) throws CoreException { > MatchingNodeSet nodeSet = this.currentPossibleMatch.nodeSet; >+ if (nodeSet.mustResolve) this.patternLocator.mustResolve = true; > if (mustResolve) { > this.unitScope= unit.scope.compilationUnitScope(); > // move the possible matching nodes that exactly match the search pattern to the matching nodes set >Index: search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java,v >retrieving revision 1.29 >diff -u -r1.29 MatchingNodeSet.java >--- search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java 23 Feb 2005 02:47:46 -0000 1.29 >+++ search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java 13 May 2005 16:32:42 -0000 >@@ -36,12 +36,23 @@ > static Integer ERASURE_MATCH = new Integer(SearchPattern.R_ERASURE_MATCH); > > /** >+ * Tell whether locators need to resolve or not for current matching node set. >+ */ >+public boolean mustResolve; >+ >+/** > * Set of possible matching ast nodes. They need to be resolved > * to determine if they really match the search pattern. > */ > SimpleSet possibleMatchingNodesSet = new SimpleSet(7); > private HashtableOfLong possibleMatchingNodesKeys = new HashtableOfLong(7); > >+ >+public MatchingNodeSet(boolean mustResolvePattern) { >+ super(); >+ mustResolve = mustResolvePattern; >+} >+ > public int addMatch(ASTNode node, int matchLevel) { > switch (matchLevel) { > case PatternLocator.INACCURATE_MATCH: >Index: search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java,v >retrieving revision 1.51 >diff -u -r1.51 MethodLocator.java >--- search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java 9 May 2005 13:19:30 -0000 1.51 >+++ search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java 13 May 2005 16:32:43 -0000 >@@ -81,6 +81,8 @@ > //public int match(FieldDeclaration node, MatchingNodeSet nodeSet) - SKIP IT > public int match(MethodDeclaration node, MatchingNodeSet nodeSet) { > if (!this.pattern.findDeclarations) return IMPOSSIBLE_MATCH; >+ >+ boolean resolve = ((InternalSearchPattern)this.pattern).mustResolve; > > // Verify method name > if (!matchesName(this.pattern.selector, node.selector)) return IMPOSSIBLE_MATCH; >@@ -92,7 +94,14 @@ > int argsLength = args == null ? 0 : args.length; > if (length != argsLength) return IMPOSSIBLE_MATCH; > for (int i = 0; i < argsLength; i++) { >- if (!matchesTypeReference(this.pattern.parameterSimpleNames[i], ((Argument) args[i]).type)) return IMPOSSIBLE_MATCH; >+ if (!matchesTypeReference(this.pattern.parameterSimpleNames[i], ((Argument) args[i]).type)) { >+ if (!mustResolve) { >+ // Set resolution flag on node set in case of types was inferred in parameterized types from generic ones... >+ // (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=79990) >+ nodeSet.mustResolve = true; >+ resolve = true; >+ } >+ } > } > } > >@@ -102,7 +111,7 @@ > } > > // Method declaration may match pattern >- return nodeSet.addMatch(node, ((InternalSearchPattern)this.pattern).mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH); >+ return nodeSet.addMatch(node, resolve ? POSSIBLE_MATCH : ACCURATE_MATCH); > } > public int match(MemberValuePair node, MatchingNodeSet nodeSet) { > if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH; >@@ -114,6 +123,8 @@ > public int match(MessageSend node, MatchingNodeSet nodeSet) { > if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH; > >+ boolean resolve = ((InternalSearchPattern)this.pattern).mustResolve; >+ > if (!matchesName(this.pattern.selector, node.selector)) return IMPOSSIBLE_MATCH; > if (this.pattern.parameterSimpleNames != null && (this.pattern.shouldCountParameter() || ((node.bits & ASTNode.InsideJavadoc) != 0))) { > int length = this.pattern.parameterSimpleNames.length; >@@ -122,7 +133,7 @@ > if (length != argsLength) return IMPOSSIBLE_MATCH; > } > >- return nodeSet.addMatch(node, ((InternalSearchPattern)this.pattern).mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH); >+ return nodeSet.addMatch(node, resolve ? POSSIBLE_MATCH : ACCURATE_MATCH); > } > //public int match(Reference node, MatchingNodeSet nodeSet) - SKIP IT > public int match(Annotation node, MatchingNodeSet nodeSet) { >@@ -215,6 +226,54 @@ > return level; > } > /** >+ * Return if pattern method may override a method in super classes >+ * or or implement one in super interfaces of given type. >+ * @param type >+ * @return level >+ */ >+int matchOverriddenMethod(ReferenceBinding type) { >+ if (type == null) return INACCURATE_MATCH; >+ int level = IMPOSSIBLE_MATCH; >+ >+ // matches superclass >+ if (!type.isInterface() && !CharOperation.equals(type.compoundName, TypeConstants.JAVA_LANG_OBJECT)) { >+ if (type.superclass().isParameterizedType()) { >+ TypeBinding erasure = ((ParameterizedTypeBinding)type.superclass()).erasure(); >+ if (erasure instanceof ReferenceBinding) { >+ MethodBinding[] methods = ((ReferenceBinding)erasure).getMethods(this.pattern.selector); >+ int length = methods.length; >+ for (int i = 0; i<length && level == IMPOSSIBLE_MATCH; i++) { >+ level = matchMethod(methods[i]); >+ } >+ if (level != IMPOSSIBLE_MATCH) return level; >+ } >+ } >+ level = matchOverriddenMethod(type.superclass()); >+ if (level != IMPOSSIBLE_MATCH) return level; >+ } >+ >+ // matches interfaces >+ ReferenceBinding[] interfaces = type.superInterfaces(); >+ if (interfaces == null) return INACCURATE_MATCH; >+ int iLength = interfaces.length; >+ for (int i = 0; i<iLength; i++) { >+ if (interfaces[i].isParameterizedType()) { >+ TypeBinding erasure = ((ParameterizedTypeBinding)interfaces[i]).erasure(); >+ if (erasure instanceof ReferenceBinding) { >+ MethodBinding[] methods = ((ReferenceBinding)erasure).getMethods(this.pattern.selector); >+ int mLength = methods.length; >+ for (int j = 0; j<mLength && level == IMPOSSIBLE_MATCH; j++) { >+ level = matchMethod(methods[j]); >+ } >+ if (level != IMPOSSIBLE_MATCH) return level; >+ } >+ } >+ level = matchOverriddenMethod(interfaces[i]); >+ if (level != IMPOSSIBLE_MATCH) return level; >+ } >+ return IMPOSSIBLE_MATCH; >+} >+/** > * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchReportReference(org.eclipse.jdt.internal.compiler.ast.ASTNode, org.eclipse.jdt.core.IJavaElement, Binding, int, org.eclipse.jdt.internal.core.search.matching.MatchLocator) > */ > protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { >@@ -415,8 +474,12 @@ > int methodLevel = matchMethod(method); > if (methodLevel == IMPOSSIBLE_MATCH) { > if (method != method.original()) methodLevel = matchMethod(method.original()); >- if (methodLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH; >- method = method.original(); >+ if (methodLevel == IMPOSSIBLE_MATCH && this.pattern.findDeclarations && this.mayBeGeneric) { >+ methodLevel = matchOverriddenMethod(method.declaringClass); >+ if (methodLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH; >+ } else { >+ method = method.original(); >+ } > } > > // declaring type >Index: search/org/eclipse/jdt/internal/core/search/matching/MethodPattern.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodPattern.java,v >retrieving revision 1.51 >diff -u -r1.51 MethodPattern.java >--- search/org/eclipse/jdt/internal/core/search/matching/MethodPattern.java 2 May 2005 13:33:11 -0000 1.51 >+++ search/org/eclipse/jdt/internal/core/search/matching/MethodPattern.java 13 May 2005 16:32:43 -0000 >@@ -287,9 +287,13 @@ > if (returnSimpleName != null || returnQualification != null) return true; > > // parameter types >- if (parameterSimpleNames != null) >- for (int i = 0, max = parameterSimpleNames.length; i < max; i++) >- if (parameterQualifications[i] != null) return true; >+ if (parameterSimpleNames != null) { >+ for (int i = 0, max = parameterSimpleNames.length; i < max; i++) { >+ if (parameterQualifications[i] != null) { >+ return true; >+ } >+ } >+ } > return false; > } > EntryResult[] queryIn(Index index) throws IOException { >Index: search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java,v >retrieving revision 1.46 >diff -u -r1.46 PatternLocator.java >--- search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java 25 Apr 2005 16:23:02 -0000 1.46 >+++ search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java 13 May 2005 16:32:44 -0000 >@@ -26,6 +26,7 @@ > protected boolean isEquivalentMatch; > protected boolean isErasureMatch; > protected boolean mustResolve; >+protected boolean mayBeGeneric; > > // match to report > SearchMatch match = null; >Index: search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java,v >retrieving revision 1.21 >diff -u -r1.21 PossibleMatch.java >--- search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java 15 Mar 2005 17:07:56 -0000 1.21 >+++ search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java 13 May 2005 16:32:44 -0000 >@@ -33,11 +33,11 @@ > private String sourceFileName; > private char[] source; > >-public PossibleMatch(MatchLocator locator, IResource resource, Openable openable, SearchDocument document) { >+public PossibleMatch(MatchLocator locator, IResource resource, Openable openable, SearchDocument document, boolean mustResolve) { > this.resource = resource; > this.openable = openable; > this.document = document; >- this.nodeSet = new MatchingNodeSet(); >+ this.nodeSet = new MatchingNodeSet(mustResolve); > char[] qualifiedName = getQualifiedName(); > if (qualifiedName != null) > this.compoundName = CharOperation.splitOn('.', qualifiedName);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 79990
:
21125
|
21157