Ensure Rewrite java parser is cached where possible

This commit is contained in:
BoykoAlex
2022-08-04 14:56:37 -04:00
parent 1c3229f874
commit 7e43e28509
2 changed files with 58 additions and 28 deletions

View File

@@ -30,6 +30,7 @@ import org.openrewrite.TreeVisitor;
import org.openrewrite.internal.RecipeIntrospectionUtils;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.JavaParser;
import org.openrewrite.java.JavaParsingException;
import org.openrewrite.java.JavaVisitor;
import org.openrewrite.java.UpdateSourcePositions;
import org.openrewrite.java.tree.J;
@@ -219,7 +220,7 @@ public class ORAstUtils {
// }
public static List<CompilationUnit> parse(JavaParser parser, Iterable<Path> sourceFiles) {
InMemoryExecutionContext ctx = new InMemoryExecutionContext(e -> log.error("", e));
InMemoryExecutionContext ctx = new InMemoryExecutionContext(ORAstUtils::logExceptionWhileParsing);
// ctx.putMessage(JavaParser.SKIP_SOURCE_SET_TYPE_GENERATION, true);
List<CompilationUnit> cus = parser.parse(sourceFiles, null, ctx);
List<Result> results = new UpdateSourcePositions()/*.doNext(new MarkParentRecipe())*/.run(cus);
@@ -227,12 +228,19 @@ public class ORAstUtils {
}
public static List<CompilationUnit> parseInputs(JavaParser parser, Iterable<Parser.Input> inputs) {
InMemoryExecutionContext ctx = new InMemoryExecutionContext(e -> log.error("", e));
InMemoryExecutionContext ctx = new InMemoryExecutionContext(ORAstUtils::logExceptionWhileParsing);
// ctx.putMessage(JavaParser.SKIP_SOURCE_SET_TYPE_GENERATION, true);
List<CompilationUnit> cus = parser.parseInputs(inputs, null, ctx);
List<Result> results = new UpdateSourcePositions()/*.doNext(new MarkParentRecipe())*/.run(cus);
return results.stream().map(r -> r.getAfter() == null ? r.getBefore() : r.getAfter()).map(CompilationUnit.class::cast).collect(Collectors.toList());
}
private static void logExceptionWhileParsing(Throwable t) {
if (!(t instanceof JavaParsingException || t instanceof StringIndexOutOfBoundsException)) {
// Do not log parse exceptions. Can be too many while user is typing code
log.error("", t);
}
}
public static J.EnumValueSet getEnumValues(J.ClassDeclaration classDecl) {
return classDecl.getBody().getStatements().stream()

View File

@@ -48,6 +48,7 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.util.concurrent.UncheckedExecutionException;
import reactor.core.Disposable;
@@ -180,10 +181,14 @@ public class RewriteCompilationUnitCache implements DocumentContentProvider, Dis
uriToCu.invalidate(uri);
Optional<IJavaProject> project = projectFinder.find(new TextDocumentIdentifier(uriStr));
if (project.isPresent()) {
JavaParser parser = javaParsers.getIfPresent(project.get());
if (parser != null) {
parser.reset();
}
//TODO There seems to be an issue with java parser #reset() call. After resetting it
// still complains that it needs to be reset
// JavaParser parser = javaParsers.getIfPresent(project.get());
// if (parser != null) {
// parser.reset();
// }
javaParsers.invalidate(project.get());
}
}
}
@@ -217,33 +222,50 @@ public class RewriteCompilationUnitCache implements DocumentContentProvider, Dis
try {
if (project != null) {
synchronized (URI_TO_CU_LOCK) {
return uriToCu.get(uri, () -> {
logger.debug("Parsing CU {}", uri);
JavaParser javaParser = /*loadJavaParser(project)*/createJavaParser(project);
Input input = new Input(Paths.get(uri), () -> {
try {
return uriToCu.get(uri, () -> {
boolean newParser = javaParsers.getIfPresent(project) == null;
try {
return new ByteArrayInputStream(fetchContent(uri).getBytes());
logger.debug("Parsing CU {}", uri);
JavaParser javaParser = loadJavaParser(project);
Input input = new Input(Paths.get(uri), () -> {
try {
return new ByteArrayInputStream(fetchContent(uri).getBytes());
} catch (Exception e) {
throw new IllegalStateException("Unexpected error fetching document content");
}
});
List<CompilationUnit> cus = ORAstUtils.parseInputs(javaParser, List.of(input));
CompilationUnit cu = cus.get(0);
if (cu != null) {
projectToDocs.get(project, () -> new HashSet<>()).add(uri);
return cu;
} else {
throw new IllegalStateException("Failed to parse Java source");
}
} catch (Exception e) {
throw new IllegalStateException("Unexpected error fetching document content");
if (newParser) {
javaParsers.invalidate(project);
}
throw e;
}
});
CompilationUnit cu = null;
try {
List<CompilationUnit> cus = ORAstUtils.parseInputs(javaParser, List.of(input));
cu = cus.get(0);
if (cu != null) {
projectToDocs.get(project, () -> new HashSet<>()).add(uri);
}
} catch (Exception e) {
// ignore rewrite parse errors
});
} catch (UncheckedExecutionException e1) {
if (e1.getCause() instanceof IllegalStateException) {
logger.error("", e1);
} else {
// ignore errors from rewrite parser. There could be many parser exceptions due to
// user incrementally typing code's text
}
return cu;
});
return null;
} catch (Exception e) {
logger.error("", e);
return null;
}
}
}
} catch (Exception e) {