Skip to content

Commit

Permalink
Performance issue on large project
Browse files Browse the repository at this point in the history
Signed-off-by: Snjezana Peco <[email protected]>
  • Loading branch information
snjeza committed Jun 16, 2020
1 parent e048ffa commit b2cf718
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,12 @@ public HoverInfoProvider(ITypeRoot aUnit, PreferenceManager preferenceManager) {
public List<Either<String, MarkedString>> computeHover(int line, int column, IProgressMonitor monitor) {
List<Either<String, MarkedString>> res = new LinkedList<>();
try {
if (monitor.isCanceled()) {
return cancelled(res);
}
IJavaElement[] elements = JDTUtils.findElementsAtSelection(unit, line, column, this.preferenceManager, monitor);
if(elements == null || elements.length == 0) {
res.add(Either.forLeft(""));
return res;
if (elements == null || elements.length == 0 || monitor.isCanceled()) {
return cancelled(res);
}
IJavaElement curr = null;
if (elements.length != 1) {
Expand All @@ -116,7 +118,9 @@ public List<Either<String, MarkedString>> computeHover(int line, int column, IPr
} else {
curr = elements[0];
}

if (monitor.isCanceled()) {
return cancelled(res);
}
if (JDTEnvironmentUtils.isSyntaxServer() || isResolved(curr, monitor)) {
IBuffer buffer = curr.getOpenable().getBuffer();
if (buffer == null && curr instanceof BinaryMember) {
Expand All @@ -128,10 +132,16 @@ public List<Either<String, MarkedString>> computeHover(int line, int column, IPr
}
}
}
if (monitor.isCanceled()) {
return cancelled(res);
}
MarkedString signature = computeSignature(curr);
if (signature != null) {
res.add(Either.forRight(signature));
}
if (monitor.isCanceled()) {
return cancelled(res);
}
MarkedString javadoc = computeJavadoc(curr);
if (javadoc != null && javadoc.getValue() != null) {
res.add(Either.forLeft(javadoc.getValue()));
Expand All @@ -140,6 +150,15 @@ public List<Either<String, MarkedString>> computeHover(int line, int column, IPr
} catch (Exception e) {
JavaLanguageServerPlugin.logException("Error computing hover", e);
}
if (monitor.isCanceled()) {
return cancelled(res);
}
return res;
}

private List<Either<String, MarkedString>> cancelled(List<Either<String, MarkedString>> res) {
res.clear();
res.add(Either.forLeft(""));
return res;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.jdt.core.CompletionProposal;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IAnnotatable;
Expand Down Expand Up @@ -703,14 +704,14 @@ public static String getFileURI(IResource resource) {

public static IJavaElement findElementAtSelection(ITypeRoot unit, int line, int column, PreferenceManager preferenceManager, IProgressMonitor monitor) throws JavaModelException {
IJavaElement[] elements = findElementsAtSelection(unit, line, column, preferenceManager, monitor);
if (elements != null && elements.length == 1) {
if ((elements != null && elements.length == 1) || monitor.isCanceled()) {
return elements[0];
}
return null;
}

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

public static ISchedulingRule getRule(String uri) {
IResource resource = JDTUtils.findFile(uri);
if (resource != null) {
return ResourcesPlugin.getWorkspace().getRuleFactory().createRule(resource);
}
return null;
}

public static IContainer findFolder(String uriString) {
return (IContainer) findResource(toURI(uriString), ResourcesPlugin.getWorkspace().getRoot()::findContainersForLocationURI);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
Expand All @@ -32,6 +34,8 @@
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.MultiRule;
import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
Expand Down Expand Up @@ -90,7 +94,6 @@ public boolean belongsTo(Object family) {
return DOCUMENT_LIFE_CYCLE_JOBS.equals(family);
}
};
this.validationTimer.setRule(ResourcesPlugin.getWorkspace().getRoot());
this.publishDiagnosticsJob = new WorkspaceJob("Publish Diagnostics") {
@Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
Expand All @@ -105,7 +108,6 @@ public boolean belongsTo(Object family) {
return PUBLISH_DIAGNOSTICS_JOBS.equals(family);
}
};
this.validationTimer.setRule(ResourcesPlugin.getWorkspace().getRoot());
}
}

Expand All @@ -129,30 +131,53 @@ protected void triggerValidation(ICompilationUnit cu, long delay) throws JavaMod
}
if (validationTimer != null) {
validationTimer.cancel();
ISchedulingRule rule = getRule(toReconcile);
if (publishDiagnosticsJob != null) {
publishDiagnosticsJob.cancel();
publishDiagnosticsJob.setRule(rule);
}
validationTimer.setRule(rule);
validationTimer.schedule(delay);
} else {
performValidation(new NullProgressMonitor());
}
}

private ISchedulingRule getRule(Set<ICompilationUnit> units) {
ISchedulingRule result = null;
IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory();
for (ICompilationUnit unit : units) {
if (unit.getResource() != null) {
ISchedulingRule rule = ruleFactory.createRule(unit.getResource());
result = MultiRule.combine(rule, result);
}
}
return result;
}

private IStatus performValidation(IProgressMonitor monitor) throws JavaModelException {
long start = System.currentTimeMillis();

List<ICompilationUnit> cusToReconcile = new ArrayList<>();
List<ICompilationUnit> cusToReconcile;
synchronized (toReconcile) {
if (toReconcile.isEmpty()) {
return Status.OK_STATUS;
}
cusToReconcile = new ArrayList<>();
cusToReconcile.addAll(toReconcile);
toReconcile.clear();
}
if (cusToReconcile.isEmpty()) {
return Status.OK_STATUS;
if (monitor.isCanceled()) {
return Status.CANCEL_STATUS;
}
// first reconcile all units with content changes
SubMonitor progress = SubMonitor.convert(monitor, cusToReconcile.size() + 1);
for (ICompilationUnit cu : cusToReconcile) {
cu.reconcile(ICompilationUnit.NO_AST, true, null, progress.newChild(1));
if (monitor.isCanceled()) {
return Status.CANCEL_STATUS;
}
cu.makeConsistent(progress);
//cu.reconcile(ICompilationUnit.NO_AST, false, null, progress.newChild(1));
}
JavaLanguageServerPlugin.logInfo("Reconciled " + toReconcile.size() + ". Took " + (System.currentTimeMillis() - start) + " ms");
if (monitor.isCanceled()) {
Expand All @@ -165,6 +190,9 @@ private IStatus performValidation(IProgressMonitor monitor) throws JavaModelExce
} catch (InterruptedException e) {
// ignore
}
if (monitor.isCanceled()) {
return Status.CANCEL_STATUS;
}
publishDiagnosticsJob.schedule(400);
} else {
return publishDiagnostics(new NullProgressMonitor());
Expand All @@ -179,6 +207,9 @@ private IStatus publishDiagnostics(IProgressMonitor monitor) throws JavaModelExc
}
this.sharedASTProvider.disposeAST();
List<ICompilationUnit> toValidate = Arrays.asList(JavaCore.getWorkingCopies(null));
if (toValidate.isEmpty()) {
return Status.OK_STATUS;
}
SubMonitor progress = SubMonitor.convert(monitor, toValidate.size() + 1);
if (monitor.isCanceled()) {
return Status.CANCEL_STATUS;
Expand All @@ -188,6 +219,9 @@ private IStatus publishDiagnostics(IProgressMonitor monitor) throws JavaModelExc
return Status.CANCEL_STATUS;
}
CompilationUnit astRoot = this.sharedASTProvider.getAST(rootToValidate, CoreASTProvider.WAIT_YES, monitor);
if (monitor.isCanceled()) {
return Status.CANCEL_STATUS;
}
if (astRoot != null) {
// report errors, even if there are no problems in the file: The client need to know that they got fixed.
ICompilationUnit unit = (ICompilationUnit) astRoot.getTypeRoot();
Expand All @@ -207,10 +241,12 @@ private void publishDiagnostics(ICompilationUnit unit, IProgressMonitor monitor)
*/
@Override
public IBuffer createBuffer(ICompilationUnit workingCopy) {
ICompilationUnit original = workingCopy.getPrimary();
IResource resource = original.getResource();
if (resource instanceof IFile) {
return new DocumentAdapter(workingCopy, (IFile) resource);
if (!monitor.isCanceled()) {
ICompilationUnit original = workingCopy.getPrimary();
IResource resource = original.getResource();
if (resource instanceof IFile) {
return new DocumentAdapter(workingCopy, (IFile) resource);
}
}
return DocumentAdapter.Null;
}
Expand All @@ -229,53 +265,57 @@ public IProblemRequestor getProblemRequestor(ICompilationUnit workingCopy) {
}

public void didClose(DidCloseTextDocumentParams params) {
ISchedulingRule rule = JDTUtils.getRule(params.getTextDocument().getUri());
try {
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
@Override
public void run(IProgressMonitor monitor) throws CoreException {
handleClosed(params);
}
}, new NullProgressMonitor());
}, rule, IWorkspace.AVOID_UPDATE, new NullProgressMonitor());
} catch (CoreException e) {
JavaLanguageServerPlugin.logException("Handle document close ", e);
}
}

public void didOpen(DidOpenTextDocumentParams params) {
ISchedulingRule rule = JDTUtils.getRule(params.getTextDocument().getUri());
try {
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
@Override
public void run(IProgressMonitor monitor) throws CoreException {
handleOpen(params);
}
}, new NullProgressMonitor());
}, rule, IWorkspace.AVOID_UPDATE, new NullProgressMonitor());
} catch (CoreException e) {
JavaLanguageServerPlugin.logException("Handle document open ", e);
}
}

