| Summary: | [assist] improve content assist for static members when import missing | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Stefan Xenos <sxenos> | ||||
| Component: | Core | Assignee: | David Audel <david_audel> | ||||
| Status: | VERIFIED FIXED | QA Contact: | |||||
| Severity: | enhancement | ||||||
| Priority: | P3 | CC: | akiezun, claus.turkalj, dan.j.allen, daniel_megert, dcorbin, jerome_lanneluc, markus.kell.r, martinae, mlists, mnemo, philippe_mulet | ||||
| Version: | 3.0 | ||||||
| Target Milestone: | 3.4 M3 | ||||||
| Hardware: | PC | ||||||
| OS: | Windows XP | ||||||
| Whiteboard: | |||||||
| Attachments: |
|
||||||
|
Description
Stefan Xenos
You could have used content assist already after typing W in which case content assist would import the type. If you terminate the content assist for W with a . then it would immediately open the content assist for the methods. After organize import in your example you do not need to compile and you can directly invoke content assist. Okay, then I suppose I should reopen this as a feature request.
It's much easier to remember class names than method names, so its likely that
people will type in the class name themselves but will want to use content
assist for the method name... meaning that content assist will fail in exactly
the situation where it's most likely to be used.
Although your workaround is quite easy, end users are unlikely to discover it
for themselves since it's not immediately obvious that content assist will add
the import after typing "Workben" but not after typing "Workbench.".
I would suggest one of the following:
- Make content assist auto-add the import (and prompt if there is an ambituity).
- Allow "organize imports" to run even if there are parse errors ("Workbench."
should be recognizable as a class name, even though the rest of the line
contains errors.)
Oh... regarding comment 1: "After organize import in your example...". Perhaps I was unclear, but the defect I was trying to report is that I CAN'T organize imports at this point. Sorry I probably didn't fully read your PR. Having a more tolerant organize import would be cool and the auto-completion might also be a good idea. However, what I would hate is getting dialogs each time a type is not unique. Try content assist for types: you save yourself lots of typing. Martin, any chance can make organize import more failure tolerant? I'm afraid 'organize imports' can't be more fault tolerant. There's a technical
reason (it uses the AST which can only be built on CU without syntax errors),
but also a usability reason: organize import removes unneeded imports: If we
would be more fault tolerant but then remove imports because we couldn't detect
a reference, you would have to add it later again, and even specify the exact
type (java.awt.List, java.util.List). So this would be very nasty .
Note that add import (CTRL + SHIFT + M) is more tolerant, but you would have to
select the type.
Philippe, couldn't code assist detect that situation ("Workbench.get"). and
tell me to add an import or the receiver ("Workbench") together with the
completion?
It could decide only to do that if there's only one ("Workbench") in the
project.
moving to jdt.core for comment to my suggestion in comment 5 You could simply offer a quickfix for the error which give you back. So when typing Workbench.get, user would be requested to fix Workbench first. Then he could retry codeassist at same location. The frustration probably comes from the fact the user did not notice the error message in the status bar... but quickfix could jump in. You can't do a quick fix at this place: Workbench.get|code assist 'get' has the error line, 'Workbench; is not marked until you finish the statement So, it requires quite some concentration to realize that 'Workbench' has no import statement; as said, it's not marked. Quick fix can only jump in when there was syntactically correct code, but there never was. Only code assist can help here by trying to save the situation. I have this scenario a lot myself and think it would make a very nice code assist feature. Please re-read my suggestion in comment #7. Instead of dumping the codeassist error into the status bar, you could activate some quickfix for it which would lead you to provide the missing import. So when codeassisting, it would tell me there is nothing, but there is a quickfix available which could improve things for next attempt (after quickfix you could even redo a free codeassist at cursor location). As I said, no AST, no error range. I see that you give me a IProblem in 'acceptError', but this problem is not reported on the CU. Should I really start creating own problem annotations, introduce a life cycle for them (when are they invalid?) and redesign my quick fixes to work without AST? And do you really want the user to require to do a 4 operations (CTRL + 1, choose, set cursor back, incoke code assist again) for that? We could do it in one? *** Bug 48242 has been marked as a duplicate of this bug. *** You should do it all in one. When we give you a problem as a side effect of no completion, you could compute a quickfix for it, and offer it to the user for free. Then, once quickfix got applied, you could re-trigger a codeassist at same location. There is no need to perform cursor move under the cover. The IProblem you are getting from completion is not different from the problems you get through reconciling. I am not sure I understand why this would be hard on your side. We discussed this topic during lunch and the behaviour with the most votes is the following: if I open code assist in a case where a type isn't imported (e.g. List list= ...; list.add<code assist>) I would like to see all add methods of all types List. Depending on the method I select from the code assist a coresponding import is generated. This doesn't require any additional user actions (e.g. selecting a quick fix, ...). Do you mind if it takes 2 minutes to compute the list ? It will likely need to search for all add methods in all indexes, then compute the information required to fill in argument names (source attachment etc...). So in theory this would be cool, but in practice, this isn't going to work. Also, if proposing 50 matches in the end, then it is completely useless to the user. Emphasizing the only problem (which needs to be fixed anyway) is the only way to go. Why wouldn't my suggestion work ? Philippe, I think you should give it a try. Quick fix also searches for all types with the name 'List' (using code assist!), and getting the methods from that should be doable as well. So it's probably the cost of two code assists, or maybe only one as you can share an AST. Mostly type names are unique and you only get a single type to resolve. Long method list should also not be a problem, the user already wrote the prefix. If you happen to find 10 types with the name 'List', you could still descide to skip it and not bring any proposals. What's better about this proposal is that it is non-interrupting. Bringing a quick fix an top of code assist, then invoke code assist again, might work, but it is a.) a new concept, b.) does the same computing as you would do. I'll think about it again, and I will defintly inptove the handling of the problem that is reported by code assist (thanks for the hint!) but I'm quite conviced that the 'code assist only' approach is the most elegant. 1. Type names are not unique. List has 3 instances in my workspace. 2. It is far more expensive than 2 codeassists as we currently find methods by navigating inside the hierarchy of the resolved List (when available); which is fairly efficient. CodeAssist for members do not use any search action. 3. It would be new code to put in place to infer in fault-tolerant mode, plus it would find numerous false matches which we cannot sort by relevance as none have enough handy information, unless we spend another 2 more minutes to find out and resolve everything. So don't expect the codeassist engine to follow this fuzzy path, where in my opinion, the user just forgot to add one import. In addition we did our best to figure the most relevant error accounting for no completion, it looks natural you should exploit it and use the quickfix support which is support to be exactly solving this issue. CodeAssist isn't forced to only do completions at cursor location, but could also jump in to solve problems preventing completion to occur. Also, in the future, you could imagine recovering from other situations in the same way. This story thus scales better. Last, whatever fuzzy mode we would enter, we would propose too many matches to be any useful, whereas solving the offending problem to start with is exactly what is going to help you here. If you re-read the original problem, the user was confused that organize imports did not help once he got in trouble. Any chance this can be addressed for 3.1? *** Bug 106034 has been marked as a duplicate of this bug. *** Somebody needs to figure out how to solve this. Having organize import handling "NonImportedClass." plus CTRL-SHIFT-O would be a huge time saver. I wonder if NetBeans has this feature yet.. *** Bug 147504 has been marked as a duplicate of this bug. *** *** This bug has been marked as a duplicate of 44984 *** Reopen as while verifying bug 44984, comment 0 test case still get no proposal. David confirms that bug 44984 fix does not handle static calls which still need some extra work... *** Bug 74599 has been marked as a duplicate of this bug. *** *** Bug 111261 has been marked as a duplicate of this bug. *** *** Bug 165444 has been marked as a duplicate of this bug. *** This would also improve the experience of bug 152123. In HEAD, I can e.g. add "java.util.Collections.*" to the favorite static imports, but when I type "Collections.empt|" and then Ctrl+Space, I get no proposals. If I just write "empt|", then Ctrl+Space shows proposals. *** Bug 114688 has been marked as a duplicate of this bug. *** Created attachment 79896 [details]
Proposed fix
With this patch when you complete a members of a not imported type, the matching members (types, static methods and static fields) are proposed for all types that match the simple name of the not imported type and the not imported type is completed.
Released for 3.4. Tests added CompletionWithMissingTypesTests#test0034() -> test0037() I think you meant released for 3.4M3 ... Verified for 3.4M3 using I20071029-0010 |