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

New folders do not register in the jdt.ls workspace #10115 #10893

Merged
merged 1 commit into from
Sep 5, 2018

Conversation

vrubezhny
Copy link
Contributor

This adds the reporting creation/modification/deletion of source folders to jdt.ls

Signed-off-by: Victor Rubezhny [email protected]

What does this PR do?

Fix adds a listener for changes inside source folders (Create/Update/Delete) in order to report them to jds.ls.

ls10115-part2

What issues does this PR fix or reference?

Fixes #10115
Depends on eclipse-che/che-ls-jdt#70
Depends on eclipse-jdtls/eclipse.jdt.ls#755

Release Notes

Docs PR

@riuvshin
Copy link
Contributor

Can one of the admins verify this patch?

2 similar comments
@riuvshin
Copy link
Contributor

Can one of the admins verify this patch?

@riuvshin
Copy link
Contributor

Can one of the admins verify this patch?

@tsmaeder tsmaeder added kind/bug Outline of a bug - must adhere to the bug report template. team/languages labels Aug 24, 2018
@@ -38,6 +42,14 @@
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. The formatting seems wrong here
  2. Why do we need annotation API?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I don't have those tabs in my code... Looks like they were there for some time, but after I fixed them locally git ignores the fix. I'll try to fix
  2. Probably because of:
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;

in PlainJavaProjectSourceFolderWatcher

@@ -90,6 +94,10 @@ public void checkMoveJavaClassInNewSourceFolder() {
// move java file into new source folder
projectExplorer.waitItem(PROJECT_NAME);
projectExplorer.waitAndSelectItem(PATH_TO_FILE);

// As FileTreeWalker's period is 10 secs - wait for the folders to be finally reported to jdt.ls
WaitUtils.sleepQuietly(11);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't there a condition we can wait for?

Copy link
Contributor Author

@vrubezhny vrubezhny Aug 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right answer is yes, we're waiting for a condition but, during the test, the content of 'Move'-dialog's tree is not updated. This sleepQuitely() call allows all the required changes to happen before the dialog is invoked.

* @param projectPath project path
* @return source folder locations
*/
public List<String> getAllSourceFoldersLocations(String projectPath) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Source folders are package fragement roots, not package fragments. I dont' think the command you introduced does what you think it does.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should read as "every location in source folder"...
If we have a project tree like:

Project
  +-- SourceFolder
       +-- org.pack.age
       +-- org.pack.house

With this method I'm going to get the list consisting of the following paths:

/projects/Project/SourceFolder/org/pack/age
/projects/Project/SourceFolder/org/pack/house

in order to make them accepted by FileWatcherByPathMatcher.
If I don't do this, any file/folder that is not created during the working session (any existing path of a project) is never being reported as Updated or Deleted and, as such, will never be refreshed on jdt.ls workspace. As result, every such path (package) deleted by user, despite of its deletions, will appear in Move-dialog as an existing package.

@@ -456,6 +457,20 @@ private ClasspathEntry fixEntry(ClasspathEntry e) {
return result.stream().map(LanguageServiceUtils::removePrefixUri).collect(Collectors.toList());
}

/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JavaLanguageServerExtensionService is made for communication with the browser. That's one reason why the methods are synchronous. This method here is NOT for that purpose, so should be somewhere else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it

private void setInitialPathsToWatch(String projectUri) {
List<String> sourceFolderLocations;
try {
sourceFolderLocations = extensionService.getAllSourceFoldersLocations(projectUri);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not use a synchronous call here, rather use the promise we get from "WorkspaceService.executeCommand()". Then we can get rid of the executor service.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-implemented

watcherIds.stream().forEach(id -> manager.unRegisterByMatcher(id));
}

private void onServerInitialized(LanguageServerInitializedEvent event) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to collect all language servers here. We only want to notify the java language server, and we can find that one by id.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to listen to language server start events. There is supposed to be a way to just ask for a language server by id. No need to remember it here.

Copy link
Contributor Author

@vrubezhny vrubezhny Sep 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's done exactly the same way here:
https://github.com/eclipse/che/blob/master/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/LanguageServerFileWatcher.java#L82

If I won't wait for LS start, the obtaining of Java LS will be failed - not sure if it's a good trying to do anything with LS before it's started...
I don't know... Maybe I can use someow org.eclipse.che.api.languageserver.FindServer.byId(String) - but again - it could return null (if it is allowed t use it from che-plugin-java-plain-server)

}

private void send(LanguageServer server, String path, FileChangeType changeType) {
RegisteredProject project = projectManager.getClosestOrNull(path);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this check necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not cleaned up code. sorry.

}

private PathMatcher folderMatcher() {
return it -> isSourceFolder(it);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is causing us to communicate with jdt.ls for every folder change in the file system. I think it would be more efficient to send every folder change to jdt.ls and let jdt.ls do the filtering.
Also, are we interested in every change or only in create/delete?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right, I think we can reduce this check to just isDirectory(it) call. And we don't need to send Update as jdt.ls just ignores this event for folders.

@vrubezhny vrubezhny force-pushed the ls10115-part2 branch 2 times, most recently from ade6988 to b6379dc Compare August 28, 2018 02:22
@vrubezhny
Copy link
Contributor Author

@tsmaeder I've re-implemented the fix based on your comments.
As result MoveJavaFileInNewSourceFolderTest is also looks fixed. (However I still in doubt if I should have leaved that sleepQuitely() line in the test as the default timeout is equal to the File Tree Walker period and, in theory, test might fail by timeout under some circumstances)

Please review.

@benoitf benoitf added status/code-review This issue has a pull request posted for it and is awaiting code review completion by the community. target/branch Indicates that a PR will be merged into a branch other than master. labels Aug 28, 2018
@svor svor requested a review from tolusha August 29, 2018 06:29
watcherIds.stream().forEach(id -> manager.unRegisterByMatcher(id));
}

private void onServerInitialized(LanguageServerInitializedEvent event) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to listen to language server start events. There is supposed to be a way to just ask for a language server by id. No need to remember it here.

This adds the reporting creation/modification/deletion of source folders to jdt.ls

Signed-off-by: Victor Rubezhny <[email protected]>
@vrubezhny
Copy link
Contributor Author

@tsmaeder I've rebased and modified this PR - now it tries to find Java LS when it's needed by its ID (JavaModule.LS_ID)

@tsmaeder tsmaeder merged commit 9d271dd into eclipse-che:5730_java_ls_poc Sep 5, 2018
@benoitf benoitf removed the status/code-review This issue has a pull request posted for it and is awaiting code review completion by the community. label Sep 5, 2018
tsmaeder pushed a commit that referenced this pull request Sep 13, 2018
tsmaeder pushed a commit that referenced this pull request Sep 20, 2018
tsmaeder pushed a commit that referenced this pull request Sep 26, 2018
tsmaeder pushed a commit that referenced this pull request Oct 1, 2018
tsmaeder pushed a commit that referenced this pull request Oct 5, 2018
tsmaeder pushed a commit that referenced this pull request Oct 12, 2018
tsmaeder pushed a commit that referenced this pull request Oct 16, 2018
tsmaeder pushed a commit that referenced this pull request Oct 17, 2018
tsmaeder pushed a commit that referenced this pull request Oct 17, 2018
tsmaeder pushed a commit that referenced this pull request Oct 17, 2018
tsmaeder pushed a commit that referenced this pull request Oct 17, 2018
tsmaeder pushed a commit that referenced this pull request Oct 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Outline of a bug - must adhere to the bug report template. target/branch Indicates that a PR will be merged into a branch other than master.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants