Bug 106000 - [plan] Need API to allow code assist/completion from outside JDT core.
Summary: [plan] Need API to allow code assist/completion from outside JDT core.
Status: RESOLVED WONTFIX
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 127898
  Show dependency tree
 
Reported: 2005-08-03 19:02 EDT by Theodora Yeung CLA
Modified: 2009-08-30 02:19 EDT (History)
8 users (show)

See Also:


Attachments
Implementation of new propose new API and extension point. (80.38 KB, patch)
2005-08-03 19:03 EDT, Theodora Yeung CLA
no flags Details | Diff
Modification to API per conversion about relevance documentation (4.16 KB, text/plain)
2005-08-31 22:31 EDT, Theodora Yeung CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Theodora Yeung CLA 2005-08-03 19:02:33 EDT
In the presence of APT, completion on annotation member values becomes 
possible and annotation processors can propose valid values to complete on 
that the java compiler cannot. 

The following is outline the approach to enable support of annotation member 
value completion.

1) Introduce a new extension 
point, "org.eclipse.jdt.core.completionParticipant", so APT could get notified 
for completion event.
2) Introduce the new interface, 
org.eclipse.jdt.core.completion.ICompletionParticipant, which will be 
implemented by all plugins that may like to participate in completion. 
 
Patch for the implementation will be included.
Comment 1 Theodora Yeung CLA 2005-08-03 19:03:59 EDT
Created attachment 25649 [details]
Implementation of new propose new API and extension point. 

The patch is generated over the lastest jdt.core code in the APT branch.
Comment 2 Dirk Baeumer CLA 2005-08-04 04:43:37 EDT
CCing Dani as a member of the text team since this might influence their ideas
to open up content assist on the editor side.
Comment 3 David Audel CLA 2005-08-23 05:51:10 EDT
A completion participant must be able to compute 'relevance' for his completion
proposals, otherwise these proposals will be always at the end of the list of
proposals.
But currently 'relevance' specification is insufficient: 'relevance' of a
proposal is a positive integer.
So 'relevance' specification should be improved.
Comment 4 Tom Hofmann CLA 2005-08-23 06:24:52 EDT
I would like to draw your attention to the fact that code assist participation
is also a hot topic on the UI side of JDT. We have to make sure that the effort
is not duplicated and that the extension point is at the correct level.

We are exploring how we can let plug-ins contribute to the content assist
process similar to what is currently possible for javadoc only (see the
org.eclipse.jdt.ui.javadocCompletionProcessor extension point).

In some scenarios, it may be enough to contribute proposals to the jdt-core code
assist process. This is true if only Java proposals need to be contributed, and
only within Java code (but not comments and string literals), and the same kind
of UI (icons, labels) is desired as is presented for jdt-core proposals.

As soon as you would like to provide your own icons, you will need to plug-in at
a higher level than jdt-core. Also, if you want to provide proposals in
locations where jdt currently does not (e.g. string literals within
annotations), you would also need to plug-in at the UI level.

Other scenarios exist where it is desireable to contribute proposals of an
entirely different kind than the Java proposals. An example are the 'hippie'
word completions that are based on the words in currently open editors. These
proposals have nothing to do with Java and such proposals can be added to any
kind of text editor.


Sorting & Filtering:

The same problem as David mentions in comment 3 arises: How to sort proposals
that come from an independent set of sources. Additionally, it may be desireable
to filter out some proposals based on whats offered by other extensions - e.g.
if there already is a Java keyword proposal for a keyword, it does not make
sense to offer a word completion for the same word.

I am exploring how this could be achieved.


User control:

Our goal is to give more control about the content assist process to the user.
Many users would like to define separate commands for Type completion, Template
completion, Word completion, Spelling correction etc. in order to get a shorter
list of proposals fitting their intention. We would like to give that power to
the users while maintaining a 'best match' content assist command which would
(as it does now) combine and sort all proposal types. The user could also opt to
exclude certain proposal types (e.g. templates) from the 'best match' assistant.
Comment 5 Theodora Yeung CLA 2005-08-23 15:41:51 EDT
On relevance-

