diff --git a/README.md b/README.md index 9a79b58c..8912eee6 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ On newer Java version you'd perhaps want to pass in the following option: -Arewrite.generatedAnnotation=jakarta.annotation.Generated ``` -### Use JavaParser.Builder `.classpathFromResources(ctx, "guava")` +### Use JavaParser.Builder `.classpathFromResources(ctx, "guava-31")` By default, the annotation processor will use `JavaParser.runtimeClasspath()` to resolve the classpath for newly generated Java code snippets. If you want to use `TypeTables` from `src/main/resources/META-INF/rewrite/classpath.tsv.gz` instead, pass in the following option: ``` diff --git a/build.gradle.kts b/build.gradle.kts index 613a0a94..20bee57b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -115,6 +115,20 @@ tasks.named("compileTestJava") { }) sourceCompatibility = JavaVersion.VERSION_21.toString() targetCompatibility = JavaVersion.VERSION_21.toString() + + options.compilerArgs.addAll( + listOf( + "--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED" + ) + ) } tasks.withType().configureEach { @@ -122,7 +136,17 @@ tasks.withType().configureEach { javaLauncher.set(javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(21)) }) - jvmArgs("--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED") + jvmArgs( + "--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED" + ) } tasks.withType().configureEach { diff --git a/src/main/java/org/openrewrite/java/template/internal/ClasspathJarNameDetector.java b/src/main/java/org/openrewrite/java/template/internal/ClasspathJarNameDetector.java index 473aa738..51f9b609 100644 --- a/src/main/java/org/openrewrite/java/template/internal/ClasspathJarNameDetector.java +++ b/src/main/java/org/openrewrite/java/template/internal/ClasspathJarNameDetector.java @@ -16,19 +16,20 @@ package org.openrewrite.java.template.internal; import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.code.Type; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCFieldAccess; import com.sun.tools.javac.tree.TreeScanner; import org.jspecify.annotations.Nullable; import javax.tools.JavaFileObject; -import java.util.Collection; import java.util.LinkedHashSet; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class ClasspathJarNameDetector { +public class ClasspathJarNameDetector extends TreeScanner { + private final Set jarNames = new LinkedHashSet<>(); /** * Locate types that are directly referred to by name in the @@ -36,37 +37,13 @@ public class ClasspathJarNameDetector { * * @return The list of imports to add. */ - public static Set classpathFor(JCTree input, Collection imports) { - Set jarNames = new LinkedHashSet() { - @Override - public boolean add(@Nullable String s) { - return s != null && super.add(s); - } - }; - - for (Symbol anImport : imports) { - jarNames.add(jarNameFor(anImport)); - } - - new TreeScanner() { - @Override - public void scan(JCTree tree) { - // Detect fully qualified classes - if (tree instanceof JCFieldAccess && - ((JCFieldAccess) tree).sym instanceof Symbol.ClassSymbol && - Character.isUpperCase(((JCFieldAccess) tree).getIdentifier().toString().charAt(0))) { - jarNames.add(jarNameFor(((JCFieldAccess) tree).sym)); - } - super.scan(tree); - } - }.scan(input); - + public Set classpathFor(JCTree input) { + scan(input); return jarNames; } - - private static @Nullable String jarNameFor(Symbol anImport) { - Symbol.ClassSymbol enclClass = anImport instanceof Symbol.ClassSymbol ? (Symbol.ClassSymbol) anImport : anImport.enclClass(); + private void addJarNameFor(Symbol owner) { + Symbol.ClassSymbol enclClass = owner instanceof Symbol.ClassSymbol ? (Symbol.ClassSymbol) owner : owner.enclClass(); while (enclClass.enclClass() != null && enclClass.enclClass() != enclClass) { enclClass = enclClass.enclClass(); } @@ -75,10 +52,94 @@ public void scan(JCTree tree) { String uriStr = classfile.toUri().toString(); Matcher matcher = Pattern.compile("([^/]*)?\\.jar!/").matcher(uriStr); if (matcher.find()) { - String jarName = matcher.group(1); - return jarName.replaceAll("-\\d.*$", ""); + String jarName = matcher.group(1) + // Retain major version number, to avoid `log4j` conflict between `log4j-1` and `log4j2-1` + .replaceFirst("(-\\d+).*?$", "$1"); + jarNames.add(jarName); } } - return null; } + + @Override + public void scan(JCTree tree) { + // Detect fully qualified classes + if (tree instanceof JCFieldAccess && + ((JCFieldAccess) tree).sym instanceof Symbol.ClassSymbol && + Character.isUpperCase(((JCFieldAccess) tree).getIdentifier().toString().charAt(0))) { + addJarNameFor(((JCFieldAccess) tree).sym); + } + + // Detect method invocations and their types + if (tree instanceof JCTree.JCMethodInvocation) { + JCTree.JCMethodInvocation invocation = (JCTree.JCMethodInvocation) tree; + Symbol.MethodSymbol methodSym = null; + + if (invocation.meth instanceof JCFieldAccess) { + JCFieldAccess methodAccess = (JCFieldAccess) invocation.meth; + if (methodAccess.sym instanceof Symbol.MethodSymbol) { + methodSym = (Symbol.MethodSymbol) methodAccess.sym; + } + } else if (invocation.meth instanceof JCTree.JCIdent) { + // Handle unqualified method calls (e.g., from static imports) + JCTree.JCIdent methodIdent = (JCTree.JCIdent) invocation.meth; + if (methodIdent.sym instanceof Symbol.MethodSymbol) { + methodSym = (Symbol.MethodSymbol) methodIdent.sym; + } + } + + if (methodSym != null) { + // Add jar for the method's owner class + addJarNameFor(methodSym.owner); + + // Add jar for the return type + if (methodSym.getReturnType() != null) { + addTypeAndTransitiveDependencies(methodSym.getReturnType()); + } + + // Add jars for exception types + for (Type thrownType : methodSym.getThrownTypes()) { + addTypeAndTransitiveDependencies(thrownType); + } + } + } + + // Detect identifiers that reference classes + if (tree instanceof JCTree.JCIdent) { + JCTree.JCIdent ident = (JCTree.JCIdent) tree; + if (ident.sym instanceof Symbol.ClassSymbol) { + Symbol.ClassSymbol classSym = (Symbol.ClassSymbol) ident.sym; + addJarNameFor(classSym); + + // Add transitive dependencies through inheritance + addTypeAndTransitiveDependencies(classSym.type); + } + } + + super.scan(tree); + } + + private void addTypeAndTransitiveDependencies(@Nullable Type type) { + if (type == null) { + return; + } + + if (type.tsym instanceof Symbol.ClassSymbol) { + Symbol.ClassSymbol classSym = (Symbol.ClassSymbol) type.tsym; + addJarNameFor(classSym); + + // Check superclass + Type superType = classSym.getSuperclass(); + if (superType != null && superType.tsym != null) { + addJarNameFor(superType.tsym); + } + + // Check interfaces + for (Type iface : classSym.getInterfaces()) { + if (iface.tsym != null) { + addJarNameFor(iface.tsym); + } + } + } + } + } diff --git a/src/main/java/org/openrewrite/java/template/internal/ImportDetector.java b/src/main/java/org/openrewrite/java/template/internal/ImportDetector.java index 31c0832f..0228f7ac 100644 --- a/src/main/java/org/openrewrite/java/template/internal/ImportDetector.java +++ b/src/main/java/org/openrewrite/java/template/internal/ImportDetector.java @@ -43,26 +43,10 @@ public static Collection imports(JCTree.JCMethodDecl methodDecl) { public static Collection imports(JCTree.JCMethodDecl methodDecl, Predicate scopePredicate) { ImportScanner importScanner = new ImportScanner(scopePredicate); + methodDecl.getParameters().forEach(importScanner::scan); + methodDecl.getTypeParameters().forEach(importScanner::scan); importScanner.scan(methodDecl.getBody()); importScanner.scan(methodDecl.getReturnType()); - for (JCTree.JCVariableDecl param : methodDecl.getParameters()) { - importScanner.scan(param); - } - for (JCTree.JCTypeParameter param : methodDecl.getTypeParameters()) { - importScanner.scan(param); - } - return importScanner.imports; - } - - /** - * Locate types that are directly referred to by name in the - * given tree and therefore need an import in the template. - * - * @return The list of imports to add. - */ - public static Collection imports(JCTree tree) { - ImportScanner importScanner = new ImportScanner(t -> true); - importScanner.scan(tree); return importScanner.imports; } diff --git a/src/main/java/org/openrewrite/java/template/internal/TemplateCode.java b/src/main/java/org/openrewrite/java/template/internal/TemplateCode.java index 30eb4407..4bef1fba 100644 --- a/src/main/java/org/openrewrite/java/template/internal/TemplateCode.java +++ b/src/main/java/org/openrewrite/java/template/internal/TemplateCode.java @@ -70,10 +70,9 @@ public static String process( if (!printer.staticImports.isEmpty()) { builder.append("\n .staticImports(").append(printer.staticImports.stream().map(i -> '"' + i + '"').collect(joining(", "))).append(")"); } - Set jarNames = ClasspathJarNameDetector.classpathFor(tree, ImportDetector.imports(tree)); - for (JCTree.JCVariableDecl parameter : parameters) { - jarNames.addAll(ClasspathJarNameDetector.classpathFor(parameter, ImportDetector.imports(parameter))); - } + ClasspathJarNameDetector classpathJarNameDetector = new ClasspathJarNameDetector(); + parameters.forEach(classpathJarNameDetector::classpathFor); + Set jarNames = classpathJarNameDetector.classpathFor(tree); if (!jarNames.isEmpty()) { builder.append("\n .javaParser(JavaParser.fromJavaVersion()"); if (classpathFromResources) { diff --git a/src/test/java/org/openrewrite/java/template/RefasterTemplateProcessorTest.java b/src/test/java/org/openrewrite/java/template/RefasterTemplateProcessorTest.java index 0234bd18..aafa09ad 100644 --- a/src/test/java/org/openrewrite/java/template/RefasterTemplateProcessorTest.java +++ b/src/test/java/org/openrewrite/java/template/RefasterTemplateProcessorTest.java @@ -46,6 +46,7 @@ class RefasterTemplateProcessorTest { @ValueSource(strings = { "Arrays", "CharacterEscapeAnnotation", + "ClasspathFromResourcesTransitive", "ComplexGenerics", "FindListAdd", "MatchOrder", @@ -174,8 +175,10 @@ static Compilation compile(JavaFileObject javaFileObject, TypeAwareProcessor pro fileForClass(BeforeTemplate.class), fileForClass(AfterTemplate.class), fileForClass(com.google.common.collect.ImmutableMap.class), + fileForClass(org.junit.jupiter.api.Assertions.class), fileForClass(org.openrewrite.Recipe.class), fileForClass(org.openrewrite.java.JavaTemplate.class), + fileForClass(org.opentest4j.MultipleFailuresError.class), fileForClass(org.slf4j.Logger.class), fileForClass(Primitive.class), fileForClass(NullMarked.class), diff --git a/src/test/java/org/openrewrite/java/template/internal/ClasspathJarNameDetectorTest.java b/src/test/java/org/openrewrite/java/template/internal/ClasspathJarNameDetectorTest.java new file mode 100644 index 00000000..4058263f --- /dev/null +++ b/src/test/java/org/openrewrite/java/template/internal/ClasspathJarNameDetectorTest.java @@ -0,0 +1,164 @@ +/* + * Copyright 2025 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.template.internal; + +import com.sun.source.util.JavacTask; +import com.sun.tools.javac.api.JavacTool; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.api.Test; + +import javax.tools.*; +import java.io.IOException; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.Set; + +import static com.google.common.truth.Truth.assertThat; +import static java.util.Collections.singletonList; + +class ClasspathJarNameDetectorTest { + + @Test + void detectsJarNamesFromImports() throws IOException { + Set jarNames = classpathForSource(""" + import java.util.List; + import java.util.ArrayList; + class Test { + List list = new ArrayList<>(); + } + """); + + // JDK classes should not be included in the jar names + assertThat(jarNames).isEmpty(); + } + + @Test + void detectJUnit() throws IOException { + Set jarNames = classpathForSource(""" + import org.junit.jupiter.api.Test; + import org.junit.jupiter.api.Assertions; + class TestClass { + @Test + void testMethod() { + Assertions.assertEquals(1, 1); + } + } + """); + + assertThat(jarNames).containsExactly("junit-jupiter-api-5"); + } + + @Test + void detectJUnitAndOpenTest4J() throws IOException { + Set jarNames = classpathForSource(""" + import org.junit.jupiter.api.Test; + import org.junit.jupiter.api.Assertions; + class TestClass { + @Test + void testMethod() { + Assertions.assertAll("This throws org.opentest4j.MultipleFailuresError"); + } + } + """); + + assertThat(jarNames).containsExactly("junit-jupiter-api-5", "opentest4j-1"); + } + + @Test + void detectJUnitAndOpenTest4JFromStatement() throws IOException { + JCCompilationUnit compilationUnit = compile(""" + import org.junit.jupiter.api.Assertions; + class TestClass { + void testMethod() { + Assertions.assertAll("heading"); + } + } + """); + + Set jarNames = classpathForTree(firstStatement(compilationUnit)); + + // assertAll throws an exception that is defined in opentest4j, so we need both junit-jupiter-api and opentest4j + assertThat(jarNames).containsExactly("junit-jupiter-api-5", "opentest4j-1"); + } + + @Test + void detectTransitiveDependencyThroughInheritance() throws IOException { + JCCompilationUnit compilationUnit = compile(""" + import org.openrewrite.java.JavaVisitor; + class TestClass { + void testMethod() { + String language = new JavaVisitor<>().getLanguage(); + } + } + """); + + Set jarNames = classpathForTree(firstStatement(compilationUnit)); + + // JavaVisitor from rewrite-java extends TreeVisitor from rewrite-core, both are needed + assertThat(jarNames).containsExactly("rewrite-java-8", "rewrite-core-8"); + } + + private static JCTree.JCStatement firstStatement(JCCompilationUnit compilationUnit) { + // Just the first statement of the method body, not the complete compilation unit, just like the processor does + JCTree.JCClassDecl classDecl = (JCTree.JCClassDecl) compilationUnit.getTypeDecls().getFirst(); + JCTree.JCMethodDecl methodDecl = classDecl.getMembers().stream() + .filter(JCTree.JCMethodDecl.class::isInstance) + .map(JCTree.JCMethodDecl.class::cast) + .filter(member -> !member.sym.isConstructor()) + .findFirst() + .orElseThrow(); + return methodDecl.body.getStatements().getFirst(); + } + + private Set classpathForSource(@Language("java") String source) throws IOException { + return classpathForTree(compile(source).getTypeDecls().getFirst()); + } + + private static Set classpathForTree(JCTree first) { + return new ClasspathJarNameDetector().classpathFor(first); + } + + private static JCCompilationUnit compile(@Language("java") String source) throws IOException { + JavaCompiler compiler = JavacTool.create(); + DiagnosticCollector diagnostics = new DiagnosticCollector<>(); + try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, StandardCharsets.UTF_8)) { + JavaFileObject sourceFile = new SimpleJavaFileObject( + URI.create("string:///Test.java"), + JavaFileObject.Kind.SOURCE) { + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return source; + } + }; + + JavacTask task = (JavacTask) compiler.getTask( + null, + fileManager, + diagnostics, + singletonList("-proc:none"), + null, + singletonList(sourceFile)); + + @SuppressWarnings("unchecked") + Iterable compilationUnits = (Iterable) task.parse(); + task.analyze(); + + return compilationUnits.iterator().next(); + } + } +} diff --git a/src/test/resources/refaster/ClasspathFromResourcesTransitive.java b/src/test/resources/refaster/ClasspathFromResourcesTransitive.java new file mode 100644 index 00000000..22be3b40 --- /dev/null +++ b/src/test/resources/refaster/ClasspathFromResourcesTransitive.java @@ -0,0 +1,27 @@ +/* + * Copyright 2025 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package foo; + +import com.google.errorprone.refaster.annotation.AfterTemplate; +import com.google.errorprone.refaster.annotation.BeforeTemplate; +import org.openrewrite.java.JavaVisitor; + +public class ClasspathFromResourcesTransitive { + @BeforeTemplate + String before(JavaVisitor visitor) { + return visitor.getLanguage(); + } +} diff --git a/src/test/resources/refaster/ClasspathFromResourcesTransitiveRecipe.java b/src/test/resources/refaster/ClasspathFromResourcesTransitiveRecipe.java new file mode 100644 index 00000000..79736aee --- /dev/null +++ b/src/test/resources/refaster/ClasspathFromResourcesTransitiveRecipe.java @@ -0,0 +1,91 @@ +/* + * Copyright 2025 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package foo; + +import org.jspecify.annotations.NullMarked; +import org.openrewrite.ExecutionContext; +import org.openrewrite.Preconditions; +import org.openrewrite.Recipe; +import org.openrewrite.TreeVisitor; +import org.openrewrite.java.JavaParser; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.JavaVisitor; +import org.openrewrite.java.search.*; +import org.openrewrite.java.template.Primitive; +import org.openrewrite.java.template.function.*; +import org.openrewrite.java.template.internal.AbstractRefasterJavaVisitor; +import org.openrewrite.java.tree.*; +import org.openrewrite.marker.SearchResult; + +import javax.annotation.Generated; +import java.util.*; + +import static org.openrewrite.java.template.internal.AbstractRefasterJavaVisitor.EmbeddingOption.*; + +/** + * OpenRewrite recipe created for Refaster template {@code ClasspathFromResourcesTransitive}. + */ +@SuppressWarnings("all") +@NullMarked +@Generated("org.openrewrite.java.template.processor.RefasterTemplateProcessor") +public class ClasspathFromResourcesTransitiveRecipe extends Recipe { + + /** + * Instantiates a new instance. + */ + public ClasspathFromResourcesTransitiveRecipe() {} + + @Override + public String getDisplayName() { + //language=markdown + return "Refaster template `ClasspathFromResourcesTransitive`"; + } + + @Override + public String getDescription() { + //language=markdown + return "Recipe created for the following Refaster template:\n```java\npublic class ClasspathFromResourcesTransitive {\n \n @BeforeTemplate\n String before(JavaVisitor visitor) {\n return visitor.getLanguage();\n }\n}\n```\n."; + } + + @Override + public TreeVisitor getVisitor() { + JavaVisitor javaVisitor = new AbstractRefasterJavaVisitor() { + JavaTemplate before; + @Override + public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) { + JavaTemplate.Matcher matcher; + if (before == null) { + before = JavaTemplate.builder("#{visitor:any(org.openrewrite.java.JavaVisitor)}.getLanguage()") + .bindType("java.lang.String") + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "rewrite-java-8", "rewrite-core-8")) + .build(); + } + if ((matcher = before.matcher(getCursor())).find()) { + return SearchResult.found(elem); + } + return super.visitMethodInvocation(elem, ctx); + } + + }; + return Preconditions.check( + Preconditions.and( + new UsesType<>("org.openrewrite.java.JavaVisitor", true), + new UsesMethod<>("org.openrewrite.java.JavaVisitor getLanguage(..)", true) + ), + javaVisitor + ); + } +} diff --git a/src/test/resources/refaster/EscapesRecipes.java b/src/test/resources/refaster/EscapesRecipes.java index fb210eae..87f7cb1e 100644 --- a/src/test/resources/refaster/EscapesRecipes.java +++ b/src/test/resources/refaster/EscapesRecipes.java @@ -102,14 +102,14 @@ public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) { if (before == null) { before = JavaTemplate.builder("String.format(\"\\\"%s\\\"\", com.google.common.base.Strings.nullToEmpty(#{value:any(java.lang.String)}))") .bindType("java.lang.String") - .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava")) + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava-31")) .build(); } if ((matcher = before.matcher(getCursor())).find()) { if (after == null) { after = JavaTemplate.builder("com.google.common.base.Strings.lenientFormat(#{value:any(java.lang.String)})") .bindType("java.lang.String") - .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava")) + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava-31")) .build(); } return embed( diff --git a/src/test/resources/refaster/GenericsRecipes.java b/src/test/resources/refaster/GenericsRecipes.java index ad63615b..cbb8943a 100644 --- a/src/test/resources/refaster/GenericsRecipes.java +++ b/src/test/resources/refaster/GenericsRecipes.java @@ -355,7 +355,9 @@ public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) { JavaTemplate.Matcher matcher; if (before == null) { before = JavaTemplate.builder("#{a:any(java.util.List)}.equals(#{b:any(java.util.List)})") - .genericTypes("T extends java.lang.Number").build(); + .genericTypes("T extends java.lang.Number") + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "jspecify-1")) + .build(); } if ((matcher = before.matcher(getCursor())).find()) { return SearchResult.found(elem); diff --git a/src/test/resources/refaster/NoGuavaRefasterRecipes.java b/src/test/resources/refaster/NoGuavaRefasterRecipes.java index 1d9dfd2e..daece379 100644 --- a/src/test/resources/refaster/NoGuavaRefasterRecipes.java +++ b/src/test/resources/refaster/NoGuavaRefasterRecipes.java @@ -103,7 +103,7 @@ public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) { if (before == null) { before = JavaTemplate.builder("com.google.common.base.Preconditions.checkNotNull(#{object:any(java.lang.Object)})") .bindType("java.lang.Object") - .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava")) + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava-31")) .build(); } if ((matcher = before.matcher(getCursor())).find()) { @@ -170,7 +170,7 @@ public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) { if (before == null) { before = JavaTemplate.builder("com.google.common.base.Preconditions.checkNotNull(#{object:any(java.lang.Object)}, #{message:any(java.lang.String)})") .bindType("java.lang.Object") - .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava")) + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava-31")) .build(); } if ((matcher = before.matcher(getCursor())).find()) { @@ -237,7 +237,7 @@ public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) { if (before == null) { before = JavaTemplate.builder("com.google.common.base.Preconditions.checkNotNull(#{object:any(java.lang.Object)}, #{message:any(java.lang.Object)})") .bindType("java.lang.Object") - .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava")) + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava-31")) .build(); } if ((matcher = before.matcher(getCursor())).find()) { diff --git a/src/test/resources/refaster/ParametersRecipes.java b/src/test/resources/refaster/ParametersRecipes.java index 38b68aa0..478ca2e1 100644 --- a/src/test/resources/refaster/ParametersRecipes.java +++ b/src/test/resources/refaster/ParametersRecipes.java @@ -102,11 +102,15 @@ public TreeVisitor getVisitor() { public J visitBinary(J.Binary elem, ExecutionContext ctx) { JavaTemplate.Matcher matcher; if (before == null) { - before = JavaTemplate.builder("#{s:any(java.lang.String)} == #{s}").build(); + before = JavaTemplate.builder("#{s:any(java.lang.String)} == #{s}") + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "jspecify-1")) + .build(); } if ((matcher = before.matcher(getCursor())).find()) { if (after == null) { - after = JavaTemplate.builder("#{s:any(java.lang.String)}.equals(#{s})").build(); + after = JavaTemplate.builder("#{s:any(java.lang.String)}.equals(#{s})") + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "jspecify-1")) + .build(); } return embed( after.apply(getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)), @@ -157,11 +161,15 @@ public TreeVisitor getVisitor() { public J visitBinary(J.Binary elem, ExecutionContext ctx) { JavaTemplate.Matcher matcher; if (before == null) { - before = JavaTemplate.builder("#{s:any(java.lang.String[])} == #{s}").build(); + before = JavaTemplate.builder("#{s:any(java.lang.String[])} == #{s}") + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "jspecify-1")) + .build(); } if ((matcher = before.matcher(getCursor())).find()) { if (after == null) { - after = JavaTemplate.builder("#{s:any(java.lang.String[])}.equals(#{s})").build(); + after = JavaTemplate.builder("#{s:any(java.lang.String[])}.equals(#{s})") + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "jspecify-1")) + .build(); } return embed( after.apply(getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)), diff --git a/src/test/resources/refaster/PreconditionsVerifierRecipes.java b/src/test/resources/refaster/PreconditionsVerifierRecipes.java index 9abff430..6ce12009 100644 --- a/src/test/resources/refaster/PreconditionsVerifierRecipes.java +++ b/src/test/resources/refaster/PreconditionsVerifierRecipes.java @@ -182,14 +182,14 @@ public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) { if (before == null) { before = JavaTemplate.builder("com.google.common.base.Strings.nullToEmpty(#{value:any(java.lang.String)})") .bindType("java.lang.String") - .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava")) + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava-31")) .build(); } if ((matcher = before.matcher(getCursor())).find()) { if (after == null) { after = JavaTemplate.builder("com.google.common.base.Strings.nullToEmpty(String.valueOf(#{value:any(java.lang.Object)}))") .bindType("java.lang.Object") - .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava")) + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava-31")) .build(); } return embed( @@ -207,7 +207,7 @@ public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) { if (after == null) { after = JavaTemplate.builder("com.google.common.base.Strings.nullToEmpty(String.valueOf(#{value:any(java.lang.Object)}))") .bindType("java.lang.Object") - .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava")) + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava-31")) .build(); } return embed( @@ -272,14 +272,14 @@ public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) { if (before == null) { before = JavaTemplate.builder("com.google.common.base.Strings.nullToEmpty(#{value:any(java.lang.String)})") .bindType("java.lang.String") - .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava")) + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava-31")) .build(); } if ((matcher = before.matcher(getCursor())).find()) { if (after == null) { after = JavaTemplate.builder("com.google.common.base.Strings.nullToEmpty(String.valueOf(#{value:any(java.lang.Object)}))") .bindType("java.lang.Object") - .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava")) + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava-31")) .build(); } return embed( @@ -292,14 +292,14 @@ public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) { if (before0 == null) { before0 = JavaTemplate.builder("com.google.common.base.Strings.nullToEmpty(String.valueOf(#{value:any(int)}))") .bindType("java.lang.String") - .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava")) + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava-31")) .build(); } if ((matcher = before0.matcher(getCursor())).find()) { if (after == null) { after = JavaTemplate.builder("com.google.common.base.Strings.nullToEmpty(String.valueOf(#{value:any(java.lang.Object)}))") .bindType("java.lang.Object") - .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava")) + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "guava-31")) .build(); } return embed( diff --git a/src/test/resources/template/LoggerRecipeFromResources$1_info.java b/src/test/resources/template/LoggerRecipeFromResources$1_info.java index 168d404d..8442b043 100644 --- a/src/test/resources/template/LoggerRecipeFromResources$1_info.java +++ b/src/test/resources/template/LoggerRecipeFromResources$1_info.java @@ -25,6 +25,6 @@ public class LoggerRecipeFromResources$1_info { public static JavaTemplate.Builder getTemplate(ExecutionContext ctx) { return JavaTemplate .builder("#{l:any(org.slf4j.Logger)}.info(#{s:any(java.lang.String)})") - .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "slf4j-api")); + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "slf4j-api-2")); } } diff --git a/src/test/resources/template/LoggerRecipeFromResources$1_logger.java b/src/test/resources/template/LoggerRecipeFromResources$1_logger.java index 740dfd85..aa5fe5f9 100644 --- a/src/test/resources/template/LoggerRecipeFromResources$1_logger.java +++ b/src/test/resources/template/LoggerRecipeFromResources$1_logger.java @@ -27,6 +27,6 @@ public static JavaTemplate.Builder getTemplate(ExecutionContext ctx) { return JavaTemplate .builder("LoggerFactory.getLogger(#{s:any(java.lang.String)})") .imports("org.slf4j.LoggerFactory") - .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "slf4j-api")); + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "slf4j-api-2")); } }