Skip to content

Commit 2da94de

Browse files
committed
Performance issue on large project
Signed-off-by: Snjezana Peco <[email protected]>
1 parent 33b1a91 commit 2da94de

File tree

7 files changed

+141
-44
lines changed

7 files changed

+141
-44
lines changed

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/HoverInfoProvider.java

+23-4
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,12 @@ public HoverInfoProvider(ITypeRoot aUnit, PreferenceManager preferenceManager) {
9191
public List<Either<String, MarkedString>> computeHover(int line, int column, IProgressMonitor monitor) {
9292
List<Either<String, MarkedString>> res = new LinkedList<>();
9393
try {
94+
if (monitor.isCanceled()) {
95+
return canceled(res);
96+
}
9497
IJavaElement[] elements = JDTUtils.findElementsAtSelection(unit, line, column, this.preferenceManager, monitor);
95-
if(elements == null || elements.length == 0) {
96-
res.add(Either.forLeft(""));
97-
return res;
98+
if (elements == null || elements.length == 0 || monitor.isCanceled()) {
99+
return canceled(res);
98100
}
99101
IJavaElement curr = null;
100102
if (elements.length != 1) {
@@ -116,7 +118,9 @@ public List<Either<String, MarkedString>> computeHover(int line, int column, IPr
116118
} else {
117119
curr = elements[0];
118120
}
119-
121+
if (monitor.isCanceled()) {
122+
return canceled(res);
123+
}
120124
if (JDTEnvironmentUtils.isSyntaxServer() || isResolved(curr, monitor)) {
121125
IBuffer buffer = curr.getOpenable().getBuffer();
122126
if (buffer == null && curr instanceof BinaryMember) {
@@ -128,10 +132,16 @@ public List<Either<String, MarkedString>> computeHover(int line, int column, IPr
128132
}
129133
}
130134
}
135+
if (monitor.isCanceled()) {
136+
return canceled(res);
137+
}
131138
MarkedString signature = computeSignature(curr);
132139
if (signature != null) {
133140
res.add(Either.forRight(signature));
134141
}
142+
if (monitor.isCanceled()) {
143+
return canceled(res);
144+
}
135145
MarkedString javadoc = computeJavadoc(curr);
136146
if (javadoc != null && javadoc.getValue() != null) {
137147
res.add(Either.forLeft(javadoc.getValue()));
@@ -140,6 +150,15 @@ public List<Either<String, MarkedString>> computeHover(int line, int column, IPr
140150
} catch (Exception e) {
141151
JavaLanguageServerPlugin.logException("Error computing hover", e);
142152
}
153+
if (monitor.isCanceled()) {
154+
return canceled(res);
155+
}
156+
return res;
157+
}
158+
159+
private List<Either<String, MarkedString>> canceled(List<Either<String, MarkedString>> res) {
160+
res.clear();
161+
res.add(Either.forLeft(""));
143162
return res;
144163
}
145164

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JDTUtils.java

+11-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.eclipse.core.runtime.Path;
4646
import org.eclipse.core.runtime.Platform;
4747
import org.eclipse.core.runtime.URIUtil;
48+
import org.eclipse.core.runtime.jobs.ISchedulingRule;
4849
import org.eclipse.jdt.core.CompletionProposal;
4950
import org.eclipse.jdt.core.Flags;
5051
import org.eclipse.jdt.core.IAnnotatable;
@@ -703,14 +704,14 @@ public static String getFileURI(IResource resource) {
703704

704705
public static IJavaElement findElementAtSelection(ITypeRoot unit, int line, int column, PreferenceManager preferenceManager, IProgressMonitor monitor) throws JavaModelException {
705706
IJavaElement[] elements = findElementsAtSelection(unit, line, column, preferenceManager, monitor);
706-
if (elements != null && elements.length == 1) {
707+
if ((elements != null && elements.length == 1) || monitor.isCanceled()) {
707708
return elements[0];
708709
}
709710
return null;
710711
}
711712

712713
public static IJavaElement[] findElementsAtSelection(ITypeRoot unit, int line, int column, PreferenceManager preferenceManager, IProgressMonitor monitor) throws JavaModelException {
713-
if (unit == null) {
714+
if (unit == null || monitor.isCanceled()) {
714715
return null;
715716
}
716717
int offset = JsonRpcHelpers.toOffset(unit.getBuffer(), line, column);
@@ -801,6 +802,14 @@ public static IFile findFile(String uriString) {
801802
return (IFile) findResource(toURI(uriString), ResourcesPlugin.getWorkspace().getRoot()::findFilesForLocationURI);
802803
}
803804

805+
public static ISchedulingRule getRule(String uri) {
806+
IResource resource = JDTUtils.findFile(uri);
807+
if (resource != null) {
808+
return ResourcesPlugin.getWorkspace().getRuleFactory().createRule(resource);
809+
}
810+
return null;
811+
}
812+
804813
public static IContainer findFolder(String uriString) {
805814
return (IContainer) findResource(toURI(uriString), ResourcesPlugin.getWorkspace().getRoot()::findContainersForLocationURI);
806815
}

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/BaseDocumentLifeCycleHandler.java

+56-14
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
import org.eclipse.core.resources.IFile;
2424
import org.eclipse.core.resources.IResource;
25+
import org.eclipse.core.resources.IResourceRuleFactory;
26+
import org.eclipse.core.resources.IWorkspace;
2527
import org.eclipse.core.resources.IWorkspaceRunnable;
2628
import org.eclipse.core.resources.ResourcesPlugin;
2729
import org.eclipse.core.resources.WorkspaceJob;
@@ -32,6 +34,8 @@
3234
import org.eclipse.core.runtime.NullProgressMonitor;
3335
import org.eclipse.core.runtime.Status;
3436
import org.eclipse.core.runtime.SubMonitor;
37+
import org.eclipse.core.runtime.jobs.ISchedulingRule;
38+
import org.eclipse.core.runtime.jobs.MultiRule;
3539
import org.eclipse.jdt.core.IBuffer;
3640
import org.eclipse.jdt.core.ICompilationUnit;
3741
import org.eclipse.jdt.core.IJavaElement;
@@ -90,7 +94,7 @@ public boolean belongsTo(Object family) {
9094
return DOCUMENT_LIFE_CYCLE_JOBS.equals(family);
9195
}
9296
};
93-
this.validationTimer.setRule(ResourcesPlugin.getWorkspace().getRoot());
97+
// this.validationTimer.setRule(ResourcesPlugin.getWorkspace().getRoot());
9498
this.publishDiagnosticsJob = new WorkspaceJob("Publish Diagnostics") {
9599
@Override
96100
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
@@ -105,7 +109,7 @@ public boolean belongsTo(Object family) {
105109
return PUBLISH_DIAGNOSTICS_JOBS.equals(family);
106110
}
107111
};
108-
this.validationTimer.setRule(ResourcesPlugin.getWorkspace().getRoot());
112+
// this.validationTimer.setRule(ResourcesPlugin.getWorkspace().getRoot());
109113
}
110114
}
111115

@@ -129,30 +133,53 @@ protected void triggerValidation(ICompilationUnit cu, long delay) throws JavaMod
129133
}
130134
if (validationTimer != null) {
131135
validationTimer.cancel();
136+
ISchedulingRule rule = getRule(toReconcile);
132137
if (publishDiagnosticsJob != null) {
133138
publishDiagnosticsJob.cancel();
139+
publishDiagnosticsJob.setRule(rule);
134140
}
141+
validationTimer.setRule(rule);
135142
validationTimer.schedule(delay);
136143
} else {
137144
performValidation(new NullProgressMonitor());
138145
}
139146
}
140147

148+
private ISchedulingRule getRule(Set<ICompilationUnit> units) {
149+
ISchedulingRule result = null;
150+
IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory();
151+
for (ICompilationUnit unit : units) {
152+
if (unit.getResource() != null) {
153+
ISchedulingRule rule = ruleFactory.createRule(unit.getResource());
154+
result = MultiRule.combine(rule, result);
155+
}
156+
}
157+
return result;
158+
}
159+
141160
private IStatus performValidation(IProgressMonitor monitor) throws JavaModelException {
142161
long start = System.currentTimeMillis();
143162

144-
List<ICompilationUnit> cusToReconcile = new ArrayList<>();
163+
List<ICompilationUnit> cusToReconcile;
145164
synchronized (toReconcile) {
165+
if (toReconcile.isEmpty()) {
166+
return Status.OK_STATUS;
167+
}
168+
cusToReconcile = new ArrayList<>();
146169
cusToReconcile.addAll(toReconcile);
147170
toReconcile.clear();
148171
}
149-
if (cusToReconcile.isEmpty()) {
150-
return Status.OK_STATUS;
172+
if (monitor.isCanceled()) {
173+
return Status.CANCEL_STATUS;
151174
}
152175
// first reconcile all units with content changes
153176
SubMonitor progress = SubMonitor.convert(monitor, cusToReconcile.size() + 1);
154177
for (ICompilationUnit cu : cusToReconcile) {
155-
cu.reconcile(ICompilationUnit.NO_AST, true, null, progress.newChild(1));
178+
if (monitor.isCanceled()) {
179+
return Status.CANCEL_STATUS;
180+
}
181+
cu.makeConsistent(progress);
182+
//cu.reconcile(ICompilationUnit.NO_AST, false, null, progress.newChild(1));
156183
}
157184
JavaLanguageServerPlugin.logInfo("Reconciled " + toReconcile.size() + ". Took " + (System.currentTimeMillis() - start) + " ms");
158185
if (monitor.isCanceled()) {
@@ -165,6 +192,9 @@ private IStatus performValidation(IProgressMonitor monitor) throws JavaModelExce
165192
} catch (InterruptedException e) {
166193
// ignore
167194
}
195+
if (monitor.isCanceled()) {
196+
return Status.CANCEL_STATUS;
197+
}
168198
publishDiagnosticsJob.schedule(400);
169199
} else {
170200
return publishDiagnostics(new NullProgressMonitor());
@@ -179,6 +209,9 @@ private IStatus publishDiagnostics(IProgressMonitor monitor) throws JavaModelExc
179209
}
180210
this.sharedASTProvider.disposeAST();
181211
List<ICompilationUnit> toValidate = Arrays.asList(JavaCore.getWorkingCopies(null));
212+
if (toValidate.isEmpty()) {
213+
return Status.OK_STATUS;
214+
}
182215
SubMonitor progress = SubMonitor.convert(monitor, toValidate.size() + 1);
183216
if (monitor.isCanceled()) {
184217
return Status.CANCEL_STATUS;
@@ -188,6 +221,9 @@ private IStatus publishDiagnostics(IProgressMonitor monitor) throws JavaModelExc
188221
return Status.CANCEL_STATUS;
189222
}
190223
CompilationUnit astRoot = this.sharedASTProvider.getAST(rootToValidate, CoreASTProvider.WAIT_YES, monitor);
224+
if (monitor.isCanceled()) {
225+
return Status.CANCEL_STATUS;
226+
}
191227
if (astRoot != null) {
192228
// report errors, even if there are no problems in the file: The client need to know that they got fixed.
193229
ICompilationUnit unit = (ICompilationUnit) astRoot.getTypeRoot();
@@ -207,10 +243,12 @@ private void publishDiagnostics(ICompilationUnit unit, IProgressMonitor monitor)
207243
*/
208244
@Override
209245
public IBuffer createBuffer(ICompilationUnit workingCopy) {
210-
ICompilationUnit original = workingCopy.getPrimary();
211-
IResource resource = original.getResource();
212-
if (resource instanceof IFile) {
213-
return new DocumentAdapter(workingCopy, (IFile) resource);
246+
if (!monitor.isCanceled()) {
247+
ICompilationUnit original = workingCopy.getPrimary();
248+
IResource resource = original.getResource();
249+
if (resource instanceof IFile) {
250+
return new DocumentAdapter(workingCopy, (IFile) resource);
251+
}
214252
}
215253
return DocumentAdapter.Null;
216254
}
@@ -229,53 +267,57 @@ public IProblemRequestor getProblemRequestor(ICompilationUnit workingCopy) {
229267
}
230268

231269
public void didClose(DidCloseTextDocumentParams params) {
270+
ISchedulingRule rule = JDTUtils.getRule(params.getTextDocument().getUri());
232271
try {
233272
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
234273
@Override
235274
public void run(IProgressMonitor monitor) throws CoreException {
236275
handleClosed(params);
237276
}
238-
}, new NullProgressMonitor());
277+
}, rule, IWorkspace.AVOID_UPDATE, new NullProgressMonitor());
239278
} catch (CoreException e) {
240279
JavaLanguageServerPlugin.logException("Handle document close ", e);
241280
}
242281
}
243282

244283
public void didOpen(DidOpenTextDocumentParams params) {
284+
ISchedulingRule rule = JDTUtils.getRule(params.getTextDocument().getUri());
245285
try {
246286
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
247287
@Override
248288
public void run(IProgressMonitor monitor) throws CoreException {
249289
handleOpen(params);
250290
}
251-
}, new NullProgressMonitor());
291+
}, rule, IWorkspace.AVOID_UPDATE, new NullProgressMonitor());
252292
} catch (CoreException e) {
253293
JavaLanguageServerPlugin.logException("Handle document open ", e);
254294
}
255295
}
256296

257297
public void didChange(DidChangeTextDocumentParams params) {
298+
ISchedulingRule rule = JDTUtils.getRule(params.getTextDocument().getUri());
258299
try {
259300
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
260301
@Override
261302
public void run(IProgressMonitor monitor) throws CoreException {
262303
handleChanged(params);
263304
}
264-
}, new NullProgressMonitor());
305+
}, rule, IWorkspace.AVOID_UPDATE, new NullProgressMonitor());
265306
} catch (CoreException e) {
266307
JavaLanguageServerPlugin.logException("Handle document change ", e);
267308
}
268309
}
269310

270311
public void didSave(DidSaveTextDocumentParams params) {
312+
ISchedulingRule rule = JDTUtils.getRule(params.getTextDocument().getUri());
271313
try {
272314
JobHelpers.waitForJobs(DocumentLifeCycleHandler.DOCUMENT_LIFE_CYCLE_JOBS, new NullProgressMonitor());
273315
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
274316
@Override
275317
public void run(IProgressMonitor monitor) throws CoreException {
276318
handleSaved(params);
277319
}
278-
}, new NullProgressMonitor());
320+
}, rule, IWorkspace.AVOID_UPDATE, new NullProgressMonitor());
279321
} catch (CoreException e) {
280322
JavaLanguageServerPlugin.logException("Handle document save ", e);
281323
}

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/CodeActionHandler.java

+22-6
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,20 @@ public CodeActionHandler(PreferenceManager preferenceManager) {
7777
}
7878

7979
public List<Either<Command, CodeAction>> getCodeActionCommands(CodeActionParams params, IProgressMonitor monitor) {
80+
if (monitor.isCanceled()) {
81+
return Collections.emptyList();
82+
}
8083
final ICompilationUnit unit = JDTUtils.resolveCompilationUnit(params.getTextDocument().getUri());
81-
if (unit == null) {
84+
if (unit == null || monitor.isCanceled()) {
8285
return Collections.emptyList();
8386
}
84-
8587
int start = DiagnosticsHelper.getStartOffset(unit, params.getRange());
8688
int end = DiagnosticsHelper.getEndOffset(unit, params.getRange());
8789
InnovationContext context = new InnovationContext(unit, start, end - start);
8890
context.setASTRoot(getASTRoot(unit));
89-
91+
if (monitor.isCanceled()) {
92+
return Collections.emptyList();
93+
}
9094
IProblemLocationCore[] locations = this.getProblemLocationCores(unit, params.getContext().getDiagnostics());
9195

9296
List<String> codeActionKinds = new ArrayList<>();
@@ -115,6 +119,9 @@ public List<Either<Command, CodeAction>> getCodeActionCommands(CodeActionParams
115119
JavaLanguageServerPlugin.logException("Problem resolving quick fix code actions", e);
116120
}
117121
}
122+
if (monitor.isCanceled()) {
123+
return Collections.emptyList();
124+
}
118125

119126
if (containsKind(codeActionKinds, CodeActionKind.Refactor)) {
120127
try {
@@ -125,7 +132,9 @@ public List<Either<Command, CodeAction>> getCodeActionCommands(CodeActionParams
125132
JavaLanguageServerPlugin.logException("Problem resolving refactor code actions", e);
126133
}
127134
}
128-
135+
if (monitor.isCanceled()) {
136+
return Collections.emptyList();
137+
}
129138
if (containsKind(codeActionKinds, JavaCodeActionKind.QUICK_ASSIST)) {
130139
try {
131140
List<ChangeCorrectionProposal> quickassistProposals = this.quickAssistProcessor.getAssists(params, context, locations);
@@ -135,7 +144,9 @@ public List<Either<Command, CodeAction>> getCodeActionCommands(CodeActionParams
135144
JavaLanguageServerPlugin.logException("Problem resolving quick assist code actions", e);
136145
}
137146
}
138-
147+
if (monitor.isCanceled()) {
148+
return Collections.emptyList();
149+
}
139150
try {
140151
for (ChangeCorrectionProposal proposal : proposals) {
141152
Optional<Either<Command, CodeAction>> codeActionFromProposal = getCodeActionFromProposal(proposal, params.getContext());
@@ -146,10 +157,15 @@ public List<Either<Command, CodeAction>> getCodeActionCommands(CodeActionParams
146157
} catch (CoreException e) {
147158
JavaLanguageServerPlugin.logException("Problem converting proposal to code actions", e);
148159
}
149-
160+
if (monitor.isCanceled()) {
161+
return Collections.emptyList();
162+
}
150163
if (containsKind(codeActionKinds, CodeActionKind.Source)) {
151164
codeActions.addAll(sourceAssistProcessor.getSourceActionCommands(params, context, locations));
152165
}
166+
if (monitor.isCanceled()) {
167+
return Collections.emptyList();
168+
}
153169
return codeActions;
154170
}
155171

0 commit comments

Comments
 (0)