Bug 461809 - [content assist] Completion proposals for Java 7 (diamond constructor) are broken with Mylyn in the loop
Summary: [content assist] Completion proposals for Java 7 (diamond constructor) are br...
Status: ASSIGNED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Text (show other bugs)
Version: 4.5   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: JDT-Text-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords: helpwanted, investigate
: 562275 (view as bug list)
Depends on:
Blocks: 506804
  Show dependency tree
 
Reported: 2015-03-10 09:30 EDT by Stephan Herrmann CLA
Modified: 2024-04-10 00:50 EDT (History)
8 users (show)

See Also:


Attachments
patch for reproduction (849 bytes, patch)
2020-04-16 05:53 EDT, Julian Honnen CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Stephan Herrmann CLA 2015-03-10 09:30:09 EDT
I was running TypeCompletionTest17 from org.eclipse.jdt.text.tests (JDT/Text) and accidentally had mylyn included.

This caused three tests to fail which expect diamond constructor completions, whereas the corresponding 1.6- variant with explicit type arguments was proposed.

I am not sure how exactly this spells out in real life, but it feels wrong if mylyn replaces Java proposals with proposals that are inferior to JDT's.

Specific failing tests are:

testGenericParameterGuessingSuper
  expected: new ArrayList<>()
  found:    new ArrayList<E>()

testGenericParameterGuessingExtends
  expected: new ArrayList<>()
  found:    new ArrayList<Number>()

testGenericParameterGuessingUnambiguos
  expected: new ArrayList<>()
  found:    new ArrayList<String>()

Seeing a FocusedJavaAllProposalComputer involved, I was surprised this proposal computer got activated, I thought all focused behavior needs explicit activation, which the tests from JDT/Text certainly don't do.

When running tests individually, they actually pass, failures occur only when running several tests together (e.g. all of TypeCompletionTest17). I observed that after the first test, org.eclipse.jdt.ui.javaAllProposalCategory had disappeared from ContentAssistProcessor#fCategoryIteration. Someone had set its fIsIncluded to false.
Comment 1 Sam Davis CLA 2015-03-10 14:16:39 EDT
Thanks for reporting this. I think the Mylyn proposal computer actually replaces the JDT one with something that delegates to JDT, so maybe we are somehow delegating to the old one. I'm putting this on the next milestone.
Comment 2 Chris Poon CLA 2015-05-27 16:24:50 EDT
After investigation, it seems like this is a bug in the framework/JDT. When the Mylyn computer is disabled, the Java computer runs first and works correctly. When the Mylyn computer is enabled, the template computer runs first and then the Mylyn computer (which calls the Java computer) runs and does not work correctly. The reason is that when the template computer runs first, it sets the core context (without setting an extended context) and this causes InternalCompletionProposal.canUseDiamond() to return false when the Java proposal is applied.

It seems like the order in which the computers run depends on bundle loading order and we can't control it, but we were able to manipulate the order in a debugging session to confirm that even when the Mylyn computer is disabled, if the template computer runs before the Java computer, the Java computer does not use the diamond operator. Similarly, the Mylyn computer works correctly if we force it to run first.

If you disable all default proposal computers other than the Task-Focused computer in Preferences > Java > Editor > Content Assist > Advanced, it works correctly.
Comment 3 Dani Megert CLA 2015-05-27 16:42:28 EDT
Before moving to JDT, please provide steps in plain SDK that show the bug.
Comment 4 Chris Poon CLA 2015-05-27 16:50:31 EDT
In any Java method, you can type "List<String> list = new A" then hit Ctrl+Space.  We would expect to see "List<String> list = new ArrayList<>()" after selecting the "ArrayList() - java.util.ArrayList" option in the Default content proposal.
Comment 5 Gunnar Wagenknecht CLA 2015-05-28 01:30:26 EDT
(In reply to Dani Megert from comment #3)
> Before moving to JDT, please provide steps in plain SDK that show the bug.

Dani, there doesn't seem to be a way in the UI to influence in which order the computers for the 'default' content assist are invoked. I can only select which ones.
Comment 6 Dani Megert CLA 2015-05-28 08:13:17 EDT
(In reply to Chris Poon from comment #4)
> In any Java method, you can type "List<String> list = new A" then hit
> Ctrl+Space.  We would expect to see "List<String> list = new ArrayList<>()"
> after selecting the "ArrayList() - java.util.ArrayList" option in the
> Default content proposal.

That's what happens for me using
http://download.eclipse.org/eclipse/downloads/drops4/S-4.5RC2a-201505222000/
Comment 7 Dani Megert CLA 2015-05-28 08:15:49 EDT
(In reply to Gunnar Wagenknecht from comment #5)
> (In reply to Dani Megert from comment #3)
> > Before moving to JDT, please provide steps in plain SDK that show the bug.
> 
> Dani, there doesn't seem to be a way in the UI to influence in which order
> the computers for the 'default' content assist are invoked. I can only
> select which ones.

Yes, that's expected since the order must not matter. In the end they will all be sorted according to the sorter selected by the user.
Comment 8 Gunnar Wagenknecht CLA 2015-05-28 08:39:37 EDT
(In reply to Dani Megert from comment #7)
> Yes, that's expected since the order must not matter.

Agreed, but it seems that Chris identified an issue where the order does matter.

> In the end they will
> all be sorted according to the sorter selected by the user.

Is there a JUnit test which we can extend/modify to demonstrate the issue?
Comment 9 Stephan Herrmann CLA 2015-05-28 09:51:11 EDT
(In reply to Gunnar Wagenknecht from comment #8)
> (In reply to Dani Megert from comment #7)
> > Yes, that's expected since the order must not matter.
> 
> Agreed, but it seems that Chris identified an issue where the order does
> matter.
> 
> > In the end they will
> > all be sorted according to the sorter selected by the user.
> 
> Is there a JUnit test which we can extend/modify to demonstrate the issue?

See the unit tests mentioned in comment 0. According to Chris' analysis it should suffice to use these tests and "somehow" manipulate the order of proposal computers to show the wrong outcome, right Chris?
Comment 10 Chris Poon CLA 2015-05-28 12:52:10 EDT
Right.  If you manipulate the order and put either the Task-Focused or the regular Java Proposals as the first proposal computers to be used (in particular the "providers" in ContentAssistProcessor.collectProposals()), the resulting proposal for "ArrayList() - java.util.ArrayList" will have the diamond operator.  If either the Template or SWT proposal computers come first then the proposal will not use the diamond operator.
Comment 11 Sam Davis CLA 2015-05-28 14:08:29 EDT
Note also that if you cycle through the proposal computers using ctrl+space to select the task focused computer, it works correctly.

Chris, maybe you could try to reproduce the problem using the build Dani mentioned?

> http://download.eclipse.org/eclipse/downloads/drops4/S-4.5RC2a-201505222000/

If someone who is set up to run the tests could check if they still fail when Mylyn is included in the run configuration, that would be great.
Comment 12 Chris Poon CLA 2015-05-28 19:46:35 EDT
Here are the steps I took to reproduce this problem:

1. Downloaded the Eclipse 4.5 build provided by Dani.
2. Start up Eclipse with a clean workspace.
3. Install Mylyn (Update Site: http://download.eclipse.org/mylyn/releases/latest)
- I installed everything except for the Subclipse connector.
4. Restart Eclipse
5. Create a project with a class.
6. In the new class, type in "List<String> los = new A" and use default proposal computer to select the "ArrayList - java.util.ArrayList" proposal.
- This should yield the result with the diamond operator.
7. Resolve any compile errors by importing java.util.List.  Then type "List<String> los2 = new A" and use the default proposal computer to select the same ArrayList proposal
- This will yield the result without the diamond operator.

I've been able to reproduce it using that method a few times.  On other workspaces I had when debugging through this, I had to create a new task and activate it in order for the default proposal to not use the diamond operator.

Note that if you cycle to the Task-Focused proposal and selecting the "ArrayList() - java.util.ArrayList" proposal, it will always use the diamond operator.
Comment 13 Chris Poon CLA 2015-05-29 13:30:12 EDT
Here are the steps I took to manipulate the order of the default proposal computers:

1. Download the Eclipse 4.5 build provided by Dani.
2. Create a new Plug-in project.
3. In the Manifest's Dependencies view, filter for "jdt" and add all of the projects to the dependency list.
4. Open up the Debug configuration, create a new Eclipse Application configuration and debug that configuration.
5. In the Eclipse debug application, create a new Java project and create a class in that project.
6. In that class, type "List<String> los = new ArrayList<>();" and import the List and ArrayList classes.
7. Go back your Eclipse development workspace and open ContentAssistProcessor.class.
8. Go to line 479, and place a breakpoint on that line.
9. Open the breakpoint properties and enable Conditional.
10. In the text area, put this in:
    !fCategoryIteration.get(iteration).add(fCategoryIteration.get(iteration).get(0)) ||
    fCategoryIteration.get(iteration).remove(0) == null

 - This should rearrange the order in which the proposal computers are being used for default proposals so that the Java proposal computer is no longer the first computer to be used.
11. Go back to the Eclipse debug application and in the class, type "List<String> los2 = new A" and use the default proposal to select the "ArrayList() - java.util.ArrayList" option
- The proposal does not use the diamond operator.

Note that Mylyn isn't installed in this instance.
Comment 14 Sam Davis CLA 2015-05-29 14:01:47 EDT
Dani, comment 13 provides steps to reproduce without Mylyn installed. This makes it clear that the Java proposal computer only works correctly if it runs before other proposal computers.

Chris, thanks for the clear and detailed steps!
Comment 15 Dani Megert CLA 2015-05-29 15:41:20 EDT
(In reply to Sam Davis from comment #14)
> Dani, comment 13 provides steps to reproduce without Mylyn installed. This
> makes it clear that the Java proposal computer only works correctly if it
> runs before other proposal computers.
> 
> Chris, thanks for the clear and detailed steps!

You can move it back to JDT Text but this will be low prio (P5).
Comment 16 Chris Poon CLA 2015-05-29 18:39:48 EDT
So it seems like the invocation context that is created first (in this case by the template proposal computer) is being used when the Java proposal is applied, instead of the Java proposal computer's invocation context.

The *core* context (InternalCompletionContext) is being cached in org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext.getCoreContext() but it's not clear whether this is part of the problem.
Comment 17 Sam Davis CLA 2015-06-01 16:54:55 EDT
Moving to JDT. This will affect almost all users of Java 7 because Mylyn is included in almost all of the standard packages.

I don't think there is any way to work around this in Mylyn. It would need to be fixed in JDT.
Comment 18 Dani Megert CLA 2015-06-02 04:11:31 EDT
I'll try to look at this during 4.6, but no guarantee.
Comment 19 Sam Davis CLA 2015-06-02 14:10:31 EDT
Thanks Dani.
Comment 20 Dani Megert CLA 2018-04-23 05:16:25 EDT
Is this still an issue?
Comment 21 Sam Davis CLA 2018-04-23 13:50:13 EDT
This is still an issue in Oxygen.2 (4.7.2). I doubt it will resolve by itself.
Comment 22 Dani Megert CLA 2018-04-25 11:37:51 EDT
I'm sorry, I don't have time for this. Anyone interested in a fix should debug it and provide a Gerrit change.
Comment 24 Stephan Herrmann CLA 2019-08-22 06:55:19 EDT
(In reply to Yanming Zhou from comment #23)
> https://stackoverflow.com/questions/54951977/eclipse-java-auto-complete-
> changes-exact-matches-to-substring-matches/57601483

The potential influence of Mylyn indeed suggests a relation to this bug.

OTOH the symptom looks more like bug 481752, bug 446210. Please chime in in the latter (still unresolved) bug, if you have more details.
Comment 25 Stephan Herrmann CLA 2019-09-26 15:48:54 EDT
(In reply to Dani Megert from comment #15)
> (In reply to Sam Davis from comment #14)
> > Dani, comment 13 provides steps to reproduce without Mylyn installed. This
> > makes it clear that the Java proposal computer only works correctly if it
> > runs before other proposal computers.
> > 
> > Chris, thanks for the clear and detailed steps!
> 
> You can move it back to JDT Text but this will be low prio (P5).

Dani, on revisiting related bug 506804, bug 550862 etc. I was about to request that "Java Proposals (Task-focused)" should be disabled, until I returned here, to see that we have indication that the root bug is in JDT indeed. I don't think we can request Mylyn to disable their proposals if the bug is ours.

Still your statement about low prio doesn't look very encouraging for people thinking of fixing this.
Comment 26 Dani Megert CLA 2019-09-27 05:50:35 EDT
(In reply to Stephan Herrmann from comment #25)
> Still your statement about low prio doesn't look very encouraging for people
> thinking of fixing this.
Having a pure JDT test case could change this.
Comment 27 Sam Davis CLA 2019-09-27 14:41:37 EDT
(In reply to comment #26)
> (In reply to Stephan Herrmann from comment #25)
> > Still your statement about low prio doesn't look very encouraging for people
> > thinking of fixing this.
> Having a pure JDT test case could change this.

Comment #2 describes exactly how this bug happens. I know it's not a test case but it should be enough to investigate.
Comment 28 Julian Honnen CLA 2020-04-16 05:53:39 EDT
Created attachment 282466 [details]
patch for reproduction

I've attached a current patch to replicate the conditional breakpoint from comment 13. With that patch and both Java Proposals and Template Proposals enabled, the issue is still reproducible.

As described in comment 2, the template computer runs first and initializes the JavaContentAssistInvocationContext.fCoreContext via computeKeywordsAndContext(). That core context is not extended.

For the java computer a new (extended) context is then created and stored in the CompletionProposalCollector. Subsequent calls to JavaContentAssistInvocationContext::getCoreContext will prefer the collector's context and correctly return an extended context.

But when the proposal is applied, a new FillArgumentNamesCompletionProposalCollector is instantiated (AbstractJavaCompletionProposal::createRequiredTypeCompletionProposal). In its constructor, it overwrites the invocation context's collector.

Further calls to JavaContentAssistInvocationContext::getCoreContext will then fall back to the core context computed by the template.
Comment 29 Stephan Herrmann CLA 2020-04-16 07:12:49 EDT
(In reply to Julian Honnen from comment #28)
> Created attachment 282466 [details]
> patch for reproduction
> 
> I've attached a current patch to replicate the conditional breakpoint from
> comment 13. With that patch and both Java Proposals and Template Proposals
> enabled, the issue is still reproducible.
> 
> As described in comment 2, the template computer runs first and initializes
> the JavaContentAssistInvocationContext.fCoreContext via
> computeKeywordsAndContext(). That core context is not extended.
> 
> For the java computer a new (extended) context is then created and stored in
> the CompletionProposalCollector. Subsequent calls to
> JavaContentAssistInvocationContext::getCoreContext will prefer the
> collector's context and correctly return an extended context.
> 
> But when the proposal is applied, a new
> FillArgumentNamesCompletionProposalCollector is instantiated
> (AbstractJavaCompletionProposal::createRequiredTypeCompletionProposal). In
> its constructor, it overwrites the invocation context's collector.
> 
> Further calls to JavaContentAssistInvocationContext::getCoreContext will
> then fall back to the core context computed by the template.

Great, so you seem to converge with comment 16.

Do you already have an idea, how to resolve the conflict?

Data flows seem to be quite tricky, so from a quick look I could not see what would be the preferred direction.

Naively I would think that FillArgumentNamesCompletionProposalCollector should be able to answer the same extended core context as before. Apparently, there's a gap in the data flow, but where exactly?

In particular in the constructor of FillArgumentNamesCompletionProposalCollector I see
  setRequireExtendedContext(true);

Is this statement not triggered, or is it insufficient?
Comment 30 Julian Honnen CLA 2020-04-16 08:25:46 EDT
(In reply to Stephan Herrmann from comment #29)
> In particular in the constructor of
> FillArgumentNamesCompletionProposalCollector I see
>   setRequireExtendedContext(true);
> 
> Is this statement not triggered, or is it insufficient?
That flag is not evaluated in this scenario, because the collector is only instantiated locally to create the proposal and then discarded.
No InternalCompletionContext will be created for that collector instance.


> Do you already have an idea, how to resolve the conflict?
My gut instinct is to remove the side-effect of overwriting the collector in the constructor. The constructor needs to populate fInvocationContext, but should not modify that context. CompletionProposalCollector::setInvocationContext is API, so that behavior probably can't be changed. Maybe we could override getInvocationContext (that's currently final though).

Alternatively we could try to use the existing FillArgumentNamesCompletionProposalCollector from invocationContext instead of creating a new one in AbstractJavaCompletionProposal::createRequiredTypeCompletionProposal.
Comment 31 Dani Megert CLA 2020-04-18 10:57:39 EDT
Mylyn isn't that active anymore. So, not sure we should spend too much time on this.
Comment 32 Stephan Herrmann CLA 2020-04-18 14:38:49 EDT
(In reply to Dani Megert from comment #31)
> Mylyn isn't that active anymore. So, not sure we should spend too much time
> on this.

Are there concrete plans to remove Mylyn from eclipse packages? Until that happens, active or not doesn't seem to make much difference regarding the broken state, does it?

From my understanding, the problem could - in theory - also affect other combinations of JDT with other proposal providers, no?

I myself have been suffering from broken completion in many situations. It's really annoying and very bad publicity for JDT.
Comment 33 Dani Megert CLA 2020-04-19 03:12:21 EDT
(In reply to Stephan Herrmann from comment #32)
> Are there concrete plans to remove Mylyn from eclipse packages?
I  presume there are people using it in one way or the other.

> From my understanding, the problem could - in theory - also affect other
> combinations of JDT with other proposal providers, no?
That's why it would be great to have a non-Mylyn test case.
Comment 34 Stephan Herrmann CLA 2020-04-19 05:25:53 EDT
(In reply to Dani Megert from comment #33)
> (In reply to Stephan Herrmann from comment #32)
> > Are there concrete plans to remove Mylyn from eclipse packages?
> I  presume there are people using it in one way or the other.

So it will remain highly relevant.
 
> > From my understanding, the problem could - in theory - also affect other
> > combinations of JDT with other proposal providers, no?
> That's why it would be great to have a non-Mylyn test case.

Starting from comment 13 Mylyn is not part of the investigation. JDT is broken if proposal categories are ordered in an unfortunate way. Mylyn is only the proof that such broken order can occur in real life.

So far, we have no proof that bug 506804 indeed has the same root cause, but if a fix in this bug also resolves the other bug (and its duplicates), then we will have fixed the most horrible annoyance in JDT that I have experienced in several years.

Any one arguing against fixing this will be suspected to work for a competitor tool ;p

Please Julian, carry on! :)
Comment 35 Dani Megert CLA 2020-04-19 07:00:14 EDT
(In reply to Stephan Herrmann from comment #34)
> the most horrible annoyance in JDT that I have experienced in several years.
But looks others did not - no duplicate in 5 years. And we had way worse issues like deadlocks or crashes, so, not the most horrible thing in JDT ;-).

> Please Julian, carry on! :)
Sure, any help is welcome!
Comment 36 Stephan Herrmann CLA 2020-04-19 07:39:56 EDT
(In reply to Dani Megert from comment #35)
> (In reply to Stephan Herrmann from comment #34)
> > the most horrible annoyance in JDT that I have experienced in several years.
> But looks others did not - no duplicate in 5 years.

Potential duplicates are hidden behind bug 506804
Comment 37 Stephan Herrmann CLA 2020-04-21 12:22:09 EDT
*** Bug 562275 has been marked as a duplicate of this bug. ***
Comment 38 Dani Megert CLA 2020-04-27 10:11:14 EDT
Mylyn got removed from EPPs (https://git.eclipse.org/r/#/c/161423/).

Whoever wants to work on this bug please assign it to yourself and set a new target milestone.
Comment 39 Eclipse Genie CLA 2022-04-20 04:54:32 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.
Comment 40 Eclipse Genie CLA 2024-04-10 00:50:38 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.