Skip to content

Commit

Permalink
[WIP] reuse a cached AST if available
Browse files Browse the repository at this point in the history
Signed-off-by: David Thompson <[email protected]>
  • Loading branch information
datho7561 committed Jan 23, 2025
1 parent 7be2137 commit 6a9559c
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.CompletionRequestor;
import org.eclipse.jdt.core.ICompletionEngine;
import org.eclipse.jdt.core.ICompletionEngineProvider;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.internal.codeassist.ICompletionEngine;
import org.eclipse.jdt.internal.codeassist.ICompletionEngineProvider;
import org.eclipse.jdt.internal.core.SearchableEnvironment;
import org.eclipse.jdt.internal.javac.completion.DOMCompletionEngine;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.ICompletionEngine;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
Expand Down Expand Up @@ -93,7 +92,6 @@
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.MethodRef;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.eclipse.jdt.core.dom.ModuleDeclaration;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NameQualifiedType;
Expand Down Expand Up @@ -125,6 +123,7 @@
import org.eclipse.jdt.core.dom.VariableDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.SearchEngine;
Expand All @@ -133,6 +132,7 @@
import org.eclipse.jdt.internal.codeassist.CompletionEngine;
import org.eclipse.jdt.internal.codeassist.DOMCodeSelector;
import org.eclipse.jdt.internal.codeassist.ExpectedTypes;
import org.eclipse.jdt.internal.codeassist.ICompletionEngine;
import org.eclipse.jdt.internal.codeassist.InternalCompletionProposal;
import org.eclipse.jdt.internal.codeassist.RelevanceConstants;
import org.eclipse.jdt.internal.codeassist.impl.AssistOptions;
Expand Down Expand Up @@ -424,29 +424,40 @@ private static CompilationUnit getCompletionAST(char[] content, char[] unitName,
}

@Override
public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit, int completionPosition, int ignored, ITypeRoot root) {
public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit, int completionPosition, ITypeRoot root) {
if (this.monitor != null) {
this.monitor.beginTask(Messages.engine_completing, IProgressMonitor.UNKNOWN);
}
this.requestor.beginReporting();

this.modelUnit = root;
if (modelUnit != null) {
try {
this.textContent = new String(this.modelUnit.getBuffer().getCharacters());
} catch (JavaModelException e) {
this.textContent = new String(sourceUnit.getContents());
ILog.get().error("unable to access buffer for completion", e); //$NON-NLS-1$
}
this.offset = completionPosition;
this.unit = getCompletionAST(this.modelUnit, root.getJavaProject(), this.workingCopyOwner, completionPosition);
if (modelUnit instanceof org.eclipse.jdt.internal.core.CompilationUnit modelCU) {
try {
this.unit = modelCU.getOrBuildAST(this.workingCopyOwner, completionPosition);
} catch (JavaModelException e) {
// do nothing
}
}
if (this.unit == null) {
this.unit = getCompletionAST(this.modelUnit, root.getJavaProject(), this.workingCopyOwner, completionPosition);
}
if (this.unit == null) {
return;
}
} else {
// uh oh
this.textContent = new String(sourceUnit.getContents());
this.offset = completionPosition;
this.unit = getCompletionAST(sourceUnit.getContents(), sourceUnit.getFileName(), this.javaProject, this.workingCopyOwner, completionPosition);
if (this.unit == null) {
this.unit = getCompletionAST(sourceUnit.getContents(), sourceUnit.getFileName(), this.javaProject, this.workingCopyOwner, completionPosition);
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1938,6 +1938,11 @@ private boolean complete(
return true;
}

@Override
public void complete(ICompilationUnit sourceUnit, int completionPosition, ITypeRoot root) {
complete(sourceUnit, completionPosition, 0, root);
}

/**
* Ask the engine to compute a completion at the specified position
* of the given compilation unit.
Expand All @@ -1952,7 +1957,6 @@ private boolean complete(
* a position in the source where the completion is taking place.
* This position is relative to the source provided.
*/
@Override
public void complete(ICompilationUnit sourceUnit, int completionPosition, int pos, ITypeRoot root) {

if(DEBUG) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.jdt.core;
package org.eclipse.jdt.internal.codeassist;

import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;

/**
Expand All @@ -21,10 +22,10 @@ public interface ICompletionEngine {
* Provide completion items based on the given source unit and completion position to the configured requestor.
*
* @param sourceUnit the compilation unit for which completion was triggered
* @param ast the AST of the compilation unit to use for completion. can be null, in which case the completion engine is expected to build it
* @param completionPosition the position that completion was triggered at
* @param pos should always be 0, don't set it to anything else
* @param root the type root for which completion was triggered
*/
public void complete(ICompilationUnit sourceUnit, int completionPosition, int pos, ITypeRoot root);
public void complete(ICompilationUnit sourceUnit, int completionPosition, ITypeRoot root);

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.jdt.core;
package org.eclipse.jdt.internal.codeassist;

import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.CompletionRequestor;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.internal.core.SearchableEnvironment;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -448,14 +448,10 @@ public void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyO

@Override
public void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner workingCopyOwner, IProgressMonitor monitor) throws JavaModelException {
codeComplete(
this,

codeComplete(this,
isWorkingCopy() ? (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) getOriginalElement() : this,
offset,
requestor,
workingCopyOwner,
this,
monitor);
offset, requestor, workingCopyOwner, this, monitor);
}

/**
Expand All @@ -477,20 +473,27 @@ public IJavaElement[] codeSelect(int offset, int length, WorkingCopyOwner workin
}
}

public org.eclipse.jdt.core.dom.CompilationUnit getOrBuildAST(WorkingCopyOwner workingCopyOwner) throws JavaModelException {
public org.eclipse.jdt.core.dom.CompilationUnit getOrBuildAST(WorkingCopyOwner workingCopyOwner, int focalPosition) throws JavaModelException {
if (this.ast != null) {
return this.ast;
}
Map<String, String> options = getOptions(true);
ASTParser parser = ASTParser.newParser(new AST(options).apiLevel()); // go through AST constructor to convert options to apiLevel
// but we should probably instead just use the latest Java version
// supported by the compiler
parser.setWorkingCopyOwner(workingCopyOwner);
parser.setSource(this);
// greedily enable everything assuming the AST will be used extensively for edition
parser.setResolveBindings(true);
parser.setStatementsRecovery(true);
parser.setBindingsRecovery(true);
parser.setCompilerOptions(options);
parser.setFocalPosition(focalPosition);
if (parser.createAST(null) instanceof org.eclipse.jdt.core.dom.CompilationUnit newAST) {
if (focalPosition >= 0) {
// do not store
return newAST;
}
this.ast = newAST;
}
return this.ast;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.ICompletionEngineProvider;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.codeassist.CompletionEngine;
import org.eclipse.jdt.internal.codeassist.ICompletionEngineProvider;

class CompletionEngineProviderDiscovery {
private static final String SELECTED_SYSPROP = "ICompletionEngineProvider"; //$NON-NLS-1$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import org.eclipse.core.runtime.PerformanceStats;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.internal.codeassist.CompletionEngine;
import org.eclipse.jdt.internal.codeassist.ICompletionEngine;
import org.eclipse.jdt.internal.codeassist.ICompletionEngineProvider;
import org.eclipse.jdt.internal.codeassist.SelectionEngine;
import org.eclipse.jdt.internal.compiler.env.IElementInfo;
import org.eclipse.jdt.internal.core.util.Util;
Expand Down Expand Up @@ -134,7 +136,7 @@ protected void codeComplete(
// code complete
ICompletionEngineProvider completionEngineProvider = CompletionEngineProviderDiscovery.getInstance();
ICompletionEngine completionEngine = completionEngineProvider.getCompletionEngine(environment, requestor, project.getOptions(true), project, owner, monitor);
completionEngine.complete(cu, position, 0, typeRoot);
completionEngine.complete(cu, position, typeRoot);

if(performanceStats != null) {
performanceStats.endRun();
Expand Down

0 comments on commit 6a9559c

Please sign in to comment.