diff --git a/engine/runtime-integration-tests/src/test/java/org/enso/example/PolyglotTestClass.java b/engine/runtime-integration-tests/src/test/java/org/enso/example/PolyglotTestClass.java new file mode 100644 index 000000000000..1118c5a73cd7 --- /dev/null +++ b/engine/runtime-integration-tests/src/test/java/org/enso/example/PolyglotTestClass.java @@ -0,0 +1,20 @@ +package org.enso.example; + +import java.time.LocalDate; +import org.graalvm.polyglot.Value; + +public final class PolyglotTestClass { + private PolyglotTestClass() {} + + public static boolean isPolyglotDate_Object(Object obj) { + return obj instanceof Value polyglotVal && polyglotVal.isDate(); + } + + public static boolean isPolyglotDate_LocalDate(LocalDate date) { + return date != null; + } + + public static boolean isPolyglotDate_Value(Value val) { + return val != null && val.isDate(); + } +} diff --git a/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/builtins/BuiltinsJavaInteropTest.java b/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/builtins/BuiltinsJavaInteropTest.java new file mode 100644 index 000000000000..06b15f606dec --- /dev/null +++ b/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/builtins/BuiltinsJavaInteropTest.java @@ -0,0 +1,88 @@ +package org.enso.interpreter.test.builtins; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import java.io.ByteArrayOutputStream; +import org.enso.test.utils.ContextUtils; +import org.graalvm.polyglot.Context; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * In these tests, we call Java methods from Enso. Java methods have different signatures that + * accept Enso values in different ways. + */ +public class BuiltinsJavaInteropTest { + private static Context ctx; + private static final ByteArrayOutputStream out = new ByteArrayOutputStream(); + + @BeforeClass + public static void prepareCtx() { + ctx = ContextUtils.createDefaultContext(out); + } + + @AfterClass + public static void disposeCtx() { + ctx.close(); + ctx = null; + } + + @After + public void resetOutput() { + out.reset(); + } + + /** + * This test reflects the state of many Java methods in stdlibs that accept Enso values as {@link + * java.lang.Object}. If the Java method has a single argument of type {@link java.lang.Object}, + * and we pass {@code Date_Time} in it, we expect the host interop conversion to convert it to + * {@link java.time.LocalDateTime}. + */ + @Test + public void javaMethodAcceptsEnsoTimeOfDay_AsObject() { + var src = + """ + from Standard.Base import Date_Time + polyglot java import org.enso.example.PolyglotTestClass + + main = + dt = Date_Time.now + PolyglotTestClass.isPolyglotDate_Object dt + """; + var result = ContextUtils.evalModule(ctx, src); + assertThat(result.asBoolean(), is(true)); + } + + @Test + public void javaMethodAcceptsEnsoTimeOfDay_AsLocalDate() { + var src = + """ + from Standard.Base import Date_Time + polyglot java import org.enso.example.PolyglotTestClass + + main = + dt = Date_Time.now + PolyglotTestClass.isPolyglotDate_LocalDate dt + """; + var result = ContextUtils.evalModule(ctx, src); + assertThat(result.asBoolean(), is(true)); + } + + @Test + public void javaMethodAcceptsEnsoTimeOfDay_AsValue() { + var src = + """ + from Standard.Base import Date_Time + polyglot java import org.enso.example.PolyglotTestClass + + main = + dt = Date_Time.now + PolyglotTestClass.isPolyglotDate_Value dt + """; + var result = ContextUtils.evalModule(ctx, src); + assertThat(result.asBoolean(), is(true)); + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/BuiltinObject.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/BuiltinObject.java new file mode 100644 index 000000000000..3c3693d0660d --- /dev/null +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/builtin/BuiltinObject.java @@ -0,0 +1,111 @@ +package org.enso.interpreter.runtime.builtin; + +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Idempotent; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.interop.InteropLibrary; +import com.oracle.truffle.api.interop.UnsupportedMessageException; +import com.oracle.truffle.api.library.ExportLibrary; +import com.oracle.truffle.api.library.ExportMessage; +import com.oracle.truffle.api.nodes.Node; +import org.enso.interpreter.node.expression.builtin.Builtin; +import org.enso.interpreter.runtime.EnsoContext; +import org.enso.interpreter.runtime.data.EnsoObject; +import org.enso.interpreter.runtime.data.Type; +import org.enso.interpreter.runtime.library.dispatch.TypesLibrary; + +/** + * Base class for every Enso builtin object. Not type. Note that base class for a builtin type is + * {@link Builtin}. + * + *
In other words, this class represents an object of builtin type in a similar way that {@link + * org.enso.interpreter.runtime.data.atom.Atom} represents an object of a non-builtin type. + */ +@ExportLibrary(InteropLibrary.class) +@ExportLibrary(TypesLibrary.class) +public abstract class BuiltinObject extends EnsoObject { + + @ExportMessage + public final boolean hasType() { + return true; + } + + /** + * Returns the name of the builtin as saved inside {@link Builtins#builtinsByName}. Not fully + * qualified. + * + * @return + */ + protected abstract String builtinName(); + + protected final Type getBuiltinType(Node node) { + return GetType.uncached(this, node); + } + + /** + * Must return false, otherwise if a builtin object is passed to a host method that has a single + * {@code Object} argument, host interop would convert the builtin object to a {@code Map} with + * all its members. Even if the builtin object is, e.g., a number of a date. + * + *
Must return false as long as all our stdlib Java methods accept {@code Object} and not
+ * {@link org.graalvm.polyglot.Value} as arguments comming from Enso.
+ */
+ @ExportMessage
+ public final boolean hasMembers() {
+ return false;
+ }
+
+ @ExportMessage
+ public final Object getMembers(boolean includeInternal) throws UnsupportedMessageException {
+ throw UnsupportedMessageException.create();
+ }
+
+ @ExportMessage
+ public final boolean hasMetaObject() {
+ return true;
+ }
+
+ @ExportMessage(name = "getType", library = TypesLibrary.class)
+ @ExportMessage(name = "getMetaObject", library = InteropLibrary.class)
+ public static final class GetType {
+
+ GetType() {}
+
+ /**
+ * Caching on class of the receiver - as long as there is the same class, its {@link
+ * #builtinName()} method will return the same value. Note that we don't want to cache on the
+ * builtin name, as that would create a separate polymorph cache for every instance of the
+ * receiver.
+ */
+ @Specialization(
+ guards = {"cachedReceiverClass == receiver.getClass()", "getCtx(node) == cachedCtx"},
+ limit = "1")
+ public static Type doItCached(
+ BuiltinObject receiver,
+ @Bind("$node") Node node,
+ @Cached("receiver.getClass()") Class extends BuiltinObject> cachedReceiverClass,
+ @Cached(value = "getCtx(node)", allowUncached = true) EnsoContext cachedCtx,
+ @Cached(value = "getBuiltinType(receiver, cachedCtx)", allowUncached = true)
+ Builtin cachedBuiltinType) {
+ return cachedBuiltinType.getType();
+ }
+
+ @Specialization(replaces = "doItCached")
+ public static Type uncached(BuiltinObject receiver, @Bind("$node") Node node) {
+ var ctx = getCtx(node);
+ return getBuiltinType(receiver, ctx).getType();
+ }
+
+ @TruffleBoundary
+ public static Builtin getBuiltinType(BuiltinObject receiver, EnsoContext ctx) {
+ return ctx.getBuiltins().getBuiltinType(receiver.builtinName());
+ }
+
+ @Idempotent
+ public static EnsoContext getCtx(Node node) {
+ return EnsoContext.get(node);
+ }
+ }
+}
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoDate.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoDate.java
index 87d54ad80b7b..1c7872096879 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoDate.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoDate.java
@@ -1,30 +1,31 @@
package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
-import com.oracle.truffle.api.nodes.Node;
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.LocalTime;
import org.enso.interpreter.dsl.Builtin;
-import org.enso.interpreter.runtime.EnsoContext;
-import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
+import org.enso.interpreter.runtime.builtin.BuiltinObject;
import org.enso.polyglot.common_utils.Core_Date_Utils;
@ExportLibrary(InteropLibrary.class)
-@ExportLibrary(TypesLibrary.class)
@Builtin(pkg = "date", name = "Date", stdlibName = "Standard.Base.Data.Time.Date.Date")
-public final class EnsoDate extends EnsoObject {
+public final class EnsoDate extends BuiltinObject {
private final LocalDate date;
public EnsoDate(LocalDate date) {
this.date = date;
}
+ @Override
+ protected String builtinName() {
+ return "Date";
+ }
+
@Builtin.Method(description = "Return current Date", autoRegister = false)
@CompilerDirectives.TruffleBoundary
public static EnsoDate today() {
@@ -77,26 +78,6 @@ LocalTime asTime() throws UnsupportedMessageException {
throw UnsupportedMessageException.create();
}
- @ExportMessage
- Type getMetaObject(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().date();
- }
-
- @ExportMessage
- boolean hasMetaObject() {
- return true;
- }
-
- @ExportMessage
- boolean hasType() {
- return true;
- }
-
- @ExportMessage
- Type getType(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().date();
- }
-
@CompilerDirectives.TruffleBoundary
@ExportMessage
@Override
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoDateTime.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoDateTime.java
index 637626e3c938..e9f1ccc2c710 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoDateTime.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoDateTime.java
@@ -1,37 +1,37 @@
package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
-import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
-import com.oracle.truffle.api.nodes.Node;
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import org.enso.interpreter.dsl.Builtin;
-import org.enso.interpreter.runtime.EnsoContext;
+import org.enso.interpreter.runtime.builtin.BuiltinObject;
import org.enso.interpreter.runtime.data.text.Text;
-import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import org.enso.polyglot.common_utils.Core_Date_Utils;
@ExportLibrary(InteropLibrary.class)
-@ExportLibrary(TypesLibrary.class)
@Builtin(
pkg = "date",
name = "DateTime",
stdlibName = "Standard.Base.Data.Time.Date_Time.Date_Time")
-public final class EnsoDateTime extends EnsoObject {
+public final class EnsoDateTime extends BuiltinObject {
private final ZonedDateTime dateTime;
public EnsoDateTime(ZonedDateTime dateTime) {
this.dateTime = dateTime;
}
+ @Override
+ protected String builtinName() {
+ return "Date_Time";
+ }
+
@Builtin.Method(
name = "epoch_start",
description = "Return the Enso start of the Epoch",
@@ -205,26 +205,6 @@ ZoneId asTimeZone() {
return dateTime.getZone();
}
- @ExportMessage
- Type getMetaObject(@CachedLibrary("this") InteropLibrary thisLib) {
- return EnsoContext.get(thisLib).getBuiltins().dateTime();
- }
-
- @ExportMessage
- boolean hasMetaObject() {
- return true;
- }
-
- @ExportMessage
- boolean hasType() {
- return true;
- }
-
- @ExportMessage
- Type getType(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().dateTime();
- }
-
@ExportMessage
@CompilerDirectives.TruffleBoundary
@Override
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoDuration.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoDuration.java
index ef441702d61e..d96397962d05 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoDuration.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoDuration.java
@@ -1,12 +1,10 @@
package org.enso.interpreter.runtime.data;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
-import com.oracle.truffle.api.nodes.Node;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
@@ -16,37 +14,21 @@
import java.time.temporal.Temporal;
import org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.runtime.EnsoContext;
+import org.enso.interpreter.runtime.builtin.BuiltinObject;
import org.enso.interpreter.runtime.error.PanicException;
-import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
@ExportLibrary(InteropLibrary.class)
-@ExportLibrary(TypesLibrary.class)
@Builtin(pkg = "date", name = "Duration", stdlibName = "Standard.Base.Data.Time.Duration.Duration")
-public final class EnsoDuration extends EnsoObject {
+public final class EnsoDuration extends BuiltinObject {
private final Duration duration;
public EnsoDuration(Duration duration) {
this.duration = duration;
}
- @ExportMessage
- boolean hasType() {
- return true;
- }
-
- @ExportMessage
- Type getType(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().duration();
- }
-
- @ExportMessage
- Type getMetaObject(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().duration();
- }
-
- @ExportMessage
- boolean hasMetaObject() {
- return true;
+ @Override
+ protected String builtinName() {
+ return "Duration";
}
@Builtin.Method(
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoFile.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoFile.java
index c99a6e067370..335cd65d4ff4 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoFile.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoFile.java
@@ -3,7 +3,6 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.TruffleFile;
-import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.InteropLibrary;
@@ -38,22 +37,22 @@
import java.util.function.Function;
import org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.runtime.EnsoContext;
+import org.enso.interpreter.runtime.builtin.BuiltinObject;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.data.vector.ArrayLikeAtNode;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.data.vector.ArrayLikeLengthNode;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.PanicException;
-import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
/**
* A wrapper for {@link TruffleFile} objects exposed to the language. For methods documentation
* please refer to {@link TruffleFile}.
*/
@ExportLibrary(InteropLibrary.class)
-@ExportLibrary(TypesLibrary.class)
@Builtin(pkg = "io", name = "File", stdlibName = "Standard.Base.System.File.File")
-public final class EnsoFile extends EnsoObject {
+public final class EnsoFile extends BuiltinObject {
+
private final TruffleFile truffleFile;
public EnsoFile(TruffleFile truffleFile) {
@@ -63,6 +62,11 @@ public EnsoFile(TruffleFile truffleFile) {
this.truffleFile = truffleFile;
}
+ @Override
+ protected String builtinName() {
+ return "File";
+ }
+
@Builtin.Method(name = "output_stream_builtin")
@Builtin.WrapException(from = IOException.class)
@Builtin.Specialize
@@ -797,26 +801,6 @@ public String toString() {
return toDisplayString(false);
}
- @ExportMessage
- Type getMetaObject(@CachedLibrary("this") InteropLibrary thisLib) {
- return EnsoContext.get(thisLib).getBuiltins().file();
- }
-
- @ExportMessage
- boolean hasMetaObject() {
- return true;
- }
-
- @ExportMessage
- boolean hasType() {
- return true;
- }
-
- @ExportMessage
- Type getType(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().file();
- }
-
static RuntimeException raiseIOException(Node where, IOException ex) {
var ctx = EnsoContext.get(where);
var guestEx = ctx.asGuestValue(ex);
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoTimeOfDay.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoTimeOfDay.java
index 29da641fe54c..331849c5f938 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoTimeOfDay.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoTimeOfDay.java
@@ -2,34 +2,36 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
-import com.oracle.truffle.api.nodes.Node;
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import org.enso.interpreter.dsl.Builtin;
-import org.enso.interpreter.runtime.EnsoContext;
+import org.enso.interpreter.runtime.builtin.BuiltinObject;
import org.enso.interpreter.runtime.data.text.Text;
-import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
@ExportLibrary(InteropLibrary.class)
-@ExportLibrary(TypesLibrary.class)
@Builtin(
pkg = "date",
name = "TimeOfDay",
stdlibName = "Standard.Base.Data.Time.Time_Of_Day.Time_Of_Day")
-public final class EnsoTimeOfDay extends EnsoObject {
+public final class EnsoTimeOfDay extends BuiltinObject {
+
private final LocalTime localTime;
public EnsoTimeOfDay(LocalTime localTime) {
this.localTime = localTime;
}
+ @Override
+ protected String builtinName() {
+ return "Time_Of_Day";
+ }
+
@Builtin.Method(
name = "new_builtin",
description = "Constructs a new Time_OF_Day from an hour",
@@ -143,26 +145,6 @@ LocalDate asDate() throws UnsupportedMessageException {
throw UnsupportedMessageException.create();
}
- @ExportMessage
- Type getMetaObject(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().timeOfDay();
- }
-
- @ExportMessage
- boolean hasMetaObject() {
- return true;
- }
-
- @ExportMessage
- boolean hasType() {
- return true;
- }
-
- @ExportMessage
- Type getType(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().timeOfDay();
- }
-
@CompilerDirectives.TruffleBoundary
@ExportMessage
@Override
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoTimeZone.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoTimeZone.java
index 3f9da89a3797..5c29c4e5e70d 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoTimeZone.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoTimeZone.java
@@ -2,35 +2,37 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
-import com.oracle.truffle.api.nodes.Node;
import java.time.DateTimeException;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.zone.ZoneRulesException;
import org.enso.interpreter.dsl.Builtin;
-import org.enso.interpreter.runtime.EnsoContext;
+import org.enso.interpreter.runtime.builtin.BuiltinObject;
import org.enso.interpreter.runtime.data.text.Text;
-import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import org.enso.polyglot.common_utils.Core_Date_Utils;
@ExportLibrary(InteropLibrary.class)
-@ExportLibrary(TypesLibrary.class)
@Builtin(
pkg = "date",
name = "TimeZone",
stdlibName = "Standard.Base.Data.Time.Time_Zone.Time_Zone")
-public final class EnsoTimeZone extends EnsoObject {
+public final class EnsoTimeZone extends BuiltinObject {
+
private final ZoneId zone;
public EnsoTimeZone(ZoneId zone) {
this.zone = zone;
}
+ @Override
+ protected String builtinName() {
+ return "Time_Zone";
+ }
+
@Builtin.Method(description = "Get the unique identifier for your system's current timezone.")
@CompilerDirectives.TruffleBoundary
public Text zoneId() {
@@ -100,24 +102,4 @@ boolean isTimeZone() {
ZoneId asTimeZone() {
return zone;
}
-
- @ExportMessage
- Type getMetaObject(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().timeZone();
- }
-
- @ExportMessage
- boolean hasMetaObject() {
- return true;
- }
-
- @ExportMessage
- boolean hasType() {
- return true;
- }
-
- @ExportMessage
- Type getType(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().timeZone();
- }
}
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/ManagedResource.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/ManagedResource.java
index e931f8bf01f7..f5d3d5cffd88 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/ManagedResource.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/ManagedResource.java
@@ -10,8 +10,8 @@
import java.lang.ref.PhantomReference;
import org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.runtime.EnsoContext;
+import org.enso.interpreter.runtime.builtin.BuiltinObject;
import org.enso.interpreter.runtime.callable.function.Function;
-import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
/**
* An Enso runtime representation of a managed resource.
@@ -35,9 +35,8 @@
* ProcessItems} processor.
*/
@ExportLibrary(InteropLibrary.class)
-@ExportLibrary(TypesLibrary.class)
@Builtin(pkg = "resource", stdlibName = "Standard.Base.Runtime.Managed_Resource.Managed_Resource")
-public final class ManagedResource extends EnsoObject {
+public final class ManagedResource extends BuiltinObject {
private final Object resource;
private final PhantomReference Users should not use Enso objects as keys to Java maps, because equals won't work the same way
* as it works in Enso.
*/
-@ExportLibrary(TypesLibrary.class)
@ExportLibrary(InteropLibrary.class)
@Builtin(stdlibName = "Standard.Base.Data.Dictionary.Dictionary", name = "Dictionary")
-public final class EnsoHashMap extends EnsoObject {
+public final class EnsoHashMap extends BuiltinObject {
private final EnsoHashMapBuilder mapBuilder;
private final int generation;
private final int size;
@@ -57,6 +52,11 @@ static EnsoHashMap createEmpty() {
return new EnsoHashMap(EnsoHashMapBuilder.create());
}
+ @Override
+ protected String builtinName() {
+ return "Dictionary";
+ }
+
EnsoHashMapBuilder getMapBuilder(
VirtualFrame frame, boolean readOnly, HashCodeNode hashCodeNode, EqualsNode equalsNode) {
if (readOnly) {
@@ -144,26 +144,6 @@ Object getHashEntriesIterator(@CachedLibrary(limit = "3") InteropLibrary interop
}
}
- @ExportMessage(library = TypesLibrary.class)
- boolean hasType() {
- return true;
- }
-
- @ExportMessage(library = TypesLibrary.class)
- Type getType(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().dictionary();
- }
-
- @ExportMessage
- boolean hasMetaObject() {
- return true;
- }
-
- @ExportMessage
- Type getMetaObject(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().dictionary();
- }
-
@ExportMessage
@TruffleBoundary
@Override
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/text/Text.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/text/Text.java
index 7ae2fac6fbc1..4bfabb1b33f8 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/text/Text.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/text/Text.java
@@ -2,12 +2,10 @@
import com.ibm.icu.text.Normalizer2;
import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
-import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.strings.TruffleString;
import com.oracle.truffle.api.strings.TruffleString.Encoding;
import java.util.ArrayDeque;
@@ -16,16 +14,12 @@
import java.util.concurrent.locks.ReentrantLock;
import org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.node.expression.builtin.text.util.ToJavaStringNode;
-import org.enso.interpreter.runtime.EnsoContext;
-import org.enso.interpreter.runtime.data.EnsoObject;
-import org.enso.interpreter.runtime.data.Type;
-import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
+import org.enso.interpreter.runtime.builtin.BuiltinObject;
import org.enso.polyglot.common_utils.Core_Text_Utils;
/** The main runtime type for Enso's Text. */
@ExportLibrary(InteropLibrary.class)
-@ExportLibrary(TypesLibrary.class)
-public final class Text extends EnsoObject {
+public final class Text extends BuiltinObject {
private static final Lock LOCK = new ReentrantLock();
private static final Text EMPTY = new Text("");
private volatile Object contents;
@@ -46,6 +40,11 @@ private Text(ConcatRope contents) {
this.contents = contents;
}
+ @Override
+ protected String builtinName() {
+ return "Text";
+ }
+
@Builtin.Method(
description =
"""
@@ -212,16 +211,6 @@ String toDisplayString(
return Core_Text_Utils.prettyPrint(str);
}
- @ExportMessage
- Type getMetaObject(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().text();
- }
-
- @ExportMessage
- boolean hasMetaObject() {
- return true;
- }
-
private void setContents(String contents) {
assert length == -1 || length == contents.length();
this.contents = contents;
@@ -245,16 +234,6 @@ public String toString() {
}
}
- @ExportMessage
- boolean hasType() {
- return true;
- }
-
- @ExportMessage
- Type getType(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().text();
- }
-
/**
* Converts text to a Java String. For use outside of Truffle Nodes.
*
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/Array.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/Array.java
index d70ad6b44fda..09ef29401c5a 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/Array.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/Array.java
@@ -2,7 +2,6 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.interop.InteropLibrary;
@@ -11,29 +10,25 @@
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
-import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.profiles.BranchProfile;
import java.util.Arrays;
import java.util.Comparator;
import org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.runtime.EnsoContext;
-import org.enso.interpreter.runtime.data.EnsoObject;
-import org.enso.interpreter.runtime.data.Type;
+import org.enso.interpreter.runtime.builtin.BuiltinObject;
import org.enso.interpreter.runtime.data.hash.EnsoHashMap;
import org.enso.interpreter.runtime.data.hash.HashMapInsertAllNode;
import org.enso.interpreter.runtime.data.hash.HashMapInsertNode;
import org.enso.interpreter.runtime.data.hash.HashMapSizeNode;
-import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import org.enso.interpreter.runtime.warning.AppendWarningNode;
import org.enso.interpreter.runtime.warning.Warning;
import org.enso.interpreter.runtime.warning.WarningsLibrary;
/** A primitive boxed array type for use in the runtime. */
@ExportLibrary(InteropLibrary.class)
-@ExportLibrary(TypesLibrary.class)
@ExportLibrary(WarningsLibrary.class)
@Builtin(pkg = "mutable", stdlibName = "Standard.Base.Data.Array.Array")
-final class Array extends EnsoObject {
+final class Array extends BuiltinObject {
private final Object[] items;
/** If true, some elements contain warning, and thus, this Array contains warning. */
@@ -78,6 +73,11 @@ final Object[] getItems() {
return items;
}
+ @Override
+ protected String builtinName() {
+ return "Array";
+ }
+
/**
* Marks the object as array-like for Polyglot APIs.
*
@@ -159,27 +159,12 @@ public String toDisplayString(boolean b) {
return toString();
}
- @ExportMessage
- Type getMetaObject(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().array();
- }
-
- @ExportMessage
- boolean hasMetaObject() {
- return true;
- }
-
@Override
@CompilerDirectives.TruffleBoundary
public String toString() {
return Arrays.toString(items);
}
- @ExportMessage
- boolean hasType() {
- return true;
- }
-
private boolean hasWarningElements(Object[] items, WarningsLibrary warnings) {
for (Object item : items) {
if (warnings.hasWarnings(item)) {
@@ -306,9 +291,4 @@ boolean isLimitReached(
return false;
}
}
-
- @ExportMessage
- Type getType(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().array();
- }
}
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayLikeHelpers.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayLikeHelpers.java
index 75255bb9abd9..8a54ad68aad8 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayLikeHelpers.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayLikeHelpers.java
@@ -5,13 +5,20 @@
import com.oracle.truffle.api.library.CachedLibrary;
import java.nio.ByteBuffer;
import org.enso.interpreter.dsl.Builtin;
+import org.enso.interpreter.runtime.builtin.BuiltinObject;
import org.enso.interpreter.runtime.data.EnsoObject;
/** Publicly available operations on array-like classes. */
@Builtin(pkg = "immutable", stdlibName = "Standard.Base.Internal.Array_Like_Helpers")
-public final class ArrayLikeHelpers {
+public final class ArrayLikeHelpers extends BuiltinObject {
+
private ArrayLikeHelpers() {}
+ @Override
+ protected String builtinName() {
+ return "Array_Like_Helpers";
+ }
+
@Builtin.Method(
name = "new_array_proxy_builtin",
description = "Creates an array backed by a proxy object.")
@@ -121,4 +128,9 @@ public static EnsoObject asVectorEnsoObjects(EnsoObject... arr) {
public static EnsoObject asVectorEmpty() {
return Vector.fromEnsoOnlyArray(null);
}
+
+ @Override
+ public Object toDisplayString(boolean allowSideEffects) {
+ return "Array_Like_Helpers";
+ }
}
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayProxy.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayProxy.java
index 0aca184e7e45..be94c9e0430f 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayProxy.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayProxy.java
@@ -2,7 +2,6 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.interop.ArityException;
@@ -13,12 +12,8 @@
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
-import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.profiles.BranchProfile;
-import org.enso.interpreter.runtime.EnsoContext;
-import org.enso.interpreter.runtime.data.EnsoObject;
-import org.enso.interpreter.runtime.data.Type;
-import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
+import org.enso.interpreter.runtime.builtin.BuiltinObject;
/**
* A wrapper that allows to turn an Enso callback providing elements into a polyglot Array.
@@ -27,9 +22,8 @@
* example exposing rows of a Table without copying any data.
*/
@ExportLibrary(InteropLibrary.class)
-@ExportLibrary(TypesLibrary.class)
@ImportStatic(BranchProfile.class)
-final class ArrayProxy extends EnsoObject {
+final class ArrayProxy extends BuiltinObject {
private final long length;
private final Object at;
@@ -44,6 +38,11 @@ static ArrayProxy create(long length, Object at) {
return new ArrayProxy(length, at);
}
+ @Override
+ protected String builtinName() {
+ return "Array";
+ }
+
@ExportMessage
public boolean hasArrayElements() {
return true;
@@ -83,29 +82,9 @@ public String toDisplayString(boolean b) {
return toString();
}
- @ExportMessage
- boolean hasMetaObject() {
- return true;
- }
-
- @ExportMessage
- Type getMetaObject(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().array();
- }
-
@Override
@CompilerDirectives.TruffleBoundary
public String toString() {
return "(Array_Proxy " + length + " " + at + ")";
}
-
- @ExportMessage
- boolean hasType() {
- return true;
- }
-
- @ExportMessage
- Type getType(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().array();
- }
}
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/Vector.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/Vector.java
index 9893427ad676..2fad7a282ae8 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/Vector.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/Vector.java
@@ -1,7 +1,6 @@
package org.enso.interpreter.runtime.data.vector;
import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
@@ -9,25 +8,26 @@
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
-import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.node.expression.foreign.HostValueToEnsoNode;
import org.enso.interpreter.runtime.EnsoContext;
-import org.enso.interpreter.runtime.data.EnsoObject;
-import org.enso.interpreter.runtime.data.Type;
+import org.enso.interpreter.runtime.builtin.BuiltinObject;
import org.enso.interpreter.runtime.data.hash.EnsoHashMap;
-import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import org.enso.interpreter.runtime.warning.AppendWarningNode;
import org.enso.interpreter.runtime.warning.WarningsLibrary;
@ExportLibrary(InteropLibrary.class)
-@ExportLibrary(TypesLibrary.class)
@Builtin(pkg = "immutable", stdlibName = "Standard.Base.Data.Vector.Vector")
-abstract class Vector extends EnsoObject {
+abstract class Vector extends BuiltinObject {
private static final Vector EMPTY_LONG = new Long(new long[0]);
private static final Vector EMPTY_DOUBLE = new Double(new double[0]);
private static final Vector EMPTY_VECTOR = new EnsoOnly(new Object[0]);
+ @Override
+ protected String builtinName() {
+ return "Vector";
+ }
+
@ExportMessage
boolean hasArrayElements() {
return true;
@@ -78,30 +78,6 @@ public String toDisplayString(boolean allowSideEffects) {
return DisplayArrayUtils.toDisplayString(this, allowSideEffects, iop);
}
- @ExportMessage
- Type getMetaObject(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().vector();
- }
-
- @ExportMessage
- boolean hasMetaObject() {
- return true;
- }
-
- //
- // methods for TypesLibrary
- //
-
- @ExportMessage
- boolean hasType() {
- return true;
- }
-
- @ExportMessage
- Type getType(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().vector();
- }
-
//
// helper methods
//
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/number/EnsoBigInteger.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/number/EnsoBigInteger.java
index 961d31e88027..2e7892b34a9f 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/number/EnsoBigInteger.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/number/EnsoBigInteger.java
@@ -1,23 +1,16 @@
package org.enso.interpreter.runtime.number;
import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
-import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
-import com.oracle.truffle.api.nodes.Node;
import java.math.BigInteger;
-import org.enso.interpreter.runtime.EnsoContext;
-import org.enso.interpreter.runtime.data.EnsoObject;
-import org.enso.interpreter.runtime.data.Type;
-import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
+import org.enso.interpreter.runtime.builtin.BuiltinObject;
/** Internal wrapper for a {@link BigInteger}. */
@ExportLibrary(InteropLibrary.class)
-@ExportLibrary(TypesLibrary.class)
-public final class EnsoBigInteger extends EnsoObject {
+public final class EnsoBigInteger extends BuiltinObject {
private final BigInteger value;
/**
@@ -37,6 +30,11 @@ public BigInteger getValue() {
return value;
}
+ @Override
+ protected String builtinName() {
+ return "Integer";
+ }
+
@Override
@CompilerDirectives.TruffleBoundary
public String toString() {
@@ -125,26 +123,6 @@ public final BigInteger asBigInteger() {
return value;
}
- @ExportMessage
- Type getMetaObject(@CachedLibrary("this") InteropLibrary thisLib) {
- return EnsoContext.get(thisLib).getBuiltins().number().getInteger();
- }
-
- @ExportMessage
- boolean hasMetaObject() {
- return true;
- }
-
- @ExportMessage
- boolean hasType() {
- return true;
- }
-
- @ExportMessage
- Type getType(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().number().getInteger();
- }
-
@Override
public boolean equals(Object obj) {
if (obj instanceof EnsoBigInteger otherBigInt) {
diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/Warning.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/Warning.java
index 27096e7881f5..14ede3705e1c 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/Warning.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/Warning.java
@@ -2,26 +2,21 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.StopIterationException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
-import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.Builtin;
import org.enso.interpreter.runtime.EnsoContext;
-import org.enso.interpreter.runtime.data.EnsoObject;
-import org.enso.interpreter.runtime.data.Type;
+import org.enso.interpreter.runtime.builtin.BuiltinObject;
import org.enso.interpreter.runtime.data.hash.EnsoHashMap;
import org.enso.interpreter.runtime.data.hash.HashMapInsertNode;
-import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
@Builtin(pkg = "error", stdlibName = "Standard.Base.Warning.Warning")
-@ExportLibrary(TypesLibrary.class)
@ExportLibrary(value = InteropLibrary.class, delegateTo = "value")
-public final class Warning extends EnsoObject {
+public final class Warning extends BuiltinObject {
final Object value;
private final Object origin;
private final long sequenceId;
@@ -32,6 +27,11 @@ private Warning(Object value, Object origin, long sequenceId) {
this.sequenceId = sequenceId;
}
+ @Override
+ protected String builtinName() {
+ return "Warning";
+ }
+
@Builtin.Method(name = "value", description = "Gets the payload of the warning.")
@SuppressWarnings("generic-enso-builtin-type")
public Object getValue() {
@@ -129,16 +129,6 @@ public long getSequenceId() {
return sequenceId;
}
- @ExportMessage
- boolean hasType() {
- return true;
- }
-
- @ExportMessage
- Type getType(@Bind("$node") Node node) {
- return EnsoContext.get(node).getBuiltins().warning();
- }
-
public static Warning wrapMapError(WarningsLibrary warningsLib, Warning warning, long index) {
var ctx = EnsoContext.get(warningsLib);
var error = warning.getValue();
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 17806a3d297d..6d9a4322ece3 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
@@ -90,6 +90,7 @@ public final boolean process(Set extends TypeElement> annotations, RoundEnviro
*/
public void handleClassElement(Element element, RoundEnvironment roundEnv) throws IOException {
TypeElement elt = (TypeElement) element;
+ ensureBuiltinClassExtendsBuiltinObject(elt);
Builtin annotation = element.getAnnotation(Builtin.class);
String clazzName =
annotation.name().isEmpty() ? element.getSimpleName().toString() : annotation.name();
@@ -347,6 +348,31 @@ private int specializationsCount(Element owner, String builtinMethodName) {
.count();
}
+ /**
+ * @param builtinClass Class annotated with {@link Builtin}.
+ */
+ private void ensureBuiltinClassExtendsBuiltinObject(TypeElement builtinClass) {
+ var builtinObjectBinName = "org.enso.interpreter.runtime.builtin.BuiltinObject";
+ if (!isSubtype(builtinClass, builtinObjectBinName)) {
+ processingEnv
+ .getMessager()
+ .printMessage(
+ Kind.ERROR, "Builtin class must extend " + builtinObjectBinName, builtinClass);
+ }
+ }
+
+ /**
+ * Returns true if the given {@code clazz} is a subtype of class with binary name {@code
+ * binaryName}.
+ *
+ * @param clazz class to check
+ * @param binaryName binary name of the class to check against
+ */
+ private boolean isSubtype(TypeElement clazz, String binaryName) {
+ var superType = processingEnv.getElementUtils().getTypeElement(binaryName);
+ return processingEnv.getTypeUtils().isSubtype(clazz.asType(), superType.asType());
+ }
+
private final List