Currently, the relevance of APT proposed completion proposal is in the single 
digit and I vaguely recall that bumping the relevance up to something like 50 
did not have the desirable effect. One question I have is what exactly is the 
range of relevance for completion proposal generated by the CompletionEngine? 
There are constants from RelevanceConstants but I am not sure if those are the 
final numbers. I agree that it would be nice to document what means by a very 
strong match vs a weak match. 

Perhaps after the problem of relevance is resolved, the sorting problem will 
become much clearer. One (simple or overly simplified) solution is to sort all 
of them by the relevance. 

On Filtering and Notifications-

Currently, completion participants get notified of completion proposal 
generated by the completion engine through the 
ICompletionParticipant.ICompletionFilter API. We could possibily leverage this 
API and notify all completion participants of what's been proposed by both the 
jdt.core as well as other participants. If "filtering" is not desired, we 
could include a similar API that only do notifications but not filtering. I 
think eliminating duplicated either in the jdt.core or jdt.ui layer may be 
complicated and troublesome as it is very difficult to define equality between 
proposals generated by difference plug-ins.

Completions outside Java Code partition -

It would be great for APT if APT have support on completion within String 
literals. I recall we have briefly touched base on the topic. 
Items to consider includes:
1) Allow more than one ContentAssist per partition. 
2) String partition may be too vague. Separating comments from String literals 
in java code is desirable. 

The goal for APT's first release is to have some completion support on 
annotation member values. Currently completion inside String literals is not a 
requirement. Including our own icons would be a nice-to-have but it is 
understood that it requires a lot of support from the UI layer that is not in 
place today. 
Comment 6 Tom Hofmann CLA 2005-08-24 04:06:40 EDT
(In reply to comment #5)
> It would be great for APT if APT have support on completion within String 
> literals. I recall we have briefly touched base on the topic. 
> Items to consider includes:
> 1) Allow more than one ContentAssist per partition. 

Our current approach would allow multiple CompletionProposalComputers per
partition. 

[ JFace terminology: there is one ContentAssistant per editor, having one
ContentAssistProcessor per partition type. The proposed addition would allow
multiple ProposalComputers per processor. ]

> 2) String partition may be too vague. Separating comments from String literals 
> in java code is desirable. 

This is already the case.

> The goal for APT's first release is to have some completion support on 
> annotation member values. Currently completion inside String literals is not a 
> requirement. Including our own icons would be a nice-to-have but it is 
> understood that it requires a lot of support from the UI layer that is not in 
> place today. 

Hm, I understand that these issues are currently not top-priority for APT.
However, when defining a new extension point, we should think further than just
the next release. If having icons and completions within String literals is ever
wanted, then there needs to be a story on the UI side, be it in addition to a
Core extension point or on its own.
Comment 7 David Audel CLA 2005-08-24 10:48:43 EDT
Currently a relevance is the sum of several constants of RelevanceConstants and
the maximum value is less than 100. Higher is the relevance, better is the proposal.

Rough description of constants usage:
R_DEFAULT is the default relevance value.
R_INTERESTING is not added if the proposal is less interesting than other
proposal of the same kind (used to decrease relevance of the a field inside his
initialization: int i = i|)
R_EXACT_NAME is added if the proposal is exactly the completion token.
R_CASE is added if the proposal case is the same as the completion token.
R_EXPECTED_TYPE is added if the type of proposal is compatible with an expected
type.
   SubX var;
   X var2 = va|
R_EXACT_EXPECTED_TYPE is added if the type of proposal is exactely an expected type.
   X var;
   X var2 = va|
R_INTERFACE is added if the proposal is an interface and the expected completion
is an interface (not very useful because now only interfaces are proposed in
this case).
   class X implements |
R_CLASS is added if the proposal is a class and the expected completion is a
class (not very useful because now only classes are proposed in this case).
   class X extends |)
R_ENUM is added if the proposal is an enum and the expected completion is an
enum (not very useful because now only enums are proposed in this case).
   AnEnum var;
   switch(var) {
      case |
R_ANNOTATION is added if the proposal is an annotation and the expected
completion is an annotation (not very useful because now only annotations are
proposed in this case).
   @AnAnnot|
R_EXCEPTION is added if the proposal is an exception and the expected completion
is an exception.
   try {}
   catch(Exc|
R_ENUM_CONSTANT (never used. i need to check if there is a bug)
R_ABSTRACT_METHOD is added when the proposal is an abstract method declaration.
R_NON_STATIC is added when the proposal is not static and the completion token
is a qualified name reference
R_UNQUALIFIED is added when the proposal does not require to be qualified and
the completion token is not a qualified name.
   aName|
R_QUALIFIED is added when the proposal require to be qualified and the
completion token is a qualified name.
   AQualified.name|
R_NON_STATIC_OVERIDE is added when the method declaration is not static (will be
probably removed).
R_NON_RESTRICTED is added when the proposal does not have an access restriction.
R_TRUE_OR_FALSE is added if the proposal is 'true' or 'false' and the completion
is a boolean expression and the completion token is empty
   if(|
R_NAME_FIRST_PREFIX, R_NAME_PREFIX, R_NAME_FIRST_SUFFIX, R_NAME_SUFFIX are added
when the proposal contains a defined prefix or sufix. 
Comment 8 Tom Hofmann CLA 2005-08-26 03:48:03 EDT
see bug 91496 for the ongoing work in jdt-text land.
Comment 9 Theodora Yeung CLA 2005-08-31 22:31:46 EDT
Created attachment 26746 [details]
Modification to API per conversion about relevance documentation
Comment 10 Theodora Yeung CLA 2005-08-31 22:59:48 EDT
I agree that the documentation on "relevance" needs much improvement.

I have modified the ICompletionEvent.accept() API so that the computation of 
number that indicates relevance is left to the jdt. The modified API accept an 
extra parameter, relevanceFlag, to allow completion participants indicate the 
strength of the proposal but not the actual relevance rating on the proposal. 
This parameter is computed by doing a bit-wise OR on a few predefined factors 
that measure proposal strength. (see API and java doc below.) The actual 
relevance rating is then computed based on this new parameter. 

Each of these relevance factors corresponds to one of the constants in 
RelevanceConstants. For example, ICompletionEvent.R_EXPECTED_TYPE will have a 
relevance rating of RelevanceConstants.R_EXPECTED_TYPE. This way, completion 
proposal generated by the completion participant will have relevance rating 
comparable to those generated by the CompletionEngine. 

The once exposed through this API is a subset of what the jdt.core uses. I 
tried to pick those that are easy to understand and include those that make 
huge impact on the actual relevance rating.

The modified API is as follow. Please comment.


/** 
	 * Indicates the text of the completion node is a prefix of the 
proposed text. 
	 * The match is case insensitive. 
	 */
	final int R_TEXT_MATCH = 0x0001;
	/** 
	 * Indicates the text of the completion node is a prefix of the 
proposed text.
	 * The match is case sensitive.
	 */ 
	final int R_CASE_MATCH  = 0x0002;	
	/**
	 * Indicates the type of the proposal is compatible with the expected 
type.
	 */
	final int R_EXPECTED_TYPE = 0x0004;	
	/**
	 * Indicates the type of the proposal is the exactly the expected type.
	 */
	final int R_EXACT_TYPE = 0x0008;
	/**
	 * Indicates the proposal does not have an access restriction.
	 */
	final int R_NON_RESTRICT = 0x0100;
	/**
	 * Indicates the proposal is non-static and the context requires non-
static completion.
	 */
	final int R_NON_STATIC = 0x0200;
	/**
	 * Indicates the proposal is an abstract method.
	 */
	final int R_ABSTRACT_METHOD = 0x0400;	
	/**
	 * Indicates the proposal included a prefix to the text of the 
completion node.
	 */
	final int R_NAME_PREFIX = 0x0800;
	/**
	 * Indicates the proposal included a suffix to the text of the 
completion node.
	 */
	final int R_NAME_SUFFIX = 0x1000;

/**
	 * Reporting a completion proposal. The type of the proposal
	 * should not be one of those ignored type. If so, the proposal
	 * will simply be dropped. 
	 * 
	 * The actual value for "relevance" of this proposal will be computed 
	 * based on the value of the parameter <code>relevanceFlag</code>.
	 * The parameter should be built by performing a bit-wise OR of the 
applicable
	 * constants defined above. Each of the constant has a 
predefined "relevance" value. 
	 *   
	 * The computed relevance value will override the existing "relevance" 
set in the proposal.
	 *  
	 * @param propsoal the proposed completion. 
	 * @param relevanceFlag the relevance of the proposal will be computed 
based this 
	 * flag.
	 * @see #ignore(int)
	 */
	void accept(CompletionProposal propsoal, int relevanceFlag);	

Comment 11 David Audel CLA 2005-09-08 11:06:49 EDT
Use a bit mask 'relevanceFlag' is a good idea. With this mask the completion
participant doesn't need to know how the relevance value is computed. If this
flag is an argument of the 'accept' method then the completion participant
cannot specify directly the relevance value of a proposal.
We could add an helper method to compute the relevance instead. With an helper
we could allow relevances computed by a participant:

exemple:
CompletionProposal cp = ...
ICompletionEvent ce = ...
// the proposal is just better than a proposal of the expected type
int relevance = ce.computeRelevance(R_EXACT_TYPE) + 1;
cp.setRelevance(relevance);
ce.accept(cp);

If we don't want to allow unspecified relevance criteria then 'accept' method is
the good one to have 'relevanceFlag'.

Currently i don't know what is the best of these two possibilities.
Comment 12 Mik Kersten CLA 2005-10-05 19:06:51 EDT
Regarding filtering and sorting: Mylar filters and sorts completions
independently of the ranking that's specific to tools that understand the
semantics of the elements.  The ranks are based on interaction history, in a
similar way and with an almost identical UI to how Open Type ranks accessed
types.  This is currently implemented by overriding the
JavaCompletionProcessor.filterAndSortProposals(..), but it would be nice if it
could be done via API or extension point, and work for XML and JSP as well as it
does for Java (as requested by Mylar users working with WTP).

Perhaps the best way of doing this is to have a "hits" section into the proposal
list, again analogous to how Open Type shows hits (btw, Mylar populates Open
Type's hits as well).  The goal of the hits section is to provide proposals that
a tool has high confidence will be selected with the arrow keys or mouse.  By
default JDT would probably offer no hits, unless you decided to do MRU hits, but
that would probalby turn into an overpopulated mess very quickly and be limited
because users are constantly switching tasks.  Fyi, Mylar tends average between
2 and 5 items in this section, and the hit ratio is very high.  
Comment 13 Dani Megert CLA 2005-10-10 11:09:33 EDT
>default JDT would probably offer no hits, unless you decided to do MRU hits
We are in fact working on LRU for code assist.
Comment 14 Mik Kersten CLA 2005-10-11 11:19:58 EDT
How do you plan on presenting it, the same way as Mylar does with the dashed
separator?

If this is implemented, it is essential for Mylar to have a means of controlling
the list of "hits".  Mylar users expect the list to be populated with things
from their task context, whereas an LRU list will be totally unaware of when
they switch tasks and as such get in the way.  When JDT added the 'Mylar-lite'
functionality was added to Open Type it turned out to be confusing for Mylar
users for this reason.  I have shoehorned Mylar's interest model into Open Type
so now it works very well, but would really appreciate if the content assist hit
matcher were easier to extend.  

So could you make your generic matcher overridable?  Ideally by mapping it to a
content type in a plug.xml extension, or alternatively by allowing a source
configuration to override it.
Comment 15 Dani Megert CLA 2005-10-12 04:57:09 EDT
In the first iteration we will not change the UI i.e. the relevance for the LRU
hits will simply be bumped up.
Comment 16 Mik Kersten CLA 2005-10-12 11:12:00 EDT
In that case I assume that when the user starts typing the list reverts to the
predictable sorted order.

From a user's point of view this could theoretically be problematic if they got
confused about why some things were at the top of the list and found the
behavior unpredictable.  But to me it seems fine because the top of the list can
feel magical anyway, and you guys have tuned it well.  

Maintaining the current UI also has the benefit of alowing the separted Mylar
hits to continue to feel like a meta-match over the existing sorted list, which
is good for us.  
Comment 17 David Audel CLA 2006-02-08 10:35:58 EST
As we don't intend to release org.eclipse.jdt.core.completionParticipant or another extension point for participating to completion in JDT/Core for 3.2, i close this bug as LATER.

To participate to the completion process the JDT/Text extension point (org.eclipse.jdt.ui.javaCompletionProposalComputer) must be use.

See bug 91496
See bug 119603
See bug 110913

Close as LATER.
Comment 18 Francis Lui CLA 2006-02-08 17:33:56 EST
However, if you don't release org.eclipse.jdt.core.completionParticipant, there will be no way for third parties to hide "public internal" methods from end-developers.
 
Is there anything we can do to get completionParticipant added, e.g. having Business Objects developers helping with the work?
 
Thanks!
 
Francis
(Development Lead for Crystal Reports for Eclipse)
Comment 19 Dani Megert CLA 2006-02-09 02:45:34 EST
>will be no way for third parties to hide "public internal" methods
Why would you put them into the API package?
- if it's for development purpose put the code into an *.internal.* package with access restrictions
- for testing? If so, simple make those methods package visible and create the same package in the test project to access the types and methods
Comment 20 David Audel CLA 2006-02-09 06:32:22 EST
As said by Daniel, package and classes with access restrictions can be filtered by codeassist (see preferences: Java>Editor>Content Assist>Sorting and Filtering).
What do you exactly need to filter ?
Comment 21 Francis Lui CLA 2006-02-09 13:52:32 EST
In any old API that has shipped for 4 versions, there are methods you wish you hadn't exposed, but are now exposed, and which you need to keep to maintain backward compatibility with existing applications.  Code migration costs can be very steep for large companies, and can block upgrades of your products.

Correct me if I'm wrong, but filtering based on access restrictions only allows you to filter on a per-package or per-class basis; you cannot hide individual methods in a class and expose other methods in the same class.

.NET 1.0+ and Visual Studio .NET 2002+ have the [EditorBrowsable(EditorBrowsableState.Never)] attribute (analogous to JDK 1.5 annotations) with which you can tag individual methods to hide such public internal methods and properties.

Java and Eclipse need a similar mechanism.  The @deprecated javadoc tag is a good first step, but the method still appears in Eclipse Code Assist.  If Eclipse had a feature to simply hide all @deprecated methods and classes from Code Assist (not just crossing them out), that would solve the problem for us.
Comment 22 Dani Megert CLA 2006-02-09 14:03:56 EST
Then we'd better add a filter for deprecated members. We already allow to filter members with discouraged and forbidden access. Another solution would be to specify whether deprecated members are discouraged or even forbidden.
Comment 23 Francis Lui CLA 2006-02-09 14:06:48 EST
Awesome!  Are you going to open a new bugzilla record, or should I?

Thanks!

Francis
Comment 24 Francis Lui CLA 2006-02-09 14:15:13 EST
We would much prefer having a filter for deprecated members.  Customers may still want to compile code that uses them; we want to strongly discourage them from writing new code using deprecated members, but still allow them to write and compile code using them if they must.

Specifying that deprecated members are discouraged or forbidden means users have to go through another step to hide them from Code Assist by hiding discouraged or forbidden methods.
Comment 25 Dani Megert CLA 2006-02-10 02:10:24 EST
David, what do you think?
Comment 26 David Audel CLA 2006-02-10 05:10:19 EST
I think filter deprecated members would be better than consider deprecated as forbidden because method be flag as forbidden.

We can add the same kind of behavior as we do for visibility filtering.
In this case we also need to add an option to control this behavior and choose the right default value.

Francis - could you open a new bugzilla record against JDT/Core ?
Comment 27 Francis Lui CLA 2006-02-10 13:36:58 EST
Thanks, Daniel and David, for the "transnational teamwork" across the Atlantic.  :)  I have created bug 127296.
Comment 28 Denis Roy CLA 2009-08-30 02:19:13 EDT
As of now 'LATER' and 'REMIND' resolutions are no longer supported.
Please reopen this bug if it is still valid for you.