Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for looking up Classes and Methods on classpath #204

Closed
rubin55 opened this issue May 8, 2017 · 22 comments · Fixed by eclipse-jdtls/eclipse.jdt.ls#216
Closed

Comments

@rubin55
Copy link

rubin55 commented May 8, 2017

Currently vscode-java allows completion and introspection of Classes and Methods on-the-fly while editing your code. Afaik, currently the only way for someone to find the source of a class or method is to have the Class imported.

It would be amazingly helpful if you could find Classes, Interfaces (and their implementations) and methods that are available to you (i.e. configured on the classpath, either explicitly or via Maven dependencies).

Environment
  • Operating System: Windows 10
  • JDK version: Oracle JDK 8 Release 121
  • Visual Studio Code version: 1.12.1
  • Java extension version: 0.3.0
Steps To Reproduce

N/A, Feature request.

@fbricon
Copy link
Collaborator

fbricon commented May 8, 2017

You can already find classes and interfaces available in the classpath:
autocomplete.

Search for interface implementors is something we'll implement, eventually, see eclipse-jdtls/eclipse.jdt.ls#99.

Method autocompletion requires the type to be imported in the 1st place. If you have a specific workflow in mind, could you please describe it, or point us to similar workflows in other IDEs?

@rubin55
Copy link
Author

rubin55 commented May 8, 2017

I was thinking more like "pop up dialog by some key combination" type, get class or class.method by matching, press enter, open .java or .class file. To do that in the file you're working on atm directly is a little hackish (ie you introduce errors in the current file, you might not want to use said clase in the current file at all but are looking for general usage details/impl details for the class).

Eclipse does this and calls it:
Open a type quickly: [Shift + Ctrl + T]
Open any resource quickly: [Shift + Ctrl + R]

@fbricon
Copy link
Collaborator

fbricon commented May 8, 2017

So as I understand it, that'd be something similar to the Ctrl+T (or Cmd+T on Mac) to open workspace symbols (=types), only it would be extended to all available classes.

I'm not too fond of the idea of introducing additional windows/wizards if we could avoid it.

So ideally, we could perform a workspace wide search for all types with our own custom prefix in the command palette (say $ instead of #), to perform something equivalent to Ctrl+Shift+T in eclipse. I don't know if vscode allows extensions to contribute such action prefixes to the command palette. @jrieken @egamma what are our options here?

We could still perform the full classpath search when hitting #, but I'd feel like abusing the semantic of Go to symbol in workspace action.

@egamma
Copy link

egamma commented May 8, 2017

@fbricon

We could still perform the full classpath search when hitting # , but I'd feel like abusing the semantic of Go to symbol in workspace action.

In the context of Java I consider this as fair play to implement the LSP protocol workspace/symbol to mean all symbols available on the class path. When selecting a symbol that is located outside of the workspace then vscode-java can open a virtual document.

@fbricon
Copy link
Collaborator

fbricon commented May 8, 2017

@egamma ok so I gave it a try and unfortunately it just doesn't scale. Including JDK and other classpath dependencies to the workspace symbol search, for the spring-amqp project as an example, the search engine returns 67862 hits, that are transformed into SymbolInformations. So everything is super slow until the UI just freezes and we never even see one result on screen.

Obviously we need to limit the results, but then the problem is no new search is triggered if you continue typing in the search bar. workspace/symbol is invoked once and for all by VS Code. I think the server protocol should allow some sort of isIncomplete attribute in the response, similar to what's done for textDocument/completion. wdyt?

@egamma
Copy link

egamma commented May 9, 2017

@fbricon I did not expect that this works without some more tuning. I remember all the effort that was put into Eclipse to make this fast.

How many of the hits are types? The Intellisense widget can handle hits of this magnitude, we have tests with about 20k hits. One difference is that the Intellisense widget is using a newer tuned list widget, whereas quick pick is still using the tree. So this is another optimization area.

I've added @aeschli his memory is more fresh than mine on what was all done in Eclipse to make this fast.

@aeschli
Copy link
Collaborator

aeschli commented May 9, 2017

I thought the Java Language server already implement the workspace symbols request.
See WorkspaceSymbolHandler.

This should run very performant as it limits itself to types (no fields or methods) which is highly tuned in JDT.

To avoid the huge result set, the API should be used with a filter string.
Also in the LSP, the workspace/symbol request has a queryString argument.

If I remember right, in Eclipse, the open type dialog didn't start a query unless the user provided a filter string. I suggest that LS clients do the same.

@rubin55
Copy link
Author

rubin55 commented May 9, 2017

That sounds great, even if only classes/types and not methods, it would definitely be a major plus with a more experimental development flow (getting to know the framework/library you're using, reading the code representation of a class, etc).

@fbricon
Copy link
Collaborator

fbricon commented May 9, 2017

@egamma @aeschli when forcing a non empty query, things get better, but still feels too sluggish. When sending A for instance, the server return 4204 types in 5 seconds. From there, the result list is displayed very fast.
So the server side search is way too slow, compared to Eclipse's same type search. It seems the search itself is fairly fast, but we spend a huuuge amount of time converting the results into SymbolInformations. Anyways, that one's on us, not vscode :-)

@aeschli
Copy link
Collaborator

aeschli commented May 9, 2017

@fbricon Something must go wrong in WorkspaceSymbolHandler, causing to resolve the TypeNameMatch's underlying JavaElement.
My wild guess its that it is in DocumentSymbolHandler.mapKind(match.getType())) and the test type.isInterface().

Instead use

  int flags= match.getModifiers(); 
   if (Flags.isInterface(flags)) { 
    if ((typeKinds & SimilarElementsRequestor.INTERFACES) != 0) {
      ...

@fbricon
Copy link
Collaborator

fbricon commented May 9, 2017

Thanks for the pointer @aeschli. I'll try that as soon as I can

@fbricon fbricon added this to the Mid May 2017 milestone May 10, 2017
@fbricon fbricon self-assigned this May 10, 2017
@jrieken
Copy link

jrieken commented May 10, 2017

FYI and unsure if you already do that, but resolving workspace symbols can happen in two steps: First (when provide is called) you can leave out the location information and feed that in when resolve is being called (when a references is actually being selected). We have done that because providers often have to pay an extra price to compute the the line/column information (instead of offsets) we want. Unsure if that applies for Java tho

@fbricon
Copy link
Collaborator

fbricon commented May 10, 2017

@jrieken For now location for types is not computed, always set to 0,0. so that's not an issue.

The performance issue is indeed caused by computing the types, as @aeschli hinted, but we also loaded each type's buffer at some point which was unnecessary. I'm down to ~1 sec to load the types starting with letter A now, but I need to figure out why I'm seeing duplicates and some results cause an error. Anyway, making progress here :-)

fbricon added a commit to fbricon/eclipse.jdt.ls that referenced this issue May 13, 2017
Fixes redhat-developer/vscode-java#204

This fix also includes generating stub class body for source-less classes.

Signed-off-by: Fred Bricon <fbricon@gmail.com>
fbricon added a commit to fbricon/eclipse.jdt.ls that referenced this issue May 15, 2017
Fixes redhat-developer/vscode-java#204

This fix also includes generating stub class body for source-less classes.

Signed-off-by: Fred Bricon <fbricon@gmail.com>
fbricon added a commit to fbricon/eclipse.jdt.ls that referenced this issue May 15, 2017
Fixes redhat-developer/vscode-java#204

This fix also includes generating stub class body for source-less classes.

Signed-off-by: Fred Bricon <fbricon@gmail.com>
fbricon added a commit to eclipse-jdtls/eclipse.jdt.ls that referenced this issue May 15, 2017
Fixes redhat-developer/vscode-java#204

This fix also includes generating stub class body for source-less classes.

Signed-off-by: Fred Bricon <fbricon@gmail.com>
@fbricon
Copy link
Collaborator

fbricon commented May 15, 2017

Ctrl+T now lists all classes from the workspace
Once you found your class and opened it, Ctrl+Shift+o will list all methods and attributes from said class (if source is available)

@rubin55
Copy link
Author

rubin55 commented May 16, 2017

Just updated to 0.4.0 and tested this, works great!

Much appreciated. I'm still awed by how quick you implemented this. Thanks again!

@dmarrazzo
Copy link

Hi,
Is it possible to extend this feature to match even partial string?
I mean if I type "vismec", I'd like to match "VisitOrMechanic" class.

@fbricon
Copy link
Collaborator

fbricon commented May 24, 2019

@dmarrazzo CamelCase search is supported:
camel-case-search

so, in your case, you should try searching for VisMec

@b-liberman
Copy link

I have version 0.47.0 and it is not working well.
For some classes - it works as expected, e.g.
image

However, many times I have to type "*" in front and then type the complete name before it appears in the list, e.g.:
image
image
image
image

Boris

@fbricon
Copy link
Collaborator

fbricon commented Aug 3, 2019

Can you please attach a sample projects reproducing the issue?

@b-liberman
Copy link

here is my gradle and vs code files
vscode_204.zip

@banatara
Copy link

banatara commented Sep 29, 2019

Hi Team, I am able to search types based on the java class name or Interface name, but could not list the types that are with the package. Say example, when I type ctrl+t #sun.rmi.server it should probably list all the class /Interface or anything within that package. This has been the feature in eclipse already as mentioned by peoples earlier in this thread.

@liudonghua123
Copy link

I also looking for search java classes which the classes are in some jars.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants