diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Builtins.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Builtins.java index d32325245c79..92c9cd92bf85 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Builtins.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/Builtins.java @@ -248,7 +248,7 @@ private static List> readBuiltinTypes() { .map( line -> { String[] builtinMeta = line.split(":"); - if (builtinMeta.length < 2 || builtinMeta.length > 3) { + if (builtinMeta.length < 2 || builtinMeta.length > 4) { java.lang.System.out.println(Arrays.toString(builtinMeta)); throw new CompilerError("Invalid builtin metadata in: " + line); } diff --git a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/BuiltinType.java b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/BuiltinType.java index 615d68161763..5099e549ec69 100644 --- a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/BuiltinType.java +++ b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/BuiltinType.java @@ -12,4 +12,7 @@ /** Fully qualified name as available in stdlib */ String name() default ""; + + /** Underlying type name of the builtin */ + String underlyingTypeName() default ""; } diff --git a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/BuiltinsProcessor.java b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/BuiltinsProcessor.java index d58a1c585536..8743a09ab7db 100644 --- a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/BuiltinsProcessor.java +++ b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/BuiltinsProcessor.java @@ -41,7 +41,7 @@ public class BuiltinsProcessor extends AbstractProcessor { private record Specialized(String owner, String methodName) {} - private Map> specializedMethods = new HashMap<>(); + private final Map> specializedMethods = new HashMap<>(); @Override public final boolean process(Set annotations, RoundEnvironment roundEnv) { @@ -91,11 +91,11 @@ public void handleClassElement(Element element, RoundEnvironment roundEnv) throw processingEnv.getFiler().createSourceFile(builtinType.fullyQualifiedName()); Optional stdLibName = annotation.stdlibName().isEmpty() ? Optional.empty() : Optional.of(annotation.stdlibName()); - generateBuiltinType(gen, builtinType, stdLibName); + generateBuiltinType(gen, builtinType, stdLibName, elt.getSimpleName().toString()); } private void generateBuiltinType( - JavaFileObject gen, ClassName builtinType, Optional stdLibName) throws IOException { + JavaFileObject gen, ClassName builtinType, Optional stdLibName, String underlyingTypeName) throws IOException { try (PrintWriter out = new PrintWriter(gen.openWriter())) { out.println("package " + builtinType.pkg() + ";"); out.println(); @@ -103,8 +103,8 @@ private void generateBuiltinType( out.println("import " + importPkg + ";"); } out.println(); - String stdLib = stdLibName.map(n -> "(name = \"" + n + "\")").orElse(""); - out.println("@BuiltinType" + stdLib); + String builtinTypeAnnotation = "@BuiltinType(" + stdLibName.map(n -> "name = \"" + n + "\", ").orElse("") + "underlyingTypeName = \"" + underlyingTypeName + "\")"; + out.println(builtinTypeAnnotation); out.println("public class " + builtinType.name() + " extends Builtin {"); out.println(""" @Override @@ -238,11 +238,8 @@ public void handleMethodElement(Element element, RoundEnvironment roundEnv) thro annotation.description(), method.getSimpleName().toString(), annotation.autoRegister()); - } else { - return; } } else { - MethodNodeClassGenerator classGenerator = new NoSpecializationClassGenerator( method, builtinMethodNode, ownerClass, stdLibOwnerClass); diff --git a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java index 34ad2cfff805..a5589b7dbc93 100644 --- a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java +++ b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/MethodProcessor.java @@ -423,7 +423,8 @@ private void generateUncheckedArrayCast( private void generateCheckedArgumentRead( PrintWriter out, MethodDefinition.ArgumentDefinition arg, String argsArray) { - String castName = "TypesGen.expect" + capitalize(arg.getTypeName()); + String builtinName = capitalize(arg.getTypeName()); + String castName = "TypesGen.expect" + builtinName; String varName = mkArgumentInternalVarName(arg); out.println(" " + arg.getTypeName() + " " + varName + ";"); out.println(" try {"); @@ -432,16 +433,20 @@ private void generateCheckedArgumentRead( out.println(" } catch (UnexpectedResultException e) {"); out.println(" com.oracle.truffle.api.CompilerDirectives.transferToInterpreter();"); out.println(" var builtins = EnsoContext.get(this).getBuiltins();"); - out.println( - " var expected = builtins.fromTypeSystem(TypesGen.getName(arguments[arg" - + arg.getPosition() - + "Idx]));"); - out.println( - " var error = builtins.error().makeTypeError(expected, arguments[arg" - + arg.getPosition() - + "Idx], \"" - + varName - + "\");"); + out.println(" var ensoTypeName = org.enso.interpreter.runtime.type.ConstantsGen.getEnsoTypeName(\"" + builtinName + "\");"); + out.println(" var error = (ensoTypeName != null)"); + out.println(" ? builtins.error().makeTypeError(builtins.fromTypeSystem(ensoTypeName), arguments[arg" + + arg.getPosition() + + "Idx], \"" + + varName + + "\")"); + out.println(" : builtins.error().makeUnsupportedArgumentsError(new Object[] { arguments[arg" + + arg.getPosition() + + "Idx] }, \"Unsupported argument for " + + varName + + " expected a " + + builtinName + + "\");"); out.println(" throw new PanicException(error,this);"); out.println(" }"); } @@ -559,7 +564,7 @@ public String key() { protected MethodMetadataEntry toMetadataEntry(String line) { String[] elements = line.split(":"); if (elements.length != 4) throw new RuntimeException("invalid builtin metadata entry: " + line); - return new MethodMetadataEntry(elements[0], elements[1], Boolean.valueOf(elements[2]), Boolean.valueOf(elements[3])); + return new MethodMetadataEntry(elements[0], elements[1], Boolean.parseBoolean(elements[2]), Boolean.parseBoolean(elements[3])); } private static final String DATAFLOW_ERROR_PROFILE = "IsDataflowErrorConditionProfile"; diff --git a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/TypeProcessor.java b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/TypeProcessor.java index 9cac5c11d2df..62490bc52199 100644 --- a/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/TypeProcessor.java +++ b/lib/scala/interpreter-dsl/src/main/java/org/enso/interpreter/dsl/TypeProcessor.java @@ -11,7 +11,6 @@ import java.io.Writer; import java.util.*; -import org.apache.commons.lang3.StringUtils; import org.openide.util.lookup.ServiceProvider; @SupportedAnnotationTypes("org.enso.interpreter.dsl.BuiltinType") @@ -22,12 +21,14 @@ public class TypeProcessor extends BuiltinsMetadataProcessor pastEntries) throws IOException { @@ -100,6 +106,8 @@ protected void storeMetadata(Writer writer, Map pastE + constr.getTpeName() + ":" + constr.getFullName() + + ":" + + constr.builtinTypeName + "\n"); if (pastEntries.containsKey(entry.getKey())) { pastEntries.remove(entry.getKey()); @@ -111,23 +119,42 @@ protected void storeMetadata(Writer writer, Map pastE out.println(); out.println("public class " + ConstantsGenClass + " {"); out.println(); + + var lookup = new HashMap(); for (Filer f : builtinTypes.keySet()) { for (Map.Entry entry : builtinTypes.get(f).entrySet()) { BuiltinTypeConstr constr = entry.getValue(); if (!constr.getFullName().isEmpty()) { - generateEntry(entry.getKey().toUpperCase(), constr.getFullName(), out); + var name = entry.getKey().toUpperCase(); + generateEntry(name, constr.getFullName(), out); + if (!constr.getBuiltinTypeName().equals("")) { + lookup.put(constr.getBuiltinTypeName(), name); + } } } } pastEntries - .values() - .forEach( - entry -> - entry.stdlibName().ifPresent(n -> generateEntry(entry.ensoName().toUpperCase(), n, out)) - ); + .forEach((k, v) -> { + v.stdlibName().ifPresent(name -> generateEntry(v.ensoName().toUpperCase(), name, out)); + v.builtinTypeName().ifPresent(builtinTypeName -> lookup.put(builtinTypeName, k.toUpperCase())); + }); out.println(); + + out.println(" public static String getEnsoTypeName(String builtinName) {"); + out.println(" return switch (builtinName) {"); + out.println(" case \"Long\" -> " + ConstantsGenClass + ".INTEGER;"); + out.println(" case \"Double\" -> " + ConstantsGenClass + ".DECIMAL;"); + out.println(" case \"Text\" -> " + ConstantsGenClass + ".TEXT;"); + lookup.forEach((k, v) -> + out.println(" case \"" + k + "\" -> " + ConstantsGenClass + "." + v + ";") + ); + out.println(" default -> null;"); + out.println(" };"); + out.println(" }"); + out.println(); + out.println("}"); } } @@ -152,13 +179,13 @@ private String toBuiltinName(String name) { } protected void registerBuiltinType( - Filer f, String name, String clazzName, String fullName) { + Filer f, String name, String clazzName, String fullName, String builtinTypeName) { Map classes = builtinTypes.get(f); if (classes == null) { classes = new HashMap<>(); builtinTypes.put(f, classes); } - classes.put(name, new BuiltinTypeConstr(clazzName, fullName)); + classes.put(name, new BuiltinTypeConstr(clazzName, fullName, builtinTypeName)); } @Override @@ -180,11 +207,11 @@ public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); } - public record TypeMetadataEntry(String ensoName, String clazzName, Optional stdlibName) implements MetadataEntry { + public record TypeMetadataEntry(String ensoName, String clazzName, Optional stdlibName, Optional builtinTypeName) implements MetadataEntry { @Override public String toString() { - return ensoName + ":" + clazzName + ":" + stdlibName.orElse(""); + return ensoName + ":" + clazzName + ":" + stdlibName.orElse("") + ":" + builtinTypeName.orElse(""); } @Override @@ -201,7 +228,8 @@ protected TypeMetadataEntry toMetadataEntry(String line) { public static TypeMetadataEntry fromStringToMetadataEntry(String line) { String[] elements = line.split(":"); if (elements.length < 2) throw new RuntimeException("invalid builtin metadata entry: " + line); - Optional stdLibName = elements.length == 3 ? Optional.of(elements[2]) : Optional.empty(); - return new TypeMetadataEntry(elements[0], elements[1], stdLibName); + Optional stdLibName = elements.length >= 3 ? Optional.of(elements[2]) : Optional.empty(); + Optional builtinTypeName = elements.length == 4 ? Optional.of(elements[3]) : Optional.empty(); + return new TypeMetadataEntry(elements[0], elements[1], stdLibName, builtinTypeName); } }