Community
Participate
Working Groups
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.
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.
CCing Dani as a member of the text team since this might influence their ideas to open up content assist on the editor side.
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.
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.
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.
(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.
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.
see bug 91496 for the ongoing work in jdt-text land.
Created attachment 26746 [details] Modification to API per conversion about relevance documentation
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);
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.
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.
>default JDT would probably offer no hits, unless you decided to do MRU hits We are in fact working on LRU for code assist.
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.
In the first iteration we will not change the UI i.e. the relevance for the LRU hits will simply be bumped up.
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.
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.
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)
>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
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 ?
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.
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.
Awesome! Are you going to open a new bugzilla record, or should I? Thanks! Francis
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.
David, what do you think?
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 ?
Thanks, Daniel and David, for the "transnational teamwork" across the Atlantic. :) I have created bug 127296.
As of now 'LATER' and 'REMIND' resolutions are no longer supported. Please reopen this bug if it is still valid for you.