public void didChange(DidChangeTextDocumentParams params) {
ISchedulingRule rule = JDTUtils.getRule(params.getTextDocument().getUri());
try {
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
@Override
public void run(IProgressMonitor monitor) throws CoreException {
handleChanged(params);
}
}, new NullProgressMonitor());
}, rule, IWorkspace.AVOID_UPDATE, new NullProgressMonitor());
} catch (CoreException e) {
JavaLanguageServerPlugin.logException("Handle document change ", e);
}
}

public void didSave(DidSaveTextDocumentParams params) {
ISchedulingRule rule = JDTUtils.getRule(params.getTextDocument().getUri());
try {
JobHelpers.waitForJobs(DocumentLifeCycleHandler.DOCUMENT_LIFE_CYCLE_JOBS, new NullProgressMonitor());
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
@Override
public void run(IProgressMonitor monitor) throws CoreException {
handleSaved(params);
}
}, new NullProgressMonitor());
}, rule, IWorkspace.AVOID_UPDATE, new NullProgressMonitor());
} catch (CoreException e) {
JavaLanguageServerPlugin.logException("Handle document save ", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,20 @@ public CodeActionHandler(PreferenceManager preferenceManager) {
}

public List<Either<Command, CodeAction>> getCodeActionCommands(CodeActionParams params, IProgressMonitor monitor) {
if (monitor.isCanceled()) {
return Collections.emptyList();
}
final ICompilationUnit unit = JDTUtils.resolveCompilationUnit(params.getTextDocument().getUri());
if (unit == null) {
if (unit == null || monitor.isCanceled()) {
return Collections.emptyList();
}

int start = DiagnosticsHelper.getStartOffset(unit, params.getRange());
int end = DiagnosticsHelper.getEndOffset(unit, params.getRange());
InnovationContext context = new InnovationContext(unit, start, end - start);
context.setASTRoot(getASTRoot(unit));

if (monitor.isCanceled()) {
return Collections.emptyList();
}
IProblemLocationCore[] locations = this.getProblemLocationCores(unit, params.getContext().getDiagnostics());

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

if (containsKind(codeActionKinds, CodeActionKind.Refactor)) {
try {
Expand All @@ -125,7 +132,9 @@ public List<Either<Command, CodeAction>> getCodeActionCommands(CodeActionParams
JavaLanguageServerPlugin.logException("Problem resolving refactor code actions", e);
}
}

if (monitor.isCanceled()) {
return Collections.emptyList();
}
if (containsKind(codeActionKinds, JavaCodeActionKind.QUICK_ASSIST)) {
try {
List<ChangeCorrectionProposal> quickassistProposals = this.quickAssistProcessor.getAssists(params, context, locations);
Expand All @@ -135,7 +144,9 @@ public List<Either<Command, CodeAction>> getCodeActionCommands(CodeActionParams
JavaLanguageServerPlugin.logException("Problem resolving quick assist code actions", e);
}
}

if (monitor.isCanceled()) {
return Collections.emptyList();
}
try {
for (ChangeCorrectionProposal proposal : proposals) {
Optional<Either<Command, CodeAction>> codeActionFromProposal = getCodeActionFromProposal(proposal, params.getContext());
Expand All @@ -146,10 +157,15 @@ public List<Either<Command, CodeAction>> getCodeActionCommands(CodeActionParams
} catch (CoreException e) {
JavaLanguageServerPlugin.logException("Problem converting proposal to code actions", e);
}

if (monitor.isCanceled()) {
return Collections.emptyList();
}
if (containsKind(codeActionKinds, CodeActionKind.Source)) {
codeActions.addAll(sourceAssistProcessor.getSourceActionCommands(params, context, locations));
}
if (monitor.isCanceled()) {
return Collections.emptyList();
}
return codeActions;
}

Expand Down
Loading

0 comments on commit b2cf718

Please sign in to comment.