Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 44627

Summary: [assist] improve content assist for static members when import missing
Product: [Eclipse Project] JDT Reporter: Stefan Xenos <sxenos>
Component: CoreAssignee: 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 Flags
Proposed fix none

Description Stefan Xenos CLA 2003-10-09 21:34:23 EDT
To reproduce:

1. Create a java file
2. Start typing the name of a static method in a class that hasn't been
referenced yet (like "Workbench.get"). Stop typing after the period.

At this point the user would like to use code completion to enter the method
name, but Ctrl-space doesn't do anything since the import doesn't exist yet.

3. Use Ctrl-Shift-O (organize imports) to add the import. An error dialog is shown:

Compilation unit has parse errors: 'Syntax error, insert ";" to complete
Statement'. No changes applied.

This can be frustrating to users. They need code completion in order to fix the
parse error and organize my imports, but they need to organize their imports
before they can use code completion. One of the two should be allowed to work in
this situation.
Comment 1 Dani Megert CLA 2003-10-10 02:09:30 EDT
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.
Comment 2 Stefan Xenos CLA 2003-10-10 16:12:53 EDT
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.)

Comment 3 Stefan Xenos CLA 2003-10-10 16:19:42 EDT
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.
Comment 4 Dani Megert CLA 2003-10-11 06:57:23 EDT
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?
Comment 5 Martin Aeschlimann CLA 2003-10-13 08:19:16 EDT
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.
Comment 6 Martin Aeschlimann CLA 2003-12-05 05:03:50 EST
moving to jdt.core for comment to my suggestion in comment 5
Comment 7 Philipe Mulet CLA 2003-12-05 05:49:00 EST
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.
Comment 8 Martin Aeschlimann CLA 2003-12-05 12:00:49 EST
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.
 
Comment 9 Philipe Mulet CLA 2003-12-05 12:23:18 EST
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).
Comment 10 Martin Aeschlimann CLA 2003-12-05 12:41:19 EST
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?



Comment 11 Martin Aeschlimann CLA 2003-12-08 04:28:13 EST
*** Bug 48242 has been marked as a duplicate of this bug. ***
Comment 12 Philipe Mulet CLA 2003-12-08 06:44:28 EST
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.
Comment 13 Dirk Baeumer CLA 2003-12-08 08:54:46 EST
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, ...).
Comment 14 Philipe Mulet CLA 2003-12-08 09:10:45 EST
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 ?
Comment 15 Martin Aeschlimann CLA 2003-12-08 10:07:11 EST
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.
Comment 16 Philipe Mulet CLA 2003-12-08 11:01:24 EST
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.
Comment 17 Stefan Xenos CLA 2004-09-11 23:56:39 EDT
Any chance this can be addressed for 3.1?
Comment 18 Dirk Baeumer CLA 2005-08-15 13:26:32 EDT
*** Bug 106034 has been marked as a duplicate of this bug. ***
Comment 19 Martin Olsson CLA 2005-08-16 13:06:34 EDT
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..
Comment 20 Martin Aeschlimann CLA 2006-06-16 14:55:03 EDT
*** Bug 147504 has been marked as a duplicate of this bug. ***
Comment 21 Dani Megert CLA 2006-06-18 10:49:44 EDT

*** This bug has been marked as a duplicate of 44984 ***
Comment 22 Frederic Fusier CLA 2006-10-30 11:31:56 EST
Reopen as while verifying bug 44984, comment 0 test case still get no proposal.
Comment 23 Frederic Fusier CLA 2006-10-30 11:33:15 EST
David confirms that bug 44984 fix does not handle static calls which still need
some extra work...
Comment 24 Frederic Fusier CLA 2006-10-30 11:34:55 EST
*** Bug 74599 has been marked as a duplicate of this bug. ***
Comment 25 Frederic Fusier CLA 2006-10-30 11:37:37 EST
*** Bug 111261 has been marked as a duplicate of this bug. ***
Comment 26 David Audel CLA 2007-02-06 07:00:14 EST
*** Bug 165444 has been marked as a duplicate of this bug. ***
Comment 27 Markus Keller CLA 2007-02-06 07:03:31 EST
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.
Comment 28 David Audel CLA 2007-06-22 04:09:57 EDT
*** Bug 114688 has been marked as a duplicate of this bug. ***
Comment 29 David Audel CLA 2007-10-08 09:11:28 EDT
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.
Comment 30 David Audel CLA 2007-10-08 09:15:12 EDT
Released for 3.4.

Tests added
  CompletionWithMissingTypesTests#test0034() -> test0037()
Comment 31 Jerome Lanneluc CLA 2007-10-09 11:36:55 EDT
I think you meant released for 3.4M3 ...
Comment 32 Jerome Lanneluc CLA 2007-10-29 06:07:17 EDT
Verified for 3.4M3 using I20071029-0010