mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
Use synchronized methods for java compilation
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package com.itsaky.lsp.java;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.sun.source.tree.CompilationUnitTree;
|
||||
import com.sun.source.util.JavacTask;
|
||||
import java.nio.file.Path;
|
||||
@@ -12,7 +14,15 @@ public class CompileTask implements AutoCloseable {
|
||||
public final JavacTask task;
|
||||
public final List<CompilationUnitTree> roots;
|
||||
public final List<Diagnostic<? extends JavaFileObject>> diagnostics;
|
||||
private final Runnable close;
|
||||
|
||||
private final CompileBatch compileBatch;
|
||||
|
||||
public CompileTask(@NonNull CompileBatch compileBatch, List<Diagnostic<? extends JavaFileObject>> diagnostics) {
|
||||
this.compileBatch = compileBatch;
|
||||
this.task = compileBatch.task;
|
||||
this.roots = compileBatch.roots;
|
||||
this.diagnostics = diagnostics;
|
||||
}
|
||||
|
||||
public CompilationUnitTree root() {
|
||||
if (roots.size() != 1) {
|
||||
@@ -39,19 +49,8 @@ public class CompileTask implements AutoCloseable {
|
||||
throw new RuntimeException("Compilation unit not found");
|
||||
}
|
||||
|
||||
public CompileTask(
|
||||
JavacTask task,
|
||||
List<CompilationUnitTree> roots,
|
||||
List<Diagnostic<? extends JavaFileObject>> diagnostics,
|
||||
Runnable close) {
|
||||
this.task = task;
|
||||
this.roots = roots;
|
||||
this.diagnostics = diagnostics;
|
||||
this.close = close;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
close.run();
|
||||
compileBatch.close ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.itsaky.lsp.java;
|
||||
|
||||
import com.itsaky.lsp.java.utils.SynchronizedTask;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collection;
|
||||
@@ -29,9 +31,9 @@ public interface CompilerProvider {
|
||||
|
||||
ParseTask parse(JavaFileObject file);
|
||||
|
||||
CompileTask compile(Path... files);
|
||||
SynchronizedTask compile(Path... files);
|
||||
|
||||
CompileTask compile(Collection<? extends JavaFileObject> sources);
|
||||
SynchronizedTask compile(Collection<? extends JavaFileObject> sources);
|
||||
|
||||
Path NOT_FOUND = Paths.get("");
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.itsaky.lsp.java;
|
||||
|
||||
import com.itsaky.androidide.utils.Logger;
|
||||
import com.itsaky.lsp.java.utils.Extractors;
|
||||
import com.itsaky.lsp.java.utils.SynchronizedTask;
|
||||
import com.itsaky.lsp.java.visitors.FindTypeDeclarations;
|
||||
import com.sun.source.tree.CompilationUnitTree;
|
||||
|
||||
@@ -18,6 +19,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -28,12 +30,15 @@ import javax.tools.StandardLocation;
|
||||
|
||||
class JavaCompilerService implements CompilerProvider {
|
||||
|
||||
private CompileBatch cachedCompile;
|
||||
|
||||
final Set<Path> classPath, docPath;
|
||||
final Set<String> jdkClasses = new HashSet<> (), classPathClasses;
|
||||
|
||||
final ReusableCompiler compiler = new ReusableCompiler ();
|
||||
|
||||
final SynchronizedTask synchronizedTask = new SynchronizedTask ();
|
||||
final ReentrantLock lock = new ReentrantLock ();
|
||||
final List<Diagnostic<? extends JavaFileObject>> diags = new ArrayList<> ();
|
||||
final Map<JavaFileObject, Long> cachedModified = new HashMap<> ();
|
||||
|
||||
// Use the same file manager for multiple tasks, so we don't repeatedly re-compile the same files
|
||||
// TODO intercept files that aren't in the batch and erase method bodies so compilation is faster
|
||||
@@ -57,9 +62,6 @@ class JavaCompilerService implements CompilerProvider {
|
||||
this.fileManager = new SourceFileManager ();
|
||||
}
|
||||
|
||||
private CompileBatch cachedCompile;
|
||||
private final Map<JavaFileObject, Long> cachedModified = new HashMap<> ();
|
||||
|
||||
private boolean needsCompile (Collection<? extends JavaFileObject> sources) {
|
||||
|
||||
if (cachedModified.size () != sources.size ()) {
|
||||
@@ -325,18 +327,34 @@ class JavaCompilerService implements CompilerProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompileTask compile (Path... files) {
|
||||
List<JavaFileObject> sources = new ArrayList<> ();
|
||||
for (Path f : files) {
|
||||
sources.add (new SourceFileObject (f));
|
||||
}
|
||||
return compile (sources);
|
||||
public synchronized SynchronizedTask compile (Path... files) {
|
||||
return synchronizedTask.getWithTask (compileTask -> {
|
||||
List<JavaFileObject> sources = new ArrayList<> ();
|
||||
for (Path f : files) {
|
||||
sources.add (new SourceFileObject (f));
|
||||
}
|
||||
return compile (sources);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompileTask compile (Collection<? extends JavaFileObject> sources) {
|
||||
CompileBatch compile = compileBatch (sources);
|
||||
return new CompileTask (compile.task, compile.roots, diags, compile::close);
|
||||
public synchronized SynchronizedTask compile (Collection<? extends JavaFileObject> sources) {
|
||||
synchronized (synchronizedTask) {
|
||||
final CompileBatch compile = compileBatch (sources);
|
||||
final CompileTask compileTask = new CompileTask (compile, diags);
|
||||
synchronizedTask.setTask (compileTask);
|
||||
return synchronizedTask;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void close () {
|
||||
if (cachedCompile != null && !cachedCompile.closed) {
|
||||
cachedCompile.close();
|
||||
}
|
||||
|
||||
if (lock.isHeldByCurrentThread() && lock.isLocked()) {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private static final Logger LOG = Logger.instance ("JavaCompilerService");
|
||||
|
||||
@@ -80,7 +80,7 @@ import javax.tools.JavaFileObject;
|
||||
*/
|
||||
class ReusableCompiler {
|
||||
|
||||
private static final Logger LOG = Logger.instance ("main");
|
||||
private static final Logger LOG = Logger.instance ("ReusableCompiler");
|
||||
private static final JavacTool systemProvider = JavacTool.create ();
|
||||
|
||||
private List<String> currentOptions = new ArrayList<> ();
|
||||
@@ -119,8 +119,7 @@ class ReusableCompiler {
|
||||
}
|
||||
|
||||
checkedOut = true;
|
||||
List<String> opts =
|
||||
StreamSupport.stream (options.spliterator (), false).collect (Collectors.toCollection (ArrayList::new));
|
||||
List<String> opts = StreamSupport.stream (options.spliterator (), false).collect (Collectors.toCollection (ArrayList::new));
|
||||
if (!opts.equals (currentOptions)) {
|
||||
LOG.warn (String.format ("Options changed from %s to %s, creating new compiler", options, opts));
|
||||
currentOptions = opts;
|
||||
@@ -133,7 +132,7 @@ class ReusableCompiler {
|
||||
|
||||
task.addTaskListener (currentContext);
|
||||
|
||||
return new Borrow (task, currentContext);
|
||||
return lastBorrow = new Borrow (task);
|
||||
}
|
||||
|
||||
class Borrow implements AutoCloseable {
|
||||
@@ -141,7 +140,7 @@ class ReusableCompiler {
|
||||
final JavacTask task;
|
||||
boolean closed;
|
||||
|
||||
Borrow (JavacTask task, ReusableContext ctx) {
|
||||
Borrow (JavacTask task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
@@ -160,7 +159,7 @@ class ReusableCompiler {
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException ("Unable to call cleanup() on JavacTaskImpl", e);
|
||||
}
|
||||
|
||||
|
||||
checkedOut = false;
|
||||
closed = true;
|
||||
}
|
||||
@@ -288,7 +287,4 @@ class ReusableCompiler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class CompilerInUseException extends RuntimeException {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.itsaky.lsp.java.rewrite.RemoveClass;
|
||||
import com.itsaky.lsp.java.rewrite.RemoveException;
|
||||
import com.itsaky.lsp.java.rewrite.RemoveMethod;
|
||||
import com.itsaky.lsp.java.rewrite.Rewrite;
|
||||
import com.itsaky.lsp.java.utils.SynchronizedTask;
|
||||
import com.itsaky.lsp.java.visitors.FindMethodDeclarationAt;
|
||||
import com.itsaky.lsp.java.visitors.FindTypeDeclarationAt;
|
||||
import com.itsaky.lsp.models.CodeActionItem;
|
||||
@@ -106,12 +107,14 @@ public class CodeActionProvider implements ICodeActionProvider {
|
||||
// task to generate the code actions
|
||||
// If we switch to resolving code actions asynchronously using Command, that will fix this problem.
|
||||
final TreeMap<String, Rewrite> rewrites = new TreeMap<> ();
|
||||
try (final CompileTask task = compiler.compile(file)) {
|
||||
long elapsed = Duration.between(started, Instant.now()).toMillis();
|
||||
LOG.info(String.format(Locale.getDefault (), "...compiled in %d ms", elapsed));
|
||||
final LineMap lines = task.root().getLineMap();
|
||||
final long cursor = lines.getPosition(params.getRange().getStart().getLine() + 1, params.getRange().getStart().getColumn () + 1);
|
||||
rewrites.putAll(overrideInheritedMethods(task, file, cursor));
|
||||
try (final SynchronizedTask synchronizedTask = compiler.compile(file)) {
|
||||
synchronizedTask.runWithTask (task -> {
|
||||
long elapsed = Duration.between(started, Instant.now()).toMillis();
|
||||
LOG.info(String.format(Locale.getDefault (), "...compiled in %d ms", elapsed));
|
||||
final LineMap lines = task.root().getLineMap();
|
||||
final long cursor = lines.getPosition(params.getRange().getStart().getLine() + 1, params.getRange().getStart().getColumn () + 1);
|
||||
rewrites.putAll(overrideInheritedMethods(task, file, cursor));
|
||||
});
|
||||
}
|
||||
|
||||
List<CodeActionItem> actions = new ArrayList<> ();
|
||||
@@ -184,15 +187,17 @@ public class CodeActionProvider implements ICodeActionProvider {
|
||||
LOG.info(String.format(Locale.getDefault (), "Check %d diagnostics for quick fixes...", params.getDiagnostics().size()));
|
||||
Instant started = Instant.now();
|
||||
Path file = params.getFile ();
|
||||
try (final CompileTask task = compiler.compile(file)) {
|
||||
List<CodeActionItem> actions = new ArrayList<>();
|
||||
for (DiagnosticItem d : params.getDiagnostics()) {
|
||||
List<CodeActionItem> newActions = codeActionForDiagnostic(task, file, d);
|
||||
actions.addAll(newActions);
|
||||
}
|
||||
long elapsed = Duration.between(started, Instant.now()).toMillis();
|
||||
LOG.info(String.format(Locale.getDefault (), "...created %d quick fixes in %d ms", actions.size(), elapsed));
|
||||
return actions;
|
||||
try (final SynchronizedTask synchronizedTask = compiler.compile(file)) {
|
||||
return synchronizedTask.getWithTask (task -> {
|
||||
List<CodeActionItem> actions = new ArrayList<>();
|
||||
for (DiagnosticItem d : params.getDiagnostics()) {
|
||||
List<CodeActionItem> newActions = codeActionForDiagnostic(task, file, d);
|
||||
actions.addAll(newActions);
|
||||
}
|
||||
long elapsed = Duration.between(started, Instant.now()).toMillis();
|
||||
LOG.info(String.format(Locale.getDefault (), "...created %d quick fixes in %d ms", actions.size(), elapsed));
|
||||
return actions;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.itsaky.lsp.java.rewrite.AddImport;
|
||||
import com.itsaky.lsp.java.utils.EditHelper;
|
||||
import com.itsaky.lsp.java.utils.Extractors;
|
||||
import com.itsaky.lsp.java.utils.ScopeHelper;
|
||||
import com.itsaky.lsp.java.utils.SynchronizedTask;
|
||||
import com.itsaky.lsp.java.visitors.FindCompletionsAt;
|
||||
import com.itsaky.lsp.java.visitors.PruneMethodBodies;
|
||||
import com.itsaky.lsp.models.Command;
|
||||
@@ -145,25 +146,27 @@ public class JavaCompletionProvider implements ICompletionProvider {
|
||||
SourceFileObject source = new SourceFileObject (file, contents, Instant.now());
|
||||
String partial = partialIdentifier(contents, (int) cursor);
|
||||
boolean endsWithParen = endsWithParen(contents, (int) cursor);
|
||||
try (CompileTask task = compiler.compile(Collections.singletonList (source))) {
|
||||
LOG.info("...compiled in " + Duration.between(started, Instant.now()).toMillis() + "ms");
|
||||
TreePath path = new FindCompletionsAt (task.task).scan(task.root(), cursor);
|
||||
switch (path.getLeaf().getKind()) {
|
||||
case IDENTIFIER:
|
||||
return completeIdentifier(task, path, partial, endsWithParen);
|
||||
case MEMBER_SELECT:
|
||||
return completeMemberSelect(task, path, partial, endsWithParen);
|
||||
case MEMBER_REFERENCE:
|
||||
return completeMemberReference(task, path, partial);
|
||||
case SWITCH:
|
||||
return completeSwitchConstant(task, path, partial);
|
||||
case IMPORT:
|
||||
return completeImport(qualifiedPartialIdentifier(contents, (int) cursor));
|
||||
default:
|
||||
CompletionResult list = new CompletionResult();
|
||||
addKeywords(path, partial, list);
|
||||
return list;
|
||||
}
|
||||
try (SynchronizedTask synchronizedTask = compiler.compile(Collections.singletonList (source))) {
|
||||
return synchronizedTask.getWithTask (task -> {
|
||||
LOG.info("...compiled in " + Duration.between(started, Instant.now()).toMillis() + "ms");
|
||||
TreePath path = new FindCompletionsAt (task.task).scan(task.root(), cursor);
|
||||
switch (path.getLeaf().getKind()) {
|
||||
case IDENTIFIER:
|
||||
return completeIdentifier(task, path, partial, endsWithParen);
|
||||
case MEMBER_SELECT:
|
||||
return completeMemberSelect(task, path, partial, endsWithParen);
|
||||
case MEMBER_REFERENCE:
|
||||
return completeMemberReference(task, path, partial);
|
||||
case SWITCH:
|
||||
return completeSwitchConstant(task, path, partial);
|
||||
case IMPORT:
|
||||
return completeImport(qualifiedPartialIdentifier(contents, (int) cursor));
|
||||
default:
|
||||
CompletionResult list = new CompletionResult();
|
||||
addKeywords(path, partial, list);
|
||||
return list;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.itsaky.lsp.java.MarkdownHelper;
|
||||
import com.itsaky.lsp.java.ParseTask;
|
||||
import com.itsaky.lsp.java.utils.ScopeHelper;
|
||||
import com.itsaky.lsp.java.utils.ShortTypePrinter;
|
||||
import com.itsaky.lsp.java.utils.SynchronizedTask;
|
||||
import com.itsaky.lsp.java.visitors.FindInvocationAt;
|
||||
import com.itsaky.lsp.models.ParameterInformation;
|
||||
import com.itsaky.lsp.models.SignatureHelp;
|
||||
@@ -89,39 +90,41 @@ public class SignatureProvider implements ISignatureHelpProvider {
|
||||
|
||||
public SignatureHelp signatureHelp(Path file, int line, int column) {
|
||||
// TODO prune
|
||||
try (CompileTask task = compiler.compile(file)) {
|
||||
long cursor = task.root().getLineMap().getPosition(line, column);
|
||||
TreePath path = new FindInvocationAt (task.task).scan(task.root(), cursor);
|
||||
if (path == null) return NOT_SUPPORTED;
|
||||
if (path.getLeaf() instanceof MethodInvocationTree) {
|
||||
MethodInvocationTree invoke = (MethodInvocationTree) path.getLeaf();
|
||||
List<ExecutableElement> overloads = methodOverloads(task, invoke);
|
||||
List<SignatureInformation> signatures = new ArrayList<> ();
|
||||
for (ExecutableElement method : overloads) {
|
||||
SignatureInformation info = info(method);
|
||||
addSourceInfo(task, method, info);
|
||||
addFancyLabel(info);
|
||||
signatures.add(info);
|
||||
try (SynchronizedTask synchronizedTask = compiler.compile(file)) {
|
||||
return synchronizedTask.getWithTask (task -> {
|
||||
long cursor = task.root().getLineMap().getPosition(line, column);
|
||||
TreePath path = new FindInvocationAt (task.task).scan(task.root(), cursor);
|
||||
if (path == null) return NOT_SUPPORTED;
|
||||
if (path.getLeaf() instanceof MethodInvocationTree) {
|
||||
MethodInvocationTree invoke = (MethodInvocationTree) path.getLeaf();
|
||||
List<ExecutableElement> overloads = methodOverloads(task, invoke);
|
||||
List<SignatureInformation> signatures = new ArrayList<> ();
|
||||
for (ExecutableElement method : overloads) {
|
||||
SignatureInformation info = info(method);
|
||||
addSourceInfo(task, method, info);
|
||||
addFancyLabel(info);
|
||||
signatures.add(info);
|
||||
}
|
||||
int activeSignature = activeSignature(task, path, invoke.getArguments(), overloads);
|
||||
int activeParameter = activeParameter(task, invoke.getArguments(), cursor);
|
||||
return new SignatureHelp(signatures, activeSignature, activeParameter);
|
||||
}
|
||||
int activeSignature = activeSignature(task, path, invoke.getArguments(), overloads);
|
||||
int activeParameter = activeParameter(task, invoke.getArguments(), cursor);
|
||||
return new SignatureHelp(signatures, activeSignature, activeParameter);
|
||||
}
|
||||
if (path.getLeaf() instanceof NewClassTree) {
|
||||
NewClassTree invoke = (NewClassTree) path.getLeaf();
|
||||
List<ExecutableElement> overloads = constructorOverloads(task, invoke);
|
||||
List<SignatureInformation> signatures = new ArrayList<> ();
|
||||
for (ExecutableElement method : overloads) {
|
||||
SignatureInformation info = info(method);
|
||||
addSourceInfo(task, method, info);
|
||||
addFancyLabel(info);
|
||||
signatures.add(info);
|
||||
if (path.getLeaf() instanceof NewClassTree) {
|
||||
NewClassTree invoke = (NewClassTree) path.getLeaf();
|
||||
List<ExecutableElement> overloads = constructorOverloads(task, invoke);
|
||||
List<SignatureInformation> signatures = new ArrayList<> ();
|
||||
for (ExecutableElement method : overloads) {
|
||||
SignatureInformation info = info(method);
|
||||
addSourceInfo(task, method, info);
|
||||
addFancyLabel(info);
|
||||
signatures.add(info);
|
||||
}
|
||||
int activeSignature = activeSignature(task, path, invoke.getArguments(), overloads);
|
||||
int activeParameter = activeParameter(task, invoke.getArguments(), cursor);
|
||||
return new SignatureHelp (signatures, activeSignature, activeParameter);
|
||||
}
|
||||
int activeSignature = activeSignature(task, path, invoke.getArguments(), overloads);
|
||||
int activeParameter = activeParameter(task, invoke.getArguments(), cursor);
|
||||
return new SignatureHelp (signatures, activeSignature, activeParameter);
|
||||
}
|
||||
return NOT_SUPPORTED;
|
||||
return NOT_SUPPORTED;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ package com.itsaky.lsp.java.rewrite;
|
||||
import com.itsaky.lsp.java.CompileTask;
|
||||
import com.itsaky.lsp.java.CompilerProvider;
|
||||
import com.itsaky.lsp.java.utils.FindHelper;
|
||||
import com.itsaky.lsp.java.utils.SynchronizedTask;
|
||||
import com.itsaky.lsp.models.Position;
|
||||
import com.itsaky.lsp.models.Range;
|
||||
import com.itsaky.lsp.models.TextEdit;
|
||||
@@ -53,32 +54,34 @@ public class AddException implements Rewrite {
|
||||
return CANCELLED;
|
||||
}
|
||||
|
||||
try (CompileTask task = compiler.compile(file)) {
|
||||
Trees trees = Trees.instance(task.task);
|
||||
ExecutableElement methodElement = FindHelper.findMethod(task, className, methodName, erasedParameterTypes);
|
||||
MethodTree methodTree = trees.getTree(methodElement);
|
||||
SourcePositions pos = trees.getSourcePositions();
|
||||
LineMap lines = task.root().getLineMap();
|
||||
long startBody = pos.getStartPosition(task.root(), methodTree.getBody());
|
||||
int line = (int) lines.getLineNumber(startBody);
|
||||
int column = (int) lines.getColumnNumber(startBody);
|
||||
Position insertPos = new Position(line - 1, column - 1);
|
||||
String simpleName = exceptionType;
|
||||
int lastDot = simpleName.lastIndexOf('.');
|
||||
if (lastDot != -1) {
|
||||
simpleName = exceptionType.substring(lastDot + 1);
|
||||
}
|
||||
|
||||
String insertText;
|
||||
if (methodTree.getThrows().isEmpty()) {
|
||||
insertText = "throws " + simpleName + " ";
|
||||
} else {
|
||||
insertText = ", " + simpleName + " ";
|
||||
}
|
||||
TextEdit insertThrows = new TextEdit(new Range (insertPos, insertPos), insertText);
|
||||
// TODO add import if needed
|
||||
TextEdit[] edits = {insertThrows};
|
||||
return Collections.singletonMap (file, edits);
|
||||
try (SynchronizedTask synchronizedTask = compiler.compile(file)) {
|
||||
return synchronizedTask.getWithTask (task -> {
|
||||
Trees trees = Trees.instance(task.task);
|
||||
ExecutableElement methodElement = FindHelper.findMethod(task, className, methodName, erasedParameterTypes);
|
||||
MethodTree methodTree = trees.getTree(methodElement);
|
||||
SourcePositions pos = trees.getSourcePositions();
|
||||
LineMap lines = task.root().getLineMap();
|
||||
long startBody = pos.getStartPosition(task.root(), methodTree.getBody());
|
||||
int line = (int) lines.getLineNumber(startBody);
|
||||
int column = (int) lines.getColumnNumber(startBody);
|
||||
Position insertPos = new Position(line - 1, column - 1);
|
||||
String simpleName = exceptionType;
|
||||
int lastDot = simpleName.lastIndexOf('.');
|
||||
if (lastDot != -1) {
|
||||
simpleName = exceptionType.substring(lastDot + 1);
|
||||
}
|
||||
|
||||
String insertText;
|
||||
if (methodTree.getThrows().isEmpty()) {
|
||||
insertText = "throws " + simpleName + " ";
|
||||
} else {
|
||||
insertText = ", " + simpleName + " ";
|
||||
}
|
||||
TextEdit insertThrows = new TextEdit(new Range (insertPos, insertPos), insertText);
|
||||
// TODO add import if needed
|
||||
TextEdit[] edits = {insertThrows};
|
||||
return Collections.singletonMap (file, edits);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
+19
-16
@@ -21,6 +21,7 @@ import com.itsaky.lsp.java.CompileTask;
|
||||
import com.itsaky.lsp.java.CompilerProvider;
|
||||
import com.itsaky.lsp.java.utils.EditHelper;
|
||||
import com.itsaky.lsp.java.utils.FindHelper;
|
||||
import com.itsaky.lsp.java.utils.SynchronizedTask;
|
||||
import com.itsaky.lsp.models.Position;
|
||||
import com.itsaky.lsp.models.Range;
|
||||
import com.itsaky.lsp.models.TextEdit;
|
||||
@@ -51,22 +52,24 @@ public class AddSuppressWarningAnnotation implements Rewrite {
|
||||
if (file == CompilerProvider.NOT_FOUND) {
|
||||
return CANCELLED;
|
||||
}
|
||||
try (CompileTask task = compiler.compile(file)) {
|
||||
Trees trees = Trees.instance(task.task);
|
||||
ExecutableElement methodElement = FindHelper.findMethod(task, className, methodName, erasedParameterTypes);
|
||||
MethodTree methodTree = trees.getTree(methodElement);
|
||||
SourcePositions pos = trees.getSourcePositions();
|
||||
int startMethod = (int) pos.getStartPosition(task.root(), methodTree);
|
||||
LineMap lines = task.root().getLineMap();
|
||||
int line = (int) lines.getLineNumber(startMethod);
|
||||
int column = (int) lines.getColumnNumber(startMethod);
|
||||
int startLine = (int) lines.getStartPosition(line);
|
||||
String indent = EditHelper.repeatSpaces (startMethod - startLine);
|
||||
String insertText = "@SuppressWarnings(\"unchecked\")\n" + indent;
|
||||
Position insertPoint = new Position(line - 1, column - 1);
|
||||
TextEdit insert = new TextEdit(new Range(insertPoint, insertPoint), insertText);
|
||||
TextEdit[] edits = {insert};
|
||||
return Collections.singletonMap (file, edits);
|
||||
try (SynchronizedTask synchronizedTask = compiler.compile(file)) {
|
||||
return synchronizedTask.getWithTask (task -> {
|
||||
Trees trees = Trees.instance(task.task);
|
||||
ExecutableElement methodElement = FindHelper.findMethod(task, className, methodName, erasedParameterTypes);
|
||||
MethodTree methodTree = trees.getTree(methodElement);
|
||||
SourcePositions pos = trees.getSourcePositions();
|
||||
int startMethod = (int) pos.getStartPosition(task.root(), methodTree);
|
||||
LineMap lines = task.root().getLineMap();
|
||||
int line = (int) lines.getLineNumber(startMethod);
|
||||
int column = (int) lines.getColumnNumber(startMethod);
|
||||
int startLine = (int) lines.getStartPosition(line);
|
||||
String indent = EditHelper.repeatSpaces (startMethod - startLine);
|
||||
String insertText = "@SuppressWarnings(\"unchecked\")\n" + indent;
|
||||
Position insertPoint = new Position(line - 1, column - 1);
|
||||
TextEdit insert = new TextEdit(new Range(insertPoint, insertPoint), insertText);
|
||||
TextEdit[] edits = {insert};
|
||||
return Collections.singletonMap (file, edits);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import com.itsaky.androidide.utils.Logger;
|
||||
import com.itsaky.lsp.java.CompileTask;
|
||||
import com.itsaky.lsp.java.CompilerProvider;
|
||||
import com.itsaky.lsp.java.utils.EditHelper;
|
||||
import com.itsaky.lsp.java.utils.SynchronizedTask;
|
||||
import com.itsaky.lsp.java.visitors.FindMethodCallAt;
|
||||
import com.itsaky.lsp.models.Position;
|
||||
import com.itsaky.lsp.models.Range;
|
||||
@@ -61,48 +62,52 @@ public class CreateMissingMethod implements Rewrite {
|
||||
|
||||
@Override
|
||||
public Map<Path, TextEdit[]> rewrite(CompilerProvider compiler) {
|
||||
try (CompileTask task = compiler.compile(file)) {
|
||||
final Trees trees = Trees.instance(task.task);
|
||||
final FindMethodCallAt methodFinder = new FindMethodCallAt (task.task);
|
||||
final MethodInvocationTree call = methodFinder.scan(task.root(), position);
|
||||
if (call == null) {
|
||||
return CANCELLED;
|
||||
}
|
||||
|
||||
final TreePath path = trees.getPath(task.root(), call);
|
||||
final String returnType = methodFinder.getReturnType();
|
||||
Path sourceFile = file;
|
||||
MethodTree currentMethod = surroundingMethod(path);
|
||||
String insertText = "\n";
|
||||
|
||||
insertText += printMethodHeader(task, call, returnType, methodFinder.isMemberSelect(), (currentMethod.getModifiers().getFlags().contains(Modifier.STATIC) || methodFinder.isStaticAccess())) + " {\n" +
|
||||
" // TODO: Implement this method\n" +
|
||||
" " + createReturnStatement(returnType) + "\n" +
|
||||
"}";
|
||||
|
||||
TextEdit[] edits;
|
||||
if(methodFinder.isMemberSelect()) {
|
||||
// Accessing method from another class
|
||||
final CompilationUnitTree compilationUnit = methodFinder.getEnclosingTreePath().getCompilationUnit();
|
||||
final ClassTree enclosingClass = methodFinder.getEnclosingClass();
|
||||
final int indent = EditHelper.indent(task.task, compilationUnit, enclosingClass) + 4;
|
||||
insertText = insertText.replaceAll("\n", "\n" + EditHelper.repeatSpaces (indent));
|
||||
insertText = insertText + "\n";
|
||||
final Position insertPoint = EditHelper.insertAtEndOfClass(task.task, compilationUnit, enclosingClass);
|
||||
edits = new TextEdit[]{new TextEdit(new Range (insertPoint, insertPoint), insertText)};
|
||||
sourceFile = Paths.get (compilationUnit.getSourceFile ().toUri ());
|
||||
} else {
|
||||
ClassTree surroundingClass = surroundingClass(path);
|
||||
int indent = EditHelper.indent(task.task, task.root(), surroundingClass) + 4;
|
||||
insertText = insertText.replaceAll("\n", "\n" + EditHelper.repeatSpaces (indent));
|
||||
insertText = insertText + "\n";
|
||||
Position insertPoint = EditHelper.insertAfter(task.task, task.root(), surroundingMethod(path));
|
||||
edits = new TextEdit[]{new TextEdit(new Range(insertPoint, insertPoint), insertText)};
|
||||
}
|
||||
|
||||
if(file != null)
|
||||
return Collections.singletonMap (sourceFile, edits);
|
||||
else return null;
|
||||
try (SynchronizedTask synchronizedTask = compiler.compile(file)) {
|
||||
return synchronizedTask.getWithTask (task -> {
|
||||
final Trees trees = Trees.instance(task.task);
|
||||
final FindMethodCallAt methodFinder = new FindMethodCallAt (task.task);
|
||||
final MethodInvocationTree call = methodFinder.scan(task.root(), position);
|
||||
if (call == null) {
|
||||
return CANCELLED;
|
||||
}
|
||||
|
||||
final TreePath path = trees.getPath(task.root(), call);
|
||||
final String returnType = methodFinder.getReturnType();
|
||||
Path sourceFile = file;
|
||||
MethodTree currentMethod = surroundingMethod(path);
|
||||
String insertText = "\n";
|
||||
|
||||
insertText += printMethodHeader(task, call, returnType, methodFinder.isMemberSelect(), (currentMethod.getModifiers().getFlags().contains(Modifier.STATIC) || methodFinder.isStaticAccess())) + " {\n" +
|
||||
" // TODO: Implement this method\n" +
|
||||
" " + createReturnStatement(returnType) + "\n" +
|
||||
"}";
|
||||
|
||||
TextEdit[] edits;
|
||||
if(methodFinder.isMemberSelect()) {
|
||||
// Accessing method from another class
|
||||
final CompilationUnitTree compilationUnit = methodFinder.getEnclosingTreePath().getCompilationUnit();
|
||||
final ClassTree enclosingClass = methodFinder.getEnclosingClass();
|
||||
final int indent = EditHelper.indent(task.task, compilationUnit, enclosingClass) + 4;
|
||||
insertText = insertText.replaceAll("\n", "\n" + EditHelper.repeatSpaces (indent));
|
||||
insertText = insertText + "\n";
|
||||
final Position insertPoint = EditHelper.insertAtEndOfClass(task.task, compilationUnit, enclosingClass);
|
||||
edits = new TextEdit[]{new TextEdit(new Range (insertPoint, insertPoint), insertText)};
|
||||
sourceFile = Paths.get (compilationUnit.getSourceFile ().toUri ());
|
||||
} else {
|
||||
ClassTree surroundingClass = surroundingClass(path);
|
||||
int indent = EditHelper.indent(task.task, task.root(), surroundingClass) + 4;
|
||||
insertText = insertText.replaceAll("\n", "\n" + EditHelper.repeatSpaces (indent));
|
||||
insertText = insertText + "\n";
|
||||
Position insertPoint = EditHelper.insertAfter(task.task, task.root(), surroundingMethod(path));
|
||||
edits = new TextEdit[]{new TextEdit(new Range(insertPoint, insertPoint), insertText)};
|
||||
}
|
||||
|
||||
if(file != null) {
|
||||
return Collections.singletonMap (sourceFile, edits);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.itsaky.androidide.utils.Logger;
|
||||
import com.itsaky.lsp.java.CompileTask;
|
||||
import com.itsaky.lsp.java.CompilerProvider;
|
||||
import com.itsaky.lsp.java.utils.EditHelper;
|
||||
import com.itsaky.lsp.java.utils.SynchronizedTask;
|
||||
import com.itsaky.lsp.models.Position;
|
||||
import com.itsaky.lsp.models.Range;
|
||||
import com.itsaky.lsp.models.TextEdit;
|
||||
@@ -55,31 +56,33 @@ public class GenerateRecordConstructor implements Rewrite {
|
||||
LOG.info("Generate default constructor for " + className + "...");
|
||||
// TODO this needs to fall back on looking for inner classes and package-private classes
|
||||
Path file = compiler.findTypeDeclaration(className);
|
||||
try (CompileTask task = compiler.compile(file)) {
|
||||
TypeElement typeElement = task.task.getElements().getTypeElement(className);
|
||||
ClassTree typeTree = Trees.instance(task.task).getTree(typeElement);
|
||||
List<VariableTree> fields = fieldsNeedingInitialization(typeTree);
|
||||
String parameters = generateParameters(task, fields);
|
||||
String initializers = generateInitializers(fields);
|
||||
StringBuilder buf = new StringBuilder ();
|
||||
buf.append("\n");
|
||||
if (typeTree.getModifiers().getFlags().contains(Modifier.PUBLIC)) {
|
||||
buf.append("public ");
|
||||
}
|
||||
|
||||
buf.append(simpleName(className))
|
||||
.append("(")
|
||||
.append(parameters)
|
||||
.append(") {\n ")
|
||||
.append(initializers)
|
||||
.append("\n}");
|
||||
String string = buf.toString();
|
||||
int indent = EditHelper.indent(task.task, task.root(), typeTree) + 4;
|
||||
string = string.replaceAll("\n", "\n" + EditHelper.repeatSpaces (indent));
|
||||
string = string + "\n\n";
|
||||
Position insert = insertPoint(task, typeTree);
|
||||
TextEdit[] edits = {new TextEdit(new Range (insert, insert), string)};
|
||||
return Collections.singletonMap (file, edits);
|
||||
try (SynchronizedTask synchronizedTask = compiler.compile(file)) {
|
||||
return synchronizedTask.getWithTask (task -> {
|
||||
TypeElement typeElement = task.task.getElements().getTypeElement(className);
|
||||
ClassTree typeTree = Trees.instance(task.task).getTree(typeElement);
|
||||
List<VariableTree> fields = fieldsNeedingInitialization(typeTree);
|
||||
String parameters = generateParameters(task, fields);
|
||||
String initializers = generateInitializers(fields);
|
||||
StringBuilder buf = new StringBuilder ();
|
||||
buf.append("\n");
|
||||
if (typeTree.getModifiers().getFlags().contains(Modifier.PUBLIC)) {
|
||||
buf.append("public ");
|
||||
}
|
||||
|
||||
buf.append(simpleName(className))
|
||||
.append("(")
|
||||
.append(parameters)
|
||||
.append(") {\n ")
|
||||
.append(initializers)
|
||||
.append("\n}");
|
||||
String string = buf.toString();
|
||||
int indent = EditHelper.indent(task.task, task.root(), typeTree) + 4;
|
||||
string = string.replaceAll("\n", "\n" + EditHelper.repeatSpaces (indent));
|
||||
string = string + "\n\n";
|
||||
Position insert = insertPoint(task, typeTree);
|
||||
TextEdit[] edits = {new TextEdit(new Range (insert, insert), string)};
|
||||
return Collections.singletonMap (file, edits);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.itsaky.lsp.java.CompilerProvider;
|
||||
import com.itsaky.lsp.java.ParseTask;
|
||||
import com.itsaky.lsp.java.utils.EditHelper;
|
||||
import com.itsaky.lsp.java.utils.FindHelper;
|
||||
import com.itsaky.lsp.java.utils.SynchronizedTask;
|
||||
import com.itsaky.lsp.models.Position;
|
||||
import com.itsaky.lsp.models.Range;
|
||||
import com.itsaky.lsp.models.TextEdit;
|
||||
@@ -67,30 +68,32 @@ public class ImplementAbstractMethods implements Rewrite {
|
||||
@Override
|
||||
public Map<Path, TextEdit[]> rewrite(CompilerProvider compiler) {
|
||||
StringJoiner insertText = new StringJoiner ("\n");
|
||||
try (CompileTask task = compiler.compile(file)) {
|
||||
Elements elements = task.task.getElements();
|
||||
Types types = task.task.getTypes();
|
||||
Trees trees = Trees.instance(task.task);
|
||||
TypeElement thisClass = (TypeElement) trees.getElement(this.path);
|
||||
DeclaredType thisType = (DeclaredType) thisClass.asType();
|
||||
ClassTree thisTree = trees.getTree(thisClass);
|
||||
int indent = EditHelper.indent(task.task, task.root(), thisTree) + 4;
|
||||
for (Element member : elements.getAllMembers(thisClass)) {
|
||||
if (member.getKind() == ElementKind.METHOD && member.getModifiers().contains(Modifier.ABSTRACT)) {
|
||||
ExecutableElement method = (ExecutableElement) member;
|
||||
MethodTree source = findSource(compiler, task, method);
|
||||
if (source == null) {
|
||||
LOG.warn("...couldn't find source for " + method);
|
||||
try (SynchronizedTask synchronizedTask = compiler.compile(file)) {
|
||||
return synchronizedTask.getWithTask (task -> {
|
||||
Elements elements = task.task.getElements();
|
||||
Types types = task.task.getTypes();
|
||||
Trees trees = Trees.instance(task.task);
|
||||
TypeElement thisClass = (TypeElement) trees.getElement(this.path);
|
||||
DeclaredType thisType = (DeclaredType) thisClass.asType();
|
||||
ClassTree thisTree = trees.getTree(thisClass);
|
||||
int indent = EditHelper.indent(task.task, task.root(), thisTree) + 4;
|
||||
for (Element member : elements.getAllMembers(thisClass)) {
|
||||
if (member.getKind() == ElementKind.METHOD && member.getModifiers().contains(Modifier.ABSTRACT)) {
|
||||
ExecutableElement method = (ExecutableElement) member;
|
||||
MethodTree source = findSource(compiler, task, method);
|
||||
if (source == null) {
|
||||
LOG.warn("...couldn't find source for " + method);
|
||||
}
|
||||
ExecutableType parameterizedType = (ExecutableType) types.asMemberOf(thisType, method);
|
||||
String text = EditHelper.printMethod(method, parameterizedType, source);
|
||||
text = text.replaceAll("\n", "\n" + EditHelper.repeatSpaces (indent));
|
||||
insertText.add(text);
|
||||
}
|
||||
ExecutableType parameterizedType = (ExecutableType) types.asMemberOf(thisType, method);
|
||||
String text = EditHelper.printMethod(method, parameterizedType, source);
|
||||
text = text.replaceAll("\n", "\n" + EditHelper.repeatSpaces (indent));
|
||||
insertText.add(text);
|
||||
}
|
||||
}
|
||||
Position insert = EditHelper.insertAtEndOfClass(task.task, task.root(), thisTree);
|
||||
TextEdit[] edits = {new TextEdit(new Range (insert, insert), insertText + "\n")};
|
||||
return Collections.singletonMap (file, edits);
|
||||
Position insert = EditHelper.insertAtEndOfClass(task.task, task.root(), thisTree);
|
||||
TextEdit[] edits = {new TextEdit(new Range (insert, insert), insertText + "\n")};
|
||||
return Collections.singletonMap (file, edits);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.itsaky.lsp.java.CompilerProvider;
|
||||
import com.itsaky.lsp.java.ParseTask;
|
||||
import com.itsaky.lsp.java.utils.EditHelper;
|
||||
import com.itsaky.lsp.java.utils.FindHelper;
|
||||
import com.itsaky.lsp.java.utils.SynchronizedTask;
|
||||
import com.itsaky.lsp.java.visitors.FindTypeDeclarationAt;
|
||||
import com.itsaky.lsp.models.Position;
|
||||
import com.itsaky.lsp.models.Range;
|
||||
@@ -69,23 +70,25 @@ public class OverrideInheritedMethod implements Rewrite {
|
||||
}
|
||||
|
||||
private String insertText(CompilerProvider compiler) {
|
||||
try (final CompileTask task = compiler.compile(file)) {
|
||||
final Types types = task.task.getTypes();
|
||||
final Trees trees = Trees.instance(task.task);
|
||||
final ExecutableElement superMethod = FindHelper.findMethod(task, superClassName, methodName, erasedParameterTypes);
|
||||
final ClassTree thisTree = new FindTypeDeclarationAt (task.task).scan(task.root(), (long) insertPosition);
|
||||
final TreePath thisPath = trees.getPath(task.root(), thisTree);
|
||||
final TypeElement thisClass = (TypeElement) trees.getElement(thisPath);
|
||||
final ExecutableType parameterizedType = (ExecutableType) types.asMemberOf((DeclaredType) thisClass.asType(), superMethod);
|
||||
final int indent = EditHelper.indent(task.task, task.root(), thisTree) + 4;
|
||||
final Optional<JavaFileObject> sourceFile = compiler.findAnywhere(superClassName);
|
||||
if (!sourceFile.isPresent ()) return "";
|
||||
final ParseTask parse = compiler.parse(sourceFile.get());
|
||||
final MethodTree source = FindHelper.findMethod(parse, superClassName, methodName, erasedParameterTypes);
|
||||
String text = EditHelper.printMethod(superMethod, parameterizedType, source);
|
||||
text = text.replaceAll("\n", "\n" + EditHelper.repeatSpaces (indent));
|
||||
text = text + "\n\n";
|
||||
return text;
|
||||
try (final SynchronizedTask synchronizedTask = compiler.compile(file)) {
|
||||
return synchronizedTask.getWithTask (task -> {
|
||||
final Types types = task.task.getTypes();
|
||||
final Trees trees = Trees.instance(task.task);
|
||||
final ExecutableElement superMethod = FindHelper.findMethod(task, superClassName, methodName, erasedParameterTypes);
|
||||
final ClassTree thisTree = new FindTypeDeclarationAt (task.task).scan(task.root(), (long) insertPosition);
|
||||
final TreePath thisPath = trees.getPath(task.root(), thisTree);
|
||||
final TypeElement thisClass = (TypeElement) trees.getElement(thisPath);
|
||||
final ExecutableType parameterizedType = (ExecutableType) types.asMemberOf((DeclaredType) thisClass.asType(), superMethod);
|
||||
final int indent = EditHelper.indent(task.task, task.root(), thisTree) + 4;
|
||||
final Optional<JavaFileObject> sourceFile = compiler.findAnywhere(superClassName);
|
||||
if (!sourceFile.isPresent ()) return "";
|
||||
final ParseTask parse = compiler.parse(sourceFile.get());
|
||||
final MethodTree source = FindHelper.findMethod(parse, superClassName, methodName, erasedParameterTypes);
|
||||
String text = EditHelper.printMethod(superMethod, parameterizedType, source);
|
||||
text = text.replaceAll("\n", "\n" + EditHelper.repeatSpaces (indent));
|
||||
text = text + "\n\n";
|
||||
return text;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ package com.itsaky.lsp.java.rewrite;
|
||||
import com.itsaky.lsp.java.CompileTask;
|
||||
import com.itsaky.lsp.java.CompilerProvider;
|
||||
import com.itsaky.lsp.java.utils.FindHelper;
|
||||
import com.itsaky.lsp.java.utils.SynchronizedTask;
|
||||
import com.itsaky.lsp.models.Position;
|
||||
import com.itsaky.lsp.models.Range;
|
||||
import com.itsaky.lsp.models.TextEdit;
|
||||
@@ -58,20 +59,22 @@ public class RemoveException implements Rewrite {
|
||||
@Override
|
||||
public Map<Path, TextEdit[]> rewrite(CompilerProvider compiler) {
|
||||
Path file = compiler.findTypeDeclaration(className);
|
||||
try (CompileTask task = compiler.compile(file)) {
|
||||
ExecutableElement methodElement = FindHelper.findMethod(task, className, methodName, erasedParameterTypes);
|
||||
MethodTree methodTree = Trees.instance(task.task).getTree(methodElement);
|
||||
if (methodTree.getThrows().size() == 1) {
|
||||
TextEdit delete = removeEntireThrows(task.task, task.root(), methodTree);
|
||||
if (delete == TextEdit.NONE) {
|
||||
return CANCELLED;
|
||||
try (SynchronizedTask synchronizedTask = compiler.compile(file)) {
|
||||
return synchronizedTask.getWithTask (task -> {
|
||||
ExecutableElement methodElement = FindHelper.findMethod(task, className, methodName, erasedParameterTypes);
|
||||
MethodTree methodTree = Trees.instance(task.task).getTree(methodElement);
|
||||
if (methodTree.getThrows().size() == 1) {
|
||||
TextEdit delete = removeEntireThrows(task.task, task.root(), methodTree);
|
||||
if (delete == TextEdit.NONE) {
|
||||
return CANCELLED;
|
||||
}
|
||||
|
||||
TextEdit[] edits = {delete};
|
||||
return Collections.singletonMap (file, edits);
|
||||
}
|
||||
|
||||
TextEdit[] edits = {delete};
|
||||
TextEdit[] edits = {removeSingleException(task.task, task.root(), methodTree)};
|
||||
return Collections.singletonMap (file, edits);
|
||||
}
|
||||
TextEdit[] edits = {removeSingleException(task.task, task.root(), methodTree)};
|
||||
return Collections.singletonMap (file, edits);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.itsaky.lsp.java.CompileTask;
|
||||
import com.itsaky.lsp.java.CompilerProvider;
|
||||
import com.itsaky.lsp.java.utils.EditHelper;
|
||||
import com.itsaky.lsp.java.utils.FindHelper;
|
||||
import com.itsaky.lsp.java.utils.SynchronizedTask;
|
||||
import com.itsaky.lsp.models.TextEdit;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import com.sun.source.util.Trees;
|
||||
@@ -46,11 +47,13 @@ public class RemoveMethod implements Rewrite {
|
||||
if (file == CompilerProvider.NOT_FOUND) {
|
||||
return CANCELLED;
|
||||
}
|
||||
try (CompileTask task = compiler.compile(file)) {
|
||||
ExecutableElement methodElement = FindHelper.findMethod(task, className, methodName, erasedParameterTypes);
|
||||
MethodTree methodTree = Trees.instance(task.task).getTree(methodElement);
|
||||
TextEdit[] edits = {EditHelper.removeTree(task.task, task.root(), methodTree)};
|
||||
return Collections.singletonMap (file, edits);
|
||||
try (SynchronizedTask synchronizedTask = compiler.compile(file)) {
|
||||
return synchronizedTask.getWithTask (task -> {
|
||||
ExecutableElement methodElement = FindHelper.findMethod(task, className, methodName, erasedParameterTypes);
|
||||
MethodTree methodTree = Trees.instance(task.task).getTree(methodElement);
|
||||
TextEdit[] edits = {EditHelper.removeTree(task.task, task.root(), methodTree)};
|
||||
return Collections.singletonMap (file, edits);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.lsp.java.utils;
|
||||
|
||||
import com.itsaky.lsp.java.CompileTask;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
public class SynchronizedTask implements AutoCloseable {
|
||||
|
||||
private volatile CompileTask task;
|
||||
|
||||
public synchronized void runWithTask (Consumer<CompileTask> taskConsumer) {
|
||||
taskConsumer.accept (task);
|
||||
}
|
||||
|
||||
public synchronized <T> T getWithTask (Function<CompileTask, T> function) {
|
||||
return function.apply (task);
|
||||
}
|
||||
|
||||
public synchronized void setTask (CompileTask task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close () {
|
||||
if (task != null) {
|
||||
task.close ();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import com.sun.source.util.TreePathScanner;
|
||||
import com.sun.source.util.Trees;
|
||||
|
||||
public class FindCompletionsAt extends TreePathScanner<TreePath, Long> {
|
||||
|
||||
private final JavacTask task;
|
||||
private CompilationUnitTree root;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user