17
17
import java .util .HashSet ;
18
18
import java .util .Set ;
19
19
20
- import org .eclipse .core .resources .IProject ;
21
20
import org .eclipse .core .resources .WorkspaceJob ;
22
21
import org .eclipse .core .runtime .IProgressMonitor ;
23
22
import org .eclipse .core .runtime .IStatus ;
24
23
import org .eclipse .core .runtime .Status ;
25
24
import org .eclipse .core .runtime .jobs .Job ;
26
25
import org .eclipse .jdt .core .ElementChangedEvent ;
26
+ import org .eclipse .jdt .core .ICompilationUnit ;
27
27
import org .eclipse .jdt .core .IElementChangedListener ;
28
28
import org .eclipse .jdt .core .IJavaElement ;
29
29
import org .eclipse .jdt .core .IJavaElementDelta ;
30
30
import org .eclipse .jdt .core .IJavaProject ;
31
31
import org .eclipse .jdt .core .JavaCore ;
32
+ import org .eclipse .jdt .core .JavaModelException ;
32
33
import org .eclipse .jdt .ls .core .internal .BuildWorkspaceStatus ;
33
34
import org .eclipse .jdt .ls .core .internal .EventNotification ;
34
35
import org .eclipse .jdt .ls .core .internal .EventType ;
41
42
import org .eclipse .lsp4j .extended .ProjectBuildParams ;
42
43
43
44
public class ClasspathUpdateHandler implements IElementChangedListener {
44
-
45
45
private final JavaClientConnection connection ;
46
+ private final BaseDocumentLifeCycleHandler lifeCycleHandler ;
46
47
47
48
public ClasspathUpdateHandler (JavaClientConnection client ) {
49
+ this (client , null );
50
+ }
51
+
52
+ public ClasspathUpdateHandler (JavaClientConnection client , BaseDocumentLifeCycleHandler lifeCycleHandler ) {
48
53
this .connection = client ;
54
+ this .lifeCycleHandler = lifeCycleHandler ;
49
55
}
50
56
51
57
@ Override
52
58
public void elementChanged (ElementChangedEvent event ) {
53
59
// 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 ();
57
65
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 );
84
74
}
85
- };
86
- job .setPriority (Job .SHORT );
87
- job .setRule (project );
88
- job .schedule ();
75
+ }
89
76
}
90
77
}
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 ();
91
105
}
92
106
EventNotification notification = new EventNotification ().withType (EventType .ClasspathUpdated ).withData (uri );
93
107
this .connection .sendEventNotification (notification );
@@ -103,32 +117,27 @@ public void removeElementChangeListener() {
103
117
JavaCore .removeElementChangedListener (this );
104
118
}
105
119
106
- private Set < String > processDeltaChildren (IJavaElementDelta delta , Set <String > uris ) {
120
+ private void processDeltaChildren (IJavaElementDelta delta , Set <IJavaProject > projects ) {
107
121
for (IJavaElementDelta c : delta .getAffectedChildren ()) {
108
- uris = processDelta (c , uris );
122
+ processDelta (c , projects );
109
123
}
110
- return uris ;
111
124
}
112
125
113
- private Set < String > processDelta (IJavaElementDelta delta , Set <String > uris ) {
126
+ private void processDelta (IJavaElementDelta delta , Set <IJavaProject > projects ) {
114
127
IJavaElement element = delta .getElement ();
115
128
switch (element .getElementType ()) {
116
129
case IJavaElement .JAVA_MODEL :
117
- uris = processDeltaChildren (delta , uris );
130
+ processDeltaChildren (delta , projects );
118
131
break ;
119
132
case IJavaElement .JAVA_PROJECT :
120
133
if (isClasspathChanged (delta .getFlags ())) {
121
- if (uris == null ) {
122
- uris = new HashSet <String >();
123
- }
124
134
IJavaProject javaProject = (IJavaProject ) element ;
125
- uris .add (ProjectUtils . getProjectRealFolder ( javaProject . getProject ()). toFile (). toURI (). toString () );
135
+ projects .add (javaProject );
126
136
}
127
137
break ;
128
138
default :
129
139
break ;
130
140
}
131
- return uris ;
132
141
}
133
142
134
143
private boolean isClasspathChanged (int flags ) {
0 commit comments