Bug 198081 - [content assist] Problem with code completion and nested classes
Summary: [content assist] Problem with code completion and nested classes
Status: NEW
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows 2000
: P3 normal with 2 votes (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
Depends on:
Blocks:
 
Reported: 2007-07-27 06:04 EDT by Mauro Molinari CLA
Modified: 2022-07-08 10:35 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mauro Molinari CLA 2007-07-27 06:04:39 EDT
Suppose you have two packages, a and c.

Suppose you have class A in package a, with nested class B:

package a;

public class A
{
  public static class B
  {
  }
}

Suppose you have class C in package c:

package c;

import a.A.B;

public class C
{
  B b = new B();
}

OBSERVED BEHAVIOUR:
When you ask for code completion on B at the declaration of b, all works fine (and the import a.A.B is added).
When you ask for code completion on the constructor of B, it does not work. 
That is:
B b = new B <= invoke code completion here: it does not give B!

If you want code completion, you have first to ask for code completion on A, then B is given:

B b = new A <= invoke code completion here: it works!
...
B b = new A.B <= invoke code completion here: it works!

EXPECTED BEHAVIOUR:
I would expect that:
B b = new B <= invoke code completion here 
does work and give B as the first suggestion.
Comment 1 Mauro Molinari CLA 2007-12-20 10:46:05 EST
The problem is quite annoying when you want to create an anonymous class using a nested interface, without declaring a variable of that type.

Example:

package a;
public class A
{
  public static interface I
  {
    void i();
  }
}

package c;
import a.A.I;
public class C
{
  void add(I item)
  {
  }
}

package b;
import c.C;
public class B
{
  public B()
  {
    new C().add(new I<= invoke code completion here
  }
}

When you try to create an anonymous class that implements interface I to call C.add(I), you don't get any result, so:
- no suggestion for I's name
- no suggested template to create the anonymous class
- no way to automatically import I, even if you type I's name manually and try Organize Imports
You are forced to declare a variable of type I to enable code completion for I, otherwise you have to write A.I when typing the argument to pass to C.add(I).

This example is quite trivial and dumb, but real cases are much more annoying.

Mauro.
Comment 2 Andy Sheldon CLA 2012-09-16 14:25:53 EDT
In both examples provided, completion now appears to work correctly in 4.2. Did not test yet in 3.8.
Comment 3 Eclipse Genie CLA 2020-06-06 15:35:01 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 4 Mauro Molinari CLA 2020-06-08 03:35:46 EDT
(In reply to Andy Sheldon from comment #2)
> In both examples provided, completion now appears to work correctly in 4.2.
> Did not test yet in 3.8.

I just tried with Eclipse 2019-12 and neither of the provided examples work as expected. The nested class/interface is not proposed when invoking code assist at the constructor call location, if it has not yet been imported.
Comment 5 Julian Honnen CLA 2020-06-23 11:57:50 EDT
I had a cursory look at the issue and it seems like support for constructor declarations of inner types (including static classes) is missing in lots of components.

At various places inner types are excluded completely (-> ExtraFlags.IsMemberType).

Their index key also contains only limited information: no package name, no parameter types, no outer type, no modifiers.
If the filtering of inner types is commented out, we end in CompletionEngine::acceptConstructors which tries to reconstruct a fully qualified name and checks if the type is accessible.

Given the limited info from the index key, neither works correctly.

Furthermore the API doesn't seem to be designed to support this usecase, as it only provides package name and simple name:

char[] fullyQualifiedName = CharOperation.concat(packageName, simpleTypeName, '.');
Comment 6 Eclipse Genie CLA 2022-07-08 10:35:31 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.