Community
Participate
Working Groups
I20060718-0800 Search does not find reference to private binary method from doubly-nested anonymous. - import org.eclipse.jdt.debug.ui as binary plug-in - open StepIntoSelectionActionDelegate - search for references to method doStepIn(..) => was: 1 match in StepIntoSelectionActionDelegate.run(IAction) => expected: second match in StepIntoSelectionActionDelegate.runToLineBeforeStepIn(..) .new IDebugEventSetListener() {...}.new Runnable() {...} BTW: Search > Occurrenced in File > Identifier finds the second reference (i.e. DOM AST bindings are OK).
Problem also occurs for fields: class Browser from SWT has 9 references to field "html", but search engine does not find the ones in org.eclipse.swt.browser.Browser.Browser(Composite, int).new OleListener() {...}.new Runnable() {...}
Could be related to bug 87165.
*** Bug 212065 has been marked as a duplicate of this bug. ***
*** Bug 323635 has been marked as a duplicate of this bug. ***
*** Bug 332071 has been marked as a duplicate of this bug. ***
Created attachment 216586 [details] Screenshot - 0 hits for binaries from b89848 I've put up a simple test that I thought it's going to fail with no results found. It's based on another test for bug 89848 [1]: public void testBug151389() throws CoreException { IType classFile = getClassFile("JavaSearchBugs", "lib", "b89848", "X.class").getType(); IMethod method = classFile.getMethod("bar", new String[0]); search(method, REFERENCES); assertSearchResults( "lib/b89848/X$1.class java.lang.String b89848.<anonymous>.toString() EXACT_MATCH" ); } As I said, I was expecting it to fail, since after I have imported the class folder for the original test [2] and searched for bar refs in X.class I got 0 hits, see screenshot. What am I missing? [1] org.eclipse.jdt.core.tests.model.JavaSearchBugsTests.testBug89848() [2] eclipse.jdt.core\org.eclipse.jdt.core.tests.model\workspace\JavaSearchBugs\lib\b89848
Created attachment 216587 [details] mylyn/context/zip
(In reply to comment #6) I didn't look at the setup used in the test case, but a contributing factor could be that the super type of the anonymous class is coming from a different JAR. Anyway, I guess it's easier to attack this bug by reproducing one of the examples in a runtime Eclipse and then checking where the reference gets dropped. Knowing the cause for the bug will make it easier to construct a test case.
Not sure if this is related, but what I noticed while debugging is that when asked JavaSearchScope[1] if it encloses a BinaryMethod[2] the answer is no/false. Checking if one path encloses another is done in JavaSearchScope.encloses(String, String, int). In this particular case enclosingPath is "/.org.eclipse.jdt.core.external.folders/.link4" and path "D:/workspace/eclipse/jdt/eclipse.jdt.core/org.eclipse.jdt.core.tests.model/workspace/JavaSearchBugs/lib/b89848/X.class". The check return false. [1] JavaSearchScope on [ /b89848/src D:\workspace\eclipse\jdt\eclipse.jdt.core\org.eclipse.jdt.core.tests.model\workspace\JavaSearchBugs\lib\b89848 ] [2] void foo() [in X [in X.class [in <default> [in D:\workspace\eclipse\jdt\eclipse.jdt.core\org.eclipse.jdt.core.tests.model\workspace\JavaSearchBugs\lib\b89848]]]]
I can't reproduce comment 0 in a fresh workspace. After importing only plug-in org.eclipse.jdt.debug.ui, StepIntoSelectionActionDelegate has too many compile errors (which can be seen in the ASTView), so search doesn't find anything at all. Comment 1 seems to work fine now (the field is now org.eclipse.swt.browser.IE.html). Bug 323635 (comment 4) is still easy to reproduce. If you set a breakpoint in BasicSearchEngine.findMatches(..) line: 223, then you see that a search for references to org.junit.runners.ParentRunner.describeChild(T) finds something in org.junit_v4.10.0\junit.jar|org/junit/runners/ParentRunner$4.class But a search for references to org.junit.runners.ParentRunner.fSorter doesn't find that anonymous class. A problem could be that fSorter is a *private* field, so the access to fSorter in the anonymous compare method is not a direct field access, but a call to the synthetic ParentRunner.access$100(ParentRunner). In this situation, the search engine also has search for references to the accessor method.
(In reply to comment #9) > Not sure if this is related, but what I noticed while debugging is that when > asked JavaSearchScope[1] if it encloses a BinaryMethod[2] the answer is > no/false. I think you are running into a separate issue. Probably the test case is different. - Problem should be in createHandle - While, the problem should be in createHandle, it would be interesting to understand why encloses returns false in your testcase.
(In reply to comment #10) > A problem could be that fSorter is a *private* field, so the access to fSorter > in the anonymous compare method is not a direct field access, but a call to the > synthetic ParentRunner.access$100(ParentRunner). In this situation, the search > engine also has search for references to the accessor method. Does creating an OrPattern for the currently used FieldPattern and a MethodPattern for the synthetic accessor make any sense? This could be an output of SearchPattern.createPattern(IJavaElement, int, int) when looking for a private binary field.
I don't think you can know upfront that a synthetic accessor may be part of the game and how it will be called. Compilers are quite free in how they generate synthetic methods. AFAIK, search for references to binary members doesn't work at all without source. So I don't think this problem should be solved through the index, but through special processing of private binary members if the declaring class contains anonymous or other nested classes.
The first difference I noticed while running a debug sessions for binaries vs sources search was in MatchLocator.reportMatching(...)[1]. For the search in sources created enclosing type represent an anonymous class[2], but for the binaries it's a top-level type[3]. However, when I tried to replace the enclosing type with an anonymous BinaryType, a moment later when visiting its methods[4] I couldn't create a ClassFileReader for it (the anonymous type is not in JavaModelManager's cache). On the other hand, if I continue with the original enclosing type[2] creating a binary method[4] fails, returns null thus the match is not reported. So the fix should be either in [1] and the ClassFileReader or in [4]. [1] MatchLocator.reportMatching(TypeDeclaration, IJavaElement, int, MatchingNodeSet, int): ... if (member.isBinary()) { enclosingElement = ((IClassFile)this.currentPossibleMatch.openable).getType(); } else { enclosingElement = member.getType(new String(type.name), occurrenceCount); } ... [2] class <anonymous #1> [in comparator() [in ParentRunner [in [Working copy] ParentRunner.java [in org.junit.runners [in junitsrc [in org.junit]]]]]] int compare(T, T) [3] class ParentRunner [in ParentRunner.class [in org.junit.runners [in D:\apps\e\bp\plugins\org.junit_4.10.0.v4_10_0_v20120426-0900\junit.jar]]] [4] JavaModelManager.getInfo(IJavaElement) line: 1941 MatchLocator.classFileReader(IType) line: 241 MatchLocator.createHandle(AbstractMethodDeclaration, IJavaElement) line: 465 MatchLocator.reportMatching(AbstractMethodDeclaration, TypeDeclaration, IJavaElement, int, boolean, MatchingNodeSet) line: 2282 MatchLocator.reportMatching(TypeDeclaration, IJavaElement, int, MatchingNodeSet, int) line: 2768 MemberDeclarationVisitor.visit(TypeDeclaration, BlockScope) line: 274 TypeDeclaration.traverse(ASTVisitor, BlockScope) line: 1341 QualifiedAllocationExpression.traverse(ASTVisitor, BlockScope) line: 552 ReturnStatement.traverse(ASTVisitor, BlockScope) line: 314 MethodDeclaration.traverse(ASTVisitor, ClassScope) line: 307 MatchLocator.reportMatching(AbstractMethodDeclaration, TypeDeclaration, IJavaElement, int, boolean, MatchingNodeSet) line: 2239 MatchLocator.reportMatching(TypeDeclaration, IJavaElement, int, MatchingNodeSet, int) line: 2768 MatchLocator.reportMatching(CompilationUnitDeclaration, boolean) line: 2495 MatchLocator.process(PossibleMatch, boolean) line: 1738 MatchLocator.locateMatches(JavaProject, PossibleMatch[], int, int) line: 1148 MatchLocator.locateMatches(JavaProject, PossibleMatchSet, int) line: 1189 MatchLocator.locateMatches(SearchDocument[]) line: 1321 JavaSearchParticipant.locateMatches(SearchDocument[], SearchPattern, IJavaSearchScope, SearchRequestor, IProgressMonitor) line: 95 BasicSearchEngine.findMatches(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor) line: 231 BasicSearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor) line: 515 SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor) line: 584 JavaSearchQuery.run(IProgressMonitor) line: 144 InternalSearchUI$InternalSearchJob.run(IProgressMonitor) line: 91 Worker.run() line: 54 [4] org.eclipse.jdt.internal.core.search.matching.MatchLocator.createBinaryMethodHandle(IType, char[], char[][])
The ClassFileReader seems to have all the data required. In innerInfos array, it holds 4 items and one of them (ParentRunner$4) is for the anonymous class in question. So we could either include methods for member types in the result for #getMethods() or if the sought method cannot be found among those we could iterate over IBinaryNestedTypes returned from #getMemberTypes(). Ideally, a ClassFileReader would be created for each member type. Does it make any sense?
(In reply to comment #14) Essentially MatchLocator.reportMatching(...) takes the compiler element, creates the model element and reports. Now, as you have found, the hierarchy of the model elements are different in binary and source w.r.t to anonymous classes. Just look in the package explorer for a jar with the source code and you would see that the anonymous functions are not in the hierarchy. One way to make the fix could be is to make the model elements take care of the anonymous methods too. However, I am afraid that it could impact many other parts of model, search and may be JDT/UI too. One motivation to go for this route could be that, there could be more usage of closures from now onwards and having this feature can be nice. I think you are trying to recommend this kind of approach when you mentioned the fix in ClassFileReader. Just to note that fixes in methods like ClassFileReader could impact other components, which you need to take care of. Next you would have noticed that createHandle() is essentially returning the method element in the type with the same given name. This type (field name parent) is being wrong in the case of binary anonymous methods. I think if we could help if you could try to fix this.
Created attachment 217930 [details] Quick fix (In reply to comment #16) > Next you would have noticed that You mean after fixing the model for binaries / fixing the ClassFileReader? > createHandle() is essentially returning the > method element in the type with the same given name. This type (field name > parent) is being wrong in the case of binary anonymous methods. I'm not sure if I'm following, could you please rephrase the last two sentences. In the meantime, I was able to create a quick fix which prints 3 refs in the Search view (see the upcoming screenshot). It does break JavaSearchBugsTests2.testBug342393() though [1], so I'm not sure if it's going in the right direction. [1] expected: b342393/Generic.java A b342393.Generic$A.ONE:<anonymous>#1.getSquare() [getSquare] EXACT_MATCH\n b342393/Generic.java A b342393.Generic$A.TWO:<anonymous>#1.getSquare() [getSquare] EXACT_MATCH\n b342393/Generic.java A b342393.Generic$A.getSquare() [getSquare] EXACT_MATCH actual: b342393/Generic.java b342393.Generic$A.ONE [getSquare] EXACT_MATCH\n b342393/Generic.java b342393.Generic$A.TWO [getSquare] EXACT_MATCH\n b342393/Generic.java A b342393.Generic$A.getSquare() [getSquare] EXACT_MATCH
Created attachment 217932 [details] Search for fSorter in org.junit sources
Created attachment 217933 [details] Search for fSorter in org.junit binaries
Created attachment 217934 [details] Search for fSorter in org.junit binaries with the quick fix
(In reply to comment #17) > Created attachment 217930 [details] > Quick fix Pushed to Gerrit as https://git.eclipse.org/r/#/c/6849/
Created attachment 218889 [details] Typos Typos extracted from from the Quick fix
(In reply to comment #22) > Created attachment 218889 [details] [diff] > Typos /** - * Common functionality for Binary member handles. + * Common functionality for Binary member handlers. */ public abstract class BinaryMember extends NamedMember { => This change is wrong. IJavaElements are really handles (value objects that refer to the actual data structure).
Created attachment 218928 [details] Typos (In reply to comment #23) > => This change is wrong. IJavaElements are really handles (value objects that > refer to the actual data structure). Oops, sorry about that. Removed the change from the patch.
(In reply to comment #22) > Created attachment 218889 [details] > Typos Pushed to Gerrit as https://git.eclipse.org/r/#/c/6934/1/.
I'll take this up for review now.
Manoj, please see how to take this forward. TIA.
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie.