Skip to content

Commit

Permalink
handle generation when referencing non yet existing classes
Browse files Browse the repository at this point in the history
Signed-off-by: Yves Brissaud <gh@lgtd.io>
  • Loading branch information
eunomie committed Jan 31, 2025
1 parent 64e6c2e commit d75a52f
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ static JavaFile generate(ModuleInfo moduleInfo) {
"clazz.getMethod(\"setClient\", $T.class).invoke(obj, dag)", Client.class);
var firstFn = true;
for (var fnInfo : objectInfo.functions()) {
var fnReturnClass = classForName(fnInfo.returnType());
CodeBlock fnReturnType = typeName(fnInfo.returnType());
if (firstFn) {
firstFn = false;
im.beginControlFlow("if (fnName.equals($S))", fnInfo.name());
Expand All @@ -246,32 +246,40 @@ static JavaFile generate(ModuleInfo moduleInfo) {
var fnBlock =
CodeBlock.builder().add("$T fn = clazz.getMethod($S", Method.class, fnInfo.qName());
var invokeBlock =
CodeBlock.builder().add("$T res = ($T) fn.invoke(obj", fnReturnClass, fnReturnClass);
CodeBlock.builder()
.add(fnReturnType)
.add(" res = (")
.add(fnReturnType)
.add(") fn.invoke(obj");
for (var parameterInfo : fnInfo.parameters()) {
Class<?> paramClazz = classForName(parameterInfo.type());
fnBlock.add(", $T.class", paramClazz);
CodeBlock paramType = typeName(parameterInfo.type());
fnBlock.add(", ").add(paramType).add(".class");

invokeBlock.add(", $L", parameterInfo.name());

if (paramClazz.isPrimitive()) {
if (paramClazz.isAssignableFrom(boolean.class)) {
im.addStatement("$T $L = false", paramClazz, parameterInfo.name());
} else if (paramClazz.isAssignableFrom(int.class)) {
im.addStatement("$T $L = 0", paramClazz, parameterInfo.name());
} else {
im.addStatement("$T $L", paramClazz, parameterInfo.name());
}
} else {
im.addStatement("$T $L = null", paramClazz, parameterInfo.name());
String defaultValue = "null";
if (parameterInfo.type().kindName().equals(TypeKind.INT.name())) {
defaultValue = "0";
} else if (parameterInfo.type().kindName().equals(TypeKind.BOOLEAN.name())) {
defaultValue = "false";
}
im.addStatement(
CodeBlock.builder()
.add(paramType)
.add(" $L = $L", parameterInfo.name(), defaultValue)
.build());
im.beginControlFlow("if (inputArgs.get($S) != null)", parameterInfo.name());
im.addStatement(
"$L = ($T) $T.fromJSON(dag, inputArgs.get($S), $T.class)",
parameterInfo.name(),
paramClazz,
JsonConverter.class,
parameterInfo.name(),
classForName(parameterInfo.type()));
CodeBlock.builder()
.add("$L = (", parameterInfo.name())
.add(paramType)
.add(
") $T.fromJSON(dag, inputArgs.get($S), ",
JsonConverter.class,
parameterInfo.name())
.add(paramType)
.add(".class)")
.build());
im.endControlFlow();
}
fnBlock.add(")");
Expand Down Expand Up @@ -391,14 +399,12 @@ static CodeBlock typeDef(TypeInfo ti) throws ClassNotFoundException {
"dag.typeDef().withKind($T.$L)", TypeDefKind.class, TypeDefKind.BOOLEAN_KIND.name());
} else if (name.startsWith("java.util.List<")) {
name = name.substring("java.util.List<".length(), name.length() - 1);
return CodeBlock.of(
"dag.typeDef().withListOf($L)", typeDef(new TypeInfo(name, "")).toString());
return CodeBlock.of("dag.typeDef().withListOf($L)", typeDef(tiFromName(name)).toString());
} else if (!ti.kindName().isEmpty() && TypeKind.valueOf(ti.kindName()) == TypeKind.ARRAY) {
// in that case the type name is com.example.Type[]
// so we remove the [] to get the underlying type
name = name.substring(0, name.length() - 2);
return CodeBlock.of(
"dag.typeDef().withListOf($L)", typeDef(new TypeInfo(name, "")).toString());
return CodeBlock.of("dag.typeDef().withListOf($L)", typeDef(tiFromName(name)).toString());
}

try {
Expand All @@ -425,18 +431,48 @@ static CodeBlock typeDef(TypeInfo ti) throws ClassNotFoundException {
}
}

static Class<?> classForName(TypeInfo ti) throws ClassNotFoundException {
String name = ti.typeName();
static TypeInfo tiFromName(String name) {
if (name.equals("int")) {
return int.class;
return new TypeInfo(name, TypeKind.INT.name());
} else if (name.equals("boolean")) {
return boolean.class;
} else if (name.startsWith("java.util.List<")) {
return List.class;
} else if (TypeKind.valueOf(ti.kindName()) == TypeKind.ARRAY) {
return Class.forName("[L" + name.substring(0, name.length() - 2) + ";");
return new TypeInfo(name, TypeKind.BOOLEAN.name());
} else if (name.equals("void")) {
return new TypeInfo(name, TypeKind.VOID.name());
} else {
return new TypeInfo(name, "");
}
}

static CodeBlock typeName(TypeInfo ti) {
try {
TypeKind tk = TypeKind.valueOf(ti.kindName());
if (tk == TypeKind.INT) {
return CodeBlock.of("$T", int.class);
} else if (tk == TypeKind.BOOLEAN) {
return CodeBlock.of("$T", boolean.class);
} else if (tk == TypeKind.VOID) {
return CodeBlock.of("$T", void.class);
} else if (tk == TypeKind.ARRAY) {
return CodeBlock.builder()
.add(typeName(tiFromName(ti.typeName().substring(0, ti.typeName().length() - 2))))
.add("[]")
.build();
}
} catch (IllegalArgumentException ignored) {
}
String name = ti.typeName();
if (name.startsWith("java.util.List<")) {
return CodeBlock.of("$T", List.class);
}
try {
Class<?> clazz = Class.forName(name);
return CodeBlock.of("$T", clazz);
} catch (ClassNotFoundException e) {
return CodeBlock.of(
"$T",
ClassName.get(
name.substring(0, name.lastIndexOf(".")), name.substring(name.lastIndexOf(".") + 1)));
}
return Class.forName(name);
}

private String trimDoc(String doc) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import io.dagger.client.ModuleID;
import io.dagger.client.TypeDef;
import io.dagger.client.TypeDefKind;
import io.dagger.java.module.DaggerJava;
import jakarta.json.bind.JsonbBuilder;
import java.lang.Class;
import java.lang.Exception;
Expand Down Expand Up @@ -81,7 +82,20 @@ private ModuleID register() throws ExecutionException, DaggerQueryException,
dag.typeDef().withKind(TypeDefKind.STRING_KIND))
.withDescription("Returns lines that match a pattern in the files of the provided Directory")
.withArg("directoryArg", dag.typeDef().withObject("Directory").withOptional(false), new Function.WithArgArguments().withDescription("Directory to grep"))
.withArg("pattern", dag.typeDef().withKind(TypeDefKind.STRING_KIND).withOptional(false), new Function.WithArgArguments().withDescription("Pattern to search for in the directory"))));
.withArg("pattern", dag.typeDef().withKind(TypeDefKind.STRING_KIND).withOptional(false), new Function.WithArgArguments().withDescription("Pattern to search for in the directory")))
.withFunction(
dag.function("itself",
dag.typeDef().withObject("DaggerJava")))
.withFunction(
dag.function("isZero",
dag.typeDef().withKind(TypeDefKind.BOOLEAN_KIND))
.withArg("value", dag.typeDef().withKind(TypeDefKind.INTEGER_KIND).withOptional(false)))
.withFunction(
dag.function("doThings",
dag.typeDef().withListOf(dag.typeDef().withKind(io.dagger.client.TypeDefKind.INTEGER_KIND)))
.withArg("stringArray", dag.typeDef().withListOf(dag.typeDef().withKind(io.dagger.client.TypeDefKind.STRING_KIND)).withOptional(false))
.withArg("ints", dag.typeDef().withListOf(dag.typeDef().withKind(io.dagger.client.TypeDefKind.INTEGER_KIND)).withOptional(false))
.withArg("containers", dag.typeDef().withListOf(dag.typeDef().withObject("Container")).withOptional(false))));
return module.id();
}

Expand Down Expand Up @@ -112,9 +126,37 @@ private JSON invoke(JSON parentJson, String parentName, String fnName,
Method fn = clazz.getMethod("grepDir", Directory.class, String.class);
String res = (String) fn.invoke(obj, directoryArg, pattern);
return JsonConverter.toJSON(res);
} else if (fnName.equals("itself")) {
Method fn = clazz.getMethod("itself");
DaggerJava res = (DaggerJava) fn.invoke(obj);
return JsonConverter.toJSON(res);
} else if (fnName.equals("isZero")) {
int value = 0;
if (inputArgs.get("value") != null) {
value = (int) JsonConverter.fromJSON(dag, inputArgs.get("value"), int.class);
}
Method fn = clazz.getMethod("isZero", int.class);
boolean res = (boolean) fn.invoke(obj, value);
return JsonConverter.toJSON(res);
} else if (fnName.equals("doThings")) {
String[] stringArray = null;
if (inputArgs.get("stringArray") != null) {
stringArray = (String[]) JsonConverter.fromJSON(dag, inputArgs.get("stringArray"), String[].class);
}
List ints = null;
if (inputArgs.get("ints") != null) {
ints = (List) JsonConverter.fromJSON(dag, inputArgs.get("ints"), List.class);
}
List containers = null;
if (inputArgs.get("containers") != null) {
containers = (List) JsonConverter.fromJSON(dag, inputArgs.get("containers"), List.class);
}
Method fn = clazz.getMethod("doThings", String[].class, List.class, List.class);
int[] res = (int[]) fn.invoke(obj, stringArray, ints, containers);
return JsonConverter.toJSON(res);
}
}
}
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,20 @@ public String grepDir(Directory directoryArg, String pattern)
.withExec(List.of("grep", "-R", pattern, "."))
.stdout();
}

@Function
public DaggerJava itself() {
return this;
}

@Function
public boolean isZero(int value) {
return value == 0;
}

@Function
public int[] doThings(String[] stringArray, List<Integer> ints, List<Container> containers) {
int[] intsArray = {stringArray.length, ints.size()};
return intsArray;
}
}

0 comments on commit d75a52f

Please sign in to comment.