Bug 151389 - [search] does not find reference to private binary member from anonymous
Summary: [search] does not find reference to private binary member from anonymous
Status: CLOSED WONTFIX
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Tomasz Zarna CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
: 212065 323635 332071 (view as bug list)
Depends on:
Blocks:
 
Reported: 2006-07-21 06:34 EDT by Markus Keller CLA
Modified: 2018-10-10 18:38 EDT (History)
8 users (show)

See Also:
srikanth_sankaran: review? (manoj.palat)


Attachments
Screenshot - 0 hits for binaries from b89848 (26.60 KB, image/png)
2012-05-31 11:49 EDT, Tomasz Zarna CLA
no flags Details
mylyn/context/zip (48.55 KB, application/octet-stream)
2012-05-31 11:49 EDT, Tomasz Zarna CLA
no flags Details
Quick fix (1.04 KB, patch)
2012-06-27 09:19 EDT, Tomasz Zarna CLA
no flags Details | Diff
Search for fSorter in org.junit sources (6.34 KB, image/png)
2012-06-27 09:39 EDT, Tomasz Zarna CLA
no flags Details
Search for fSorter in org.junit binaries (4.59 KB, image/png)
2012-06-27 09:40 EDT, Tomasz Zarna CLA
no flags Details
Search for fSorter in org.junit binaries with the quick fix (5.23 KB, image/png)
2012-06-27 09:40 EDT, Tomasz Zarna CLA
no flags Details
Typos (5.25 KB, patch)
2012-07-18 14:06 EDT, Tomasz Zarna CLA
no flags Details | Diff
Typos (4.60 KB, patch)
2012-07-19 10:15 EDT, Tomasz Zarna CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Keller CLA 2006-07-21 06:34:04 EDT
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).
Comment 1 Markus Keller CLA 2006-12-08 13:35:26 EST
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() {...}
Comment 2 Markus Keller CLA 2007-03-14 12:36:03 EDT
Could be related to bug 87165.
Comment 3 Frederic Fusier CLA 2007-12-05 16:53:19 EST
*** Bug 212065 has been marked as a duplicate of this bug. ***
Comment 4 Markus Keller CLA 2010-08-30 10:39:40 EDT
*** Bug 323635 has been marked as a duplicate of this bug. ***
Comment 5 Satyam Kandula CLA 2010-12-08 04:15:53 EST
*** Bug 332071 has been marked as a duplicate of this bug. ***
Comment 6 Tomasz Zarna CLA 2012-05-31 11:49:42 EDT
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
Comment 7 Tomasz Zarna CLA 2012-05-31 11:49:47 EDT
Created attachment 216587 [details]
mylyn/context/zip
Comment 8 Markus Keller CLA 2012-05-31 12:06:07 EDT
(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.
Comment 9 Tomasz Zarna CLA 2012-06-01 12:24:37 EDT
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]]]]
Comment 10 Markus Keller CLA 2012-06-01 13:24:10 EDT
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.
Comment 11 Satyam Kandula CLA 2012-06-04 00:59:47 EDT
(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.
Comment 12 Tomasz Zarna CLA 2012-06-20 12:58:16 EDT
(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.
Comment 13 Markus Keller CLA 2012-06-21 05:38:12 EDT
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.
Comment 14 Tomasz Zarna CLA 2012-06-22 08:38:33 EDT
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[][])
Comment 15 Tomasz Zarna CLA 2012-06-22 09:25:58 EDT
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?
Comment 16 Satyam Kandula CLA 2012-06-27 02:02:33 EDT
(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.
Comment 17 Tomasz Zarna CLA 2012-06-27 09:19:35 EDT
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
Comment 18 Tomasz Zarna CLA 2012-06-27 09:39:46 EDT
Created attachment 217932 [details]
Search for fSorter in org.junit sources
Comment 19 Tomasz Zarna CLA 2012-06-27 09:40:03 EDT
Created attachment 217933 [details]
Search for fSorter in org.junit binaries
Comment 20 Tomasz Zarna CLA 2012-06-27 09:40:29 EDT
Created attachment 217934 [details]
Search for fSorter in org.junit binaries with the quick fix
Comment 21 Tomasz Zarna CLA 2012-07-18 14:04:46 EDT
(In reply to comment #17)
> Created attachment 217930 [details]
> Quick fix

Pushed to Gerrit as https://git.eclipse.org/r/#/c/6849/
Comment 22 Tomasz Zarna CLA 2012-07-18 14:06:02 EDT
Created attachment 218889 [details]
Typos

Typos extracted from from the Quick fix
Comment 23 Markus Keller CLA 2012-07-19 05:33:15 EDT
(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).
Comment 24 Tomasz Zarna CLA 2012-07-19 10:15:10 EDT
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.
Comment 25 Tomasz Zarna CLA 2012-07-24 08:35:01 EDT
(In reply to comment #22)
> Created attachment 218889 [details]
> Typos

Pushed to Gerrit as https://git.eclipse.org/r/#/c/6934/1/.
Comment 26 Srikanth Sankaran CLA 2012-08-15 07:03:44 EDT
I'll take this up for review now.
Comment 27 Srikanth Sankaran CLA 2014-10-21 02:56:20 EDT
Manoj, please see how to take this forward. TIA.
Comment 28 Eclipse Genie CLA 2018-10-10 18:38:16 EDT
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.