Skip to content

Commit bb26c98

Browse files
ethan-vanderheijdenrgrunber
authored andcommittedJun 7, 2024
Revalidate open files in project when classpath updates.
1 parent 4c0e045 commit bb26c98

File tree

3 files changed

+55
-47
lines changed

3 files changed

+55
-47
lines changed
 

‎org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/ProjectUtils.java

-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.util.Arrays;
2020
import java.util.Collection;
2121
import java.util.Collections;
22-
import java.util.Comparator;
2322
import java.util.HashMap;
2423
import java.util.HashSet;
2524
import java.util.Hashtable;

‎org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/ClasspathUpdateHandler.java

+54-45
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,19 @@
1717
import java.util.HashSet;
1818
import java.util.Set;
1919

20-
import org.eclipse.core.resources.IProject;
2120
import org.eclipse.core.resources.WorkspaceJob;
2221
import org.eclipse.core.runtime.IProgressMonitor;
2322
import org.eclipse.core.runtime.IStatus;
2423
import org.eclipse.core.runtime.Status;
2524
import org.eclipse.core.runtime.jobs.Job;
2625
import org.eclipse.jdt.core.ElementChangedEvent;
26+
import org.eclipse.jdt.core.ICompilationUnit;
2727
import org.eclipse.jdt.core.IElementChangedListener;
2828
import org.eclipse.jdt.core.IJavaElement;
2929
import org.eclipse.jdt.core.IJavaElementDelta;
3030
import org.eclipse.jdt.core.IJavaProject;
3131
import org.eclipse.jdt.core.JavaCore;
32+
import org.eclipse.jdt.core.JavaModelException;
3233
import org.eclipse.jdt.ls.core.internal.BuildWorkspaceStatus;
3334
import org.eclipse.jdt.ls.core.internal.EventNotification;
3435
import org.eclipse.jdt.ls.core.internal.EventType;
@@ -41,53 +42,66 @@
4142
import org.eclipse.lsp4j.extended.ProjectBuildParams;
4243

4344
public class ClasspathUpdateHandler implements IElementChangedListener {
44-
4545
private final JavaClientConnection connection;
46+
private final BaseDocumentLifeCycleHandler lifeCycleHandler;
4647

4748
public ClasspathUpdateHandler(JavaClientConnection client) {
49+
this(client, null);
50+
}
51+
52+
public ClasspathUpdateHandler(JavaClientConnection client, BaseDocumentLifeCycleHandler lifeCycleHandler) {
4853
this.connection = client;
54+
this.lifeCycleHandler = lifeCycleHandler;
4955
}
5056

5157
@Override
5258
public void elementChanged(ElementChangedEvent event) {
5359
// Collect project names which have classpath changed.
54-
Set<String> uris = processDelta(event.getDelta(), null);
55-
if (connection != null && uris != null && !uris.isEmpty()) {
56-
for (String uri : uris) {
60+
Set<IJavaProject> projects = new HashSet<>();
61+
processDelta(event.getDelta(), projects);
62+
if (connection != null && projects != null && !projects.isEmpty()) {
63+
for (IJavaProject javaProject : projects) {
64+
String uri = ProjectUtils.getProjectRealFolder(javaProject.getProject()).toFile().toURI().toString();
5765
PreferenceManager preferenceManager = JavaLanguageServerPlugin.getPreferencesManager();
58-
if (preferenceManager.getPreferences().getNullAnalysisMode().equals(FeatureStatus.automatic)) {
59-
IProject project = ProjectUtils.getProjectFromUri(uri);
60-
if (project != null) {
61-
IJavaProject javaProject = ProjectUtils.getJavaProject(project);
62-
if (javaProject != null) {
63-
WorkspaceJob job = new WorkspaceJob("Classpath Update Job") {
64-
@Override
65-
public IStatus runInWorkspace(IProgressMonitor monitor) {
66-
if (!preferenceManager.getPreferences().updateAnnotationNullAnalysisOptions(javaProject, true) || !preferenceManager.getPreferences().isAutobuildEnabled()) {
67-
// When the project's compiler options didn't change or auto build is disabled, rebuilding is not required.
68-
return Status.OK_STATUS;
69-
}
70-
BuildWorkspaceHandler buildWorkspaceHandler = new BuildWorkspaceHandler(JavaLanguageServerPlugin.getProjectsManager());
71-
ProjectBuildParams params = new ProjectBuildParams(Arrays.asList(new TextDocumentIdentifier(uri)), true);
72-
BuildWorkspaceStatus status = buildWorkspaceHandler.buildProjects(params, monitor);
73-
switch (status) {
74-
case FAILED:
75-
case WITH_ERROR:
76-
return Status.error("error occurs during building project");
77-
case SUCCEED:
78-
return Status.OK_STATUS;
79-
case CANCELLED:
80-
return Status.CANCEL_STATUS;
81-
default:
82-
return Status.OK_STATUS;
83-
}
66+
if (!preferenceManager.getPreferences().isAutobuildEnabled()) {
67+
if (lifeCycleHandler != null) {
68+
for (ICompilationUnit unit : JavaCore.getWorkingCopies(null)) {
69+
if (unit.getJavaProject().equals(javaProject)) {
70+
try {
71+
lifeCycleHandler.triggerValidation(unit);
72+
} catch (JavaModelException e) {
73+
JavaLanguageServerPlugin.logException("Failed to revalidate document after classpath change: " + unit.getPath(), e);
8474
}
85-
};
86-
job.setPriority(Job.SHORT);
87-
job.setRule(project);
88-
job.schedule();
75+
}
8976
}
9077
}
78+
} else if (preferenceManager.getPreferences().getNullAnalysisMode().equals(FeatureStatus.automatic)) {
79+
WorkspaceJob job = new WorkspaceJob("Classpath Update Job") {
80+
@Override
81+
public IStatus runInWorkspace(IProgressMonitor monitor) {
82+
if (!preferenceManager.getPreferences().updateAnnotationNullAnalysisOptions(javaProject, true)) {
83+
// When the project's compiler options didn't change, rebuilding is not required.
84+
return Status.OK_STATUS;
85+
}
86+
BuildWorkspaceHandler buildWorkspaceHandler = new BuildWorkspaceHandler(JavaLanguageServerPlugin.getProjectsManager());
87+
ProjectBuildParams params = new ProjectBuildParams(Arrays.asList(new TextDocumentIdentifier(uri)), true);
88+
BuildWorkspaceStatus status = buildWorkspaceHandler.buildProjects(params, monitor);
89+
switch (status) {
90+
case FAILED:
91+
case WITH_ERROR:
92+
return Status.error("error occurs during building project");
93+
case SUCCEED:
94+
return Status.OK_STATUS;
95+
case CANCELLED:
96+
return Status.CANCEL_STATUS;
97+
default:
98+
return Status.OK_STATUS;
99+
}
100+
}
101+
};
102+
job.setPriority(Job.SHORT);
103+
job.setRule(javaProject.getProject());
104+
job.schedule();
91105
}
92106
EventNotification notification = new EventNotification().withType(EventType.ClasspathUpdated).withData(uri);
93107
this.connection.sendEventNotification(notification);
@@ -103,32 +117,27 @@ public void removeElementChangeListener() {
103117
JavaCore.removeElementChangedListener(this);
104118
}
105119

106-
private Set<String> processDeltaChildren(IJavaElementDelta delta, Set<String> uris) {
120+
private void processDeltaChildren(IJavaElementDelta delta, Set<IJavaProject> projects) {
107121
for (IJavaElementDelta c : delta.getAffectedChildren()) {
108-
uris = processDelta(c, uris);
122+
processDelta(c, projects);
109123
}
110-
return uris;
111124
}
112125

113-
private Set<String> processDelta(IJavaElementDelta delta, Set<String> uris) {
126+
private void processDelta(IJavaElementDelta delta, Set<IJavaProject> projects) {
114127
IJavaElement element = delta.getElement();
115128
switch (element.getElementType()) {
116129
case IJavaElement.JAVA_MODEL:
117-
uris = processDeltaChildren(delta, uris);
130+
processDeltaChildren(delta, projects);
118131
break;
119132
case IJavaElement.JAVA_PROJECT:
120133
if (isClasspathChanged(delta.getFlags())) {
121-
if (uris == null) {
122-
uris = new HashSet<String>();
123-
}
124134
IJavaProject javaProject = (IJavaProject) element;
125-
uris.add(ProjectUtils.getProjectRealFolder(javaProject.getProject()).toFile().toURI().toString());
135+
projects.add(javaProject);
126136
}
127137
break;
128138
default:
129139
break;
130140
}
131-
return uris;
132141
}
133142

134143
private boolean isClasspathChanged(int flags) {

‎org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/JDTLanguageServer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ public IStatus run(IProgressMonitor monitor) {
303303
try {
304304
workspaceDiagnosticsHandler = new WorkspaceDiagnosticsHandler(JDTLanguageServer.this.client, pm, preferenceManager.getClientPreferences(), documentLifeCycleHandler);
305305
workspaceDiagnosticsHandler.addResourceChangeListener();
306-
classpathUpdateHandler = new ClasspathUpdateHandler(JDTLanguageServer.this.client);
306+
classpathUpdateHandler = new ClasspathUpdateHandler(JDTLanguageServer.this.client, documentLifeCycleHandler);
307307
classpathUpdateHandler.addElementChangeListener();
308308
SourceAttachUpdateHandler attachListener = new SourceAttachUpdateHandler(client);
309309
attachListener.addElementChangeListener();

0 commit comments

Comments
 (0)