Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions src/main/java/org/openrewrite/java/template/Semantics.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package org.openrewrite.java.template;

import org.openrewrite.ExecutionContext;
import org.openrewrite.java.JavaTemplate;
import org.openrewrite.java.JavaVisitor;
import org.openrewrite.java.template.function.*;
Expand Down Expand Up @@ -112,4 +113,94 @@ public static JavaTemplate.Builder statement(JavaVisitor<?> owner, String name,
public static JavaTemplate.Builder statement(JavaVisitor<?> owner, String name, Stat10<?, ?, ?, ?, ?, ?, ?, ?, ?, ?> p) {
return new PatternBuilder(name).build(owner);
}

// Again, but with a first ExecutionContext argument for JavaParser classpathFromResources

public static JavaTemplate.Builder expression(ExecutionContext ctx, JavaVisitor<?> owner, String name, Expr0<?> f) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder expression(ExecutionContext ctx, JavaVisitor<?> owner, String name, Expr1<?, ?> f) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder expression(ExecutionContext ctx, JavaVisitor<?> owner, String name, Expr2<?, ?, ?> f) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder expression(ExecutionContext ctx, JavaVisitor<?> owner, String name, Expr3<?, ?, ?, ?> f) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder expression(ExecutionContext ctx, JavaVisitor<?> owner, String name, Expr4<?, ?, ?, ?, ?> f) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder expression(ExecutionContext ctx, JavaVisitor<?> owner, String name, Expr5<?, ?, ?, ?, ?, ?> f) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder expression(ExecutionContext ctx, JavaVisitor<?> owner, String name, Expr6<?, ?, ?, ?, ?, ?, ?> f) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder expression(ExecutionContext ctx, JavaVisitor<?> owner, String name, Expr7<?, ?, ?, ?, ?, ?, ?, ?> f) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder expression(ExecutionContext ctx, JavaVisitor<?> owner, String name, Expr8<?, ?, ?, ?, ?, ?, ?, ?, ?> f) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder expression(ExecutionContext ctx, JavaVisitor<?> owner, String name, Expr9<?, ?, ?, ?, ?, ?, ?, ?, ?, ?> f) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder expression(ExecutionContext ctx, JavaVisitor<?> owner, String name, Expr10<?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?> f) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder statement(ExecutionContext ctx, JavaVisitor<?> owner, String name, Stat0 p) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder statement(ExecutionContext ctx, JavaVisitor<?> owner, String name, Stat1<?> p) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder statement(ExecutionContext ctx, JavaVisitor<?> owner, String name, Stat2<?, ?> p) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder statement(ExecutionContext ctx, JavaVisitor<?> owner, String name, Stat3<?, ?, ?> p) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder statement(ExecutionContext ctx, JavaVisitor<?> owner, String name, Stat4<?, ?, ?, ?> p) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder statement(ExecutionContext ctx, JavaVisitor<?> owner, String name, Stat5<?, ?, ?, ?, ?> p) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder statement(ExecutionContext ctx, JavaVisitor<?> owner, String name, Stat6<?, ?, ?, ?, ?, ?> p) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder statement(ExecutionContext ctx, JavaVisitor<?> owner, String name, Stat7<?, ?, ?, ?, ?, ?, ?> p) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder statement(ExecutionContext ctx, JavaVisitor<?> owner, String name, Stat8<?, ?, ?, ?, ?, ?, ?, ?> p) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder statement(ExecutionContext ctx, JavaVisitor<?> owner, String name, Stat9<?, ?, ?, ?, ?, ?, ?, ?, ?> p) {
return new PatternBuilder(name).build(ctx, owner);
}

public static JavaTemplate.Builder statement(ExecutionContext ctx, JavaVisitor<?> owner, String name, Stat10<?, ?, ?, ?, ?, ?, ?, ?, ?, ?> p) {
return new PatternBuilder(name).build(ctx, owner);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
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.LinkedHashSet;
Expand All @@ -38,7 +39,7 @@ public class ClasspathJarNameDetector {
public static Set<String> classpathFor(JCTree input, List<Symbol> imports) {
Set<String> jarNames = new LinkedHashSet<String>() {
@Override
public boolean add(String s) {
public boolean add(@Nullable String s) {
return s != null && super.add(s);
}
};
Expand All @@ -47,13 +48,13 @@ public boolean add(String s) {
jarNames.add(jarNameFor(anImport));
}

// Detect fully qualified classes
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))) {
((JCFieldAccess) tree).sym instanceof Symbol.ClassSymbol &&
Character.isUpperCase(((JCFieldAccess) tree).getIdentifier().toString().charAt(0))) {
jarNames.add(jarNameFor(((JCFieldAccess) tree).sym));
}
super.scan(tree);
Expand All @@ -64,7 +65,7 @@ public void scan(JCTree tree) {
}


private static String jarNameFor(Symbol anImport) {
private static @Nullable String jarNameFor(Symbol anImport) {
Symbol.ClassSymbol enclClass = anImport instanceof Symbol.ClassSymbol ? (Symbol.ClassSymbol) anImport : anImport.enclClass();
while (enclClass.enclClass() != null && enclClass.enclClass() != enclClass) {
enclClass = enclClass.enclClass();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.openrewrite.java.template.internal;

import lombok.Value;
import org.openrewrite.ExecutionContext;
import org.openrewrite.java.JavaTemplate;
import org.openrewrite.java.JavaVisitor;

Expand All @@ -38,4 +39,16 @@ public JavaTemplate.Builder build(JavaVisitor<?> owner) {
throw new RuntimeException(e);
}
}

public JavaTemplate.Builder build(ExecutionContext ctx, JavaVisitor<?> owner) {
try {
Class<?> templateClass = Class.forName(owner.getClass().getName() + "_" + name, true,
owner.getClass().getClassLoader());
Method getTemplate = templateClass.getDeclaredMethod("getTemplate", ExecutionContext.class);
return (JavaTemplate.Builder) getTemplate.invoke(null, ctx);
} catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException |
IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,15 @@

public class TemplateCode {

public static <T extends JCTree> String process(T tree, @Nullable Type returnType, List<JCTree.JCVariableDecl> parameters, List<JCTree.JCTypeParameter> typeParameters, int pos, boolean asStatement, boolean fullyQualified) {
public static <T extends JCTree> String process(
T tree,
@Nullable Type returnType,
List<JCTree.JCVariableDecl> parameters,
List<JCTree.JCTypeParameter> typeParameters,
int pos,
boolean asStatement,
boolean fullyQualified,
boolean classpathFromResources) {
StringWriter writer = new StringWriter();
TemplateCodePrinter printer = new TemplateCodePrinter(writer, parameters, pos, fullyQualified);
try {
Expand All @@ -62,18 +70,18 @@ public static <T extends JCTree> String process(T tree, @Nullable Type returnTyp
if (!printer.staticImports.isEmpty()) {
builder.append("\n .staticImports(").append(printer.staticImports.stream().map(i -> '"' + i + '"').collect(joining(", "))).append(")");
}
List<Symbol> imports = ImportDetector.imports(tree);
Set<String> jarNames = ClasspathJarNameDetector.classpathFor(tree, imports);
Set<String> jarNames = ClasspathJarNameDetector.classpathFor(tree, ImportDetector.imports(tree));
for (JCTree.JCVariableDecl parameter : parameters) {
jarNames.addAll(ClasspathJarNameDetector.classpathFor(parameter, ImportDetector.imports(parameter)));
}
if (!jarNames.isEmpty()) {
// It might be preferable to enumerate exactly the needed dependencies rather than the full classpath
// But this is expedient
// See https://github.com/openrewrite/rewrite-templating/issues/86
// String classpath = jarNames.stream().map(jarName -> '"' + jarName + '"').sorted().collect(joining(", "));
// builder.append("\n .javaParser(JavaParser.fromJavaVersion().classpath(").append(classpath).append("))");
builder.append("\n .javaParser(JavaParser.fromJavaVersion().classpath(JavaParser.runtimeClasspath()))");
builder.append("\n .javaParser(JavaParser.fromJavaVersion()");
if (classpathFromResources) {
String joinedJarNames = jarNames.stream().collect(joining("\", \"", "\"", "\""));
builder.append(".classpathFromResources(ctx, ").append(joinedJarNames).append("))\n ");
} else {
builder.append(".classpath(JavaParser.runtimeClasspath()))\n ");
}
}
return builder.toString();
} catch (IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,19 @@ public String toJavaTemplateBuilder(int pos) {
tree = ((JCTree.JCReturn) tree).getExpression();
}

String javaParserClasspathFrom = processingEnv.getOptions().get("rewrite.javaParserClasspathFrom");
boolean classpathFromResources = "resources".equals(javaParserClasspathFrom);

List<JCTree.JCTypeParameter> typeParameters = classDecl.typarams == null ? emptyList() : classDecl.typarams;
return TemplateCode.process(tree, method.getReturnType().type, method.getParameters(), typeParameters, pos, method.restype.type instanceof Type.JCVoidType, true);
return TemplateCode.process(
tree,
method.getReturnType().type,
method.getParameters(),
typeParameters,
pos,
method.restype.type instanceof Type.JCVoidType,
true,
classpathFromResources);
}

public boolean validate() {
Expand Down
Loading