diff --git a/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/MetaObjectTest.java b/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/MetaObjectTest.java index a41448435dc9..6b56f5c6d94d 100644 --- a/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/MetaObjectTest.java +++ b/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/MetaObjectTest.java @@ -9,12 +9,14 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.oracle.truffle.api.interop.InteropLibrary; import java.io.PrintWriter; import java.io.StringWriter; import java.net.URI; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; +import java.util.function.Predicate; import org.enso.common.MethodNames; import org.enso.interpreter.runtime.data.Type; import org.enso.interpreter.runtime.type.ConstantsGen; @@ -272,6 +274,33 @@ public void numbersAreEitherIntegerOrFloat() throws Exception { } } + /** + * Primitive values and exceptions currently don't have an associated language. + * + *

TODO[PM]: Will be implemented in https://github.com/enso-org/enso/pull/11468 + */ + @Test + public void allEnsoNonPrimitiveValuesHaveLanguage() throws Exception { + var gen = ValuesGenerator.create(ctx, Language.ENSO); + Predicate isPrimitiveOrException = + (val) -> val.fitsInInt() || val.fitsInDouble() || val.isBoolean() || val.isException(); + var nonPrimitiveValues = + gen.allValues().stream().filter(isPrimitiveOrException.negate()).toList(); + var interop = InteropLibrary.getUncached(); + ContextUtils.executeInContext( + ctx, + () -> { + for (var value : nonPrimitiveValues) { + var unwrappedValue = ContextUtils.unwrapValue(ctx, value); + assertThat( + "Value " + unwrappedValue + " should have associated language", + interop.hasLanguage(unwrappedValue), + is(true)); + } + return null; + }); + } + @Test public void compareQualifiedAndSimpleTypeName() throws Exception { var g = generator(); diff --git a/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/WarningsTest.java b/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/WarningsTest.java index 61aead7772ee..f29576cdb676 100644 --- a/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/WarningsTest.java +++ b/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/WarningsTest.java @@ -2,16 +2,28 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.sameInstance; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.oracle.truffle.api.interop.InteropLibrary; +import java.util.List; import org.enso.common.LanguageInfo; import org.enso.common.MethodNames; +import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode; import org.enso.interpreter.runtime.EnsoContext; +import org.enso.interpreter.runtime.data.hash.EnsoHashMap; +import org.enso.interpreter.runtime.data.hash.HashMapGetNode; +import org.enso.interpreter.runtime.data.hash.HashMapInsertNode; +import org.enso.interpreter.runtime.data.hash.HashMapSizeNode; +import org.enso.interpreter.runtime.data.text.Text; +import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers; import org.enso.interpreter.runtime.warning.AppendWarningNode; import org.enso.interpreter.runtime.warning.Warning; +import org.enso.interpreter.runtime.warning.WarningsLibrary; import org.enso.interpreter.runtime.warning.WithWarnings; import org.enso.test.utils.ContextUtils; import org.graalvm.polyglot.Context; @@ -194,4 +206,92 @@ public void warningOnAnError() throws Exception { assertEquals( "Standard.Base.Error.Error", errorWithWarning.getMetaObject().getMetaQualifiedName()); } + + @Test + public void warningsArray_readViaInterop_shouldNotRemoveWarnings() { + ContextUtils.executeInContext( + ctx, + () -> { + var warn1 = Warning.create(ensoContext, 1L, null); + var warn2 = Warning.create(ensoContext, 2L, null); + var arr = ArrayLikeHelpers.wrapEnsoObjects(warn1, warn2); + var interop = InteropLibrary.getUncached(); + var warn1FromArr = interop.readArrayElement(arr, 0); + assertThat( + "warn1 and warn1FromArr should be the same reference", + warn1, + is(sameInstance(warn1FromArr))); + var warn2FromArr = interop.readArrayElement(arr, 1); + assertThat( + "warn2 and warn2FromArr should be the same reference", + warn2, + is(sameInstance(warn2FromArr))); + return null; + }); + } + + @Test + public void warningsArray_collectWarningsViaWarningsLibrary() { + ContextUtils.executeInContext( + ctx, + () -> { + var appendWarnNode = AppendWarningNode.getUncached(); + var warnsLib = WarningsLibrary.getUncached(); + var hashMapSizeNode = HashMapSizeNode.getUncached(); + var hashMapGetNode = HashMapGetNode.getUncached(); + + var warn1 = Warning.create(ensoContext, 1L, null); + var warn2 = Warning.create(ensoContext, 2L, null); + var warnsMap = createWarningsMap(List.of(warn1, warn2)); + var text1 = Text.create("1"); + var text2 = Text.create("2"); + var arr = ArrayLikeHelpers.wrapEnsoObjects(text1, text2); + var arrWithWarns = appendWarnNode.executeAppend(null, arr, warnsMap); + assertThat(warnsLib.hasWarnings(arrWithWarns), is(true)); + var gatheredWarns = warnsLib.getWarnings(arrWithWarns, false); + assertThat("Hash size should be 2", hashMapSizeNode.execute(gatheredWarns), is(2L)); + var warn1FromMap = + hashMapGetNode.execute(null, null, gatheredWarns, warn1.getSequenceId(), null); + assertThat( + "Original warning and warning gathered via WarningsLibrary should be the same object", + warn1 == warn1FromMap, + is(true)); + return null; + }); + } + + @Test + public void nothingWithWarn_IsNotRemovedByHostValueToEnsoNode() { + ContextUtils.executeInContext( + ctx, + () -> { + var hostValueToEnsoNode = HostValueToEnsoNode.getUncached(); + var warn = Warning.create(ensoContext, ensoContext.getNothing(), null); + var converted = hostValueToEnsoNode.execute(warn); + assertThat(converted, is(sameInstance(warn))); + return null; + }); + } + + @Test + public void nothingWithWarn_FromMapToArray() { + ContextUtils.executeInContext( + ctx, + () -> { + var warn = Warning.create(ensoContext, ensoContext.getNothing(), null); + var warnsMap = createWarningsMap(List.of(warn)); + var warns = Warning.fromMapToArray(warnsMap); + assertThat(warns.length, is(1)); + return null; + }); + } + + private EnsoHashMap createWarningsMap(List warns) { + var map = EnsoHashMap.empty(); + var mapInsertNode = HashMapInsertNode.getUncached(); + for (var warn : warns) { + map = mapInsertNode.execute(null, map, warn.getSequenceId(), warn); + } + return map; + } } diff --git a/engine/runtime-integration-tests/src/test/scala/org/enso/interpreter/test/semantic/CodeLocationsTest.scala b/engine/runtime-integration-tests/src/test/scala/org/enso/interpreter/test/semantic/CodeLocationsTest.scala index ccf25ea82211..b019106796e3 100644 --- a/engine/runtime-integration-tests/src/test/scala/org/enso/interpreter/test/semantic/CodeLocationsTest.scala +++ b/engine/runtime-integration-tests/src/test/scala/org/enso/interpreter/test/semantic/CodeLocationsTest.scala @@ -34,19 +34,25 @@ class CodeLocationsTest extends InterpreterTest { "be correct in simple arithmetic expressions" in withLocationsInstrumenter { instrumenter => - val code = "main = 2 + 45 * 20" - instrumenter.assertNodeExists(7, 11, classOf[ApplicationNode]) - instrumenter.assertNodeExists(11, 7, classOf[ApplicationNode]) - instrumenter.assertNodeExists(11, 2, classOf[LiteralNode]) + val code = + """from Standard.Base.Data.Numbers import all + |main = (2 + 45) * 20 + |""".stripMargin.replace("\r", "") + instrumenter.assertNodeExists(50, 13, classOf[ApplicationNode]) + instrumenter.assertNodeExists(51, 6, classOf[ApplicationNode]) + instrumenter.assertNodeExists(51, 1, classOf[LiteralNode]) eval(code) () } "be correct with parenthesized expressions" in withLocationsInstrumenter { instrumenter => - val code = "main = (2 + 45) * 20" - instrumenter.assertNodeExists(7, 13, classOf[ApplicationNode]) - instrumenter.assertNodeExists(8, 6, classOf[ApplicationNode]) + val code = + """from Standard.Base.Data.Numbers import all + |main = (2 + 45) * 20 + |""".stripMargin.replace("\r", "") + instrumenter.assertNodeExists(50, 13, classOf[ApplicationNode]) + instrumenter.assertNodeExists(51, 6, classOf[ApplicationNode]) eval(code) () } @@ -54,13 +60,12 @@ class CodeLocationsTest extends InterpreterTest { "be correct in applications and method calls" in withLocationsInstrumenter { instrumenter => val code = - """import Standard.Base.Data.List.List - |import Standard.Base.Any.Any + """from Standard.Base import all | |main = (2-2 == 0).if_then_else (List.Cons 5 6) 0 |""".stripMargin.linesIterator.mkString("\n") - instrumenter.assertNodeExists(73, 41, classOf[ApplicationNode]) - instrumenter.assertNodeExists(98, 13, classOf[ApplicationNode]) + instrumenter.assertNodeExists(38, 41, classOf[ApplicationNode]) + instrumenter.assertNodeExists(63, 13, classOf[ApplicationNode]) eval(code) () } @@ -69,18 +74,18 @@ class CodeLocationsTest extends InterpreterTest { withLocationsInstrumenter { instrumenter => val code = """ - |import Standard.Base.IO + |from Standard.Base import all | |main = | x = 2 + 2 * 2 | y = x * x | IO.println y |""".stripMargin.linesIterator.mkString("\n") - instrumenter.assertNodeExists(37, 13, classOf[AssignmentNode]) - instrumenter.assertNodeExists(55, 9, classOf[AssignmentNode]) - instrumenter.assertNodeExists(59, 1, classOf[ReadLocalVariableNode]) - instrumenter.assertNodeExists(63, 1, classOf[ReadLocalVariableNode]) - instrumenter.assertNodeExists(80, 1, classOf[ReadLocalVariableNode]) + instrumenter.assertNodeExists(43, 13, classOf[AssignmentNode]) + instrumenter.assertNodeExists(61, 9, classOf[AssignmentNode]) + instrumenter.assertNodeExists(65, 1, classOf[ReadLocalVariableNode]) + instrumenter.assertNodeExists(69, 1, classOf[ReadLocalVariableNode]) + instrumenter.assertNodeExists(86, 1, classOf[ReadLocalVariableNode]) eval(code) () } @@ -89,8 +94,7 @@ class CodeLocationsTest extends InterpreterTest { withLocationsInstrumenter { instrumenter => val code = """ - |import Standard.Base.Nothing - |import Standard.Base.IO + |from Standard.Base import all | |Nothing.method = | foo = a -> b -> @@ -102,10 +106,10 @@ class CodeLocationsTest extends InterpreterTest { |main = Nothing.method |""".stripMargin.linesIterator.mkString("\n") - instrumenter.assertNodeExists(137, 5, classOf[ApplicationNode]) - instrumenter.assertNodeExists(155, 1, classOf[ReadLocalVariableNode]) - instrumenter.assertNodeExists(151, 7, classOf[ApplicationNode]) - instrumenter.assertNodeExists(163, 9, classOf[ApplicationNode]) + instrumenter.assertNodeExists(114, 5, classOf[ApplicationNode]) + instrumenter.assertNodeExists(132, 1, classOf[ReadLocalVariableNode]) + instrumenter.assertNodeExists(128, 7, classOf[ApplicationNode]) + instrumenter.assertNodeExists(140, 9, classOf[ApplicationNode]) eval(code) () } @@ -114,7 +118,7 @@ class CodeLocationsTest extends InterpreterTest { withLocationsInstrumenter { instrumenter => val code = """ - |import Standard.Base.Data.List.List + |from Standard.Base import all | |main = | x = List.Cons 1 2 @@ -131,10 +135,10 @@ class CodeLocationsTest extends InterpreterTest { | | foo x + foo y |""".stripMargin.linesIterator.mkString("\n") - instrumenter.assertNodeExists(127, 0, 114, 1, classOf[CaseNode]) - instrumenter.assertNodeExists(178, 7, classOf[ApplicationNode]) - instrumenter.assertNodeExists(198, 9, classOf[AssignmentNode]) - instrumenter.assertNodeExists(235, 5, classOf[ApplicationNode]) + instrumenter.assertNodeExists(121, 0, 114, 1, classOf[CaseNode]) + instrumenter.assertNodeExists(172, 7, classOf[ApplicationNode]) + instrumenter.assertNodeExists(192, 9, classOf[AssignmentNode]) + instrumenter.assertNodeExists(229, 5, classOf[ApplicationNode]) eval(code) () } @@ -142,7 +146,8 @@ class CodeLocationsTest extends InterpreterTest { "be correct for lambdas" in withLocationsInstrumenter { instrumenter => val code = - """ + """from Standard.Base import all + | |main = | f = a -> b -> a + b | g = x -> y -> @@ -151,8 +156,8 @@ class CodeLocationsTest extends InterpreterTest { | | f 1 (g 2 3) |""".stripMargin.linesIterator.mkString("\n") - instrumenter.assertNodeExists(16, 15, classOf[CreateFunctionNode]) - instrumenter.assertNodeExists(40, 42, classOf[CreateFunctionNode]) + instrumenter.assertNodeExists(46, 15, classOf[CreateFunctionNode]) + instrumenter.assertNodeExists(70, 42, classOf[CreateFunctionNode]) eval(code) () } @@ -160,16 +165,17 @@ class CodeLocationsTest extends InterpreterTest { "be correct for defaulted arguments" in withLocationsInstrumenter { instrumenter => val code = - """ + """from Standard.Base import all + | |main = | bar = x -> x + x * x | foo = x -> (y = bar x) -> x + y | foo 0 |""".stripMargin.linesIterator.mkString("\n") - instrumenter.assertNodeExists(53, 5, classOf[ApplicationNode]) - instrumenter.assertNodeExists(53, 3, classOf[ReadLocalVariableNode]) - instrumenter.assertNodeExists(57, 1, classOf[ReadLocalVariableNode]) + instrumenter.assertNodeExists(93, 5, classOf[ApplicationNode]) + instrumenter.assertNodeExists(93, 1, classOf[ReadLocalVariableNode]) + instrumenter.assertNodeExists(97, 1, classOf[ReadLocalVariableNode]) eval(code) () } @@ -177,13 +183,14 @@ class CodeLocationsTest extends InterpreterTest { "be correct for lazy arguments" in withLocationsInstrumenter { instrumenter => val code = - """ + """from Standard.Base import all + | |main = | bar = a -> ~b -> ~c -> b | | bar 0 10 0 |""".stripMargin.linesIterator.mkString("\n") - instrumenter.assertNodeExists(35, 1, classOf[ForceNode]) + instrumenter.assertNodeExists(65, 1, classOf[ForceNode]) eval(code) () } @@ -198,19 +205,21 @@ class CodeLocationsTest extends InterpreterTest { "be correct for negated expressions" in withLocationsInstrumenter { instrumenter => val code = - """ + """from Standard.Base import all + | |main = | f = 1 | -f |""".stripMargin.linesIterator.mkString("\n") - instrumenter.assertNodeExists(22, 1, 2, 1, classOf[ApplicationNode]) + instrumenter.assertNodeExists(52, 1, 2, 1, classOf[ApplicationNode]) eval(code) } "be correct in sugared method definitions" in withLocationsInstrumenter { instrumenter => val code = - """ + """from Standard.Base.Data.Numbers import all + | |Test.foo a b = a * b - a | |main = Test.foo 2 3 @@ -221,7 +230,10 @@ class CodeLocationsTest extends InterpreterTest { val method = mod.getMethod(tpe, "foo").get method.value.invokeMember( MethodNames.Function.GET_SOURCE_START - ) shouldEqual 1 + ) should ( + equal(44) or + equal(45) + ) method.value.invokeMember( MethodNames.Function.GET_SOURCE_LENGTH ) should ( @@ -229,7 +241,7 @@ class CodeLocationsTest extends InterpreterTest { equal(25) ) - instrumenter.assertNodeExists(16, 9, classOf[ApplicationNode]) + instrumenter.assertNodeExists(59, 9, classOf[ApplicationNode]) eval(code) } @@ -237,20 +249,23 @@ class CodeLocationsTest extends InterpreterTest { "be correct in sugared function definitions" in withLocationsInstrumenter { instrumenter => val code = - """|main = + """|from Standard.Base import all + | + |main = | f a b = a - b | f 10 20 |""".stripMargin.linesIterator.mkString("\n") - instrumenter.assertNodeExists(11, 1, 13, 0, classOf[AssignmentNode]) - instrumenter.assertNodeExists(19, 1, 5, 0, classOf[ApplicationNode]) + instrumenter.assertNodeExists(41, 1, 13, 0, classOf[AssignmentNode]) + instrumenter.assertNodeExists(49, 1, 5, 0, classOf[ApplicationNode]) eval(code) } "be correct in the presence of comments" in withLocationsInstrumenter { instrumenter => val code = - """ + """from Standard.Base import all + | |# this is a comment |#this too |## But this is a doc. @@ -260,8 +275,8 @@ class CodeLocationsTest extends InterpreterTest { | # perform the addition | x + y # the addition is performed here |""".stripMargin.linesIterator.mkString("\n") - instrumenter.assertNodeExists(82, 1, classOf[LiteralNode]) - instrumenter.assertNodeExists(164, 5, classOf[ApplicationNode]) + instrumenter.assertNodeExists(112, 1, classOf[LiteralNode]) + instrumenter.assertNodeExists(194, 5, classOf[ApplicationNode]) eval(code) shouldEqual 3 } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/callable/FunctionCallInstrumentationNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/callable/FunctionCallInstrumentationNode.java index 499279dd78a0..16c243a3523b 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/callable/FunctionCallInstrumentationNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/callable/FunctionCallInstrumentationNode.java @@ -1,6 +1,7 @@ package org.enso.interpreter.node.callable; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; @@ -56,7 +57,7 @@ public boolean isInstrumentable() { /** A simple value class for function call information. */ @ExportLibrary(InteropLibrary.class) - public static final class FunctionCall implements EnsoObject { + public static final class FunctionCall extends EnsoObject { private final Function function; private final State state; private final @CompilerDirectives.CompilationFinal(dimensions = 1) Object[] arguments; @@ -132,7 +133,7 @@ public Object[] getArguments() { } @Override - @CompilerDirectives.TruffleBoundary + @TruffleBoundary public String toString() { return "FunctionCall[function=" + function @@ -140,6 +141,13 @@ public String toString() { + Arrays.toString(arguments) + "]"; } + + @Override + @ExportMessage + @TruffleBoundary + public Object toDisplayString(boolean allowSideEffects) { + return toString(); + } } /** diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/controlflow/caseexpr/BranchResult.java b/engine/runtime/src/main/java/org/enso/interpreter/node/controlflow/caseexpr/BranchResult.java index f9c348072845..8c965a62cc4a 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/controlflow/caseexpr/BranchResult.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/controlflow/caseexpr/BranchResult.java @@ -1,10 +1,27 @@ package org.enso.interpreter.node.controlflow.caseexpr; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.nodes.Node; import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.data.EnsoObject; -record BranchResult(boolean isMatched, Object result) implements EnsoObject { +final class BranchResult extends EnsoObject { + private final boolean isMatched; + private final Object result; + + BranchResult(boolean isMatched, Object result) { + this.isMatched = isMatched; + this.result = result; + } + + public boolean isMatched() { + return isMatched; + } + + public Object result() { + return result; + } + static BranchResult failure(Node node) { return new BranchResult(false, EnsoContext.get(node).getBuiltins().nothing()); } @@ -12,4 +29,10 @@ static BranchResult failure(Node node) { static BranchResult success(Object result) { return new BranchResult(true, result); } + + @Override + @TruffleBoundary + public Object toDisplayString(boolean allowSideEffects) { + return "BranchResult(" + isMatched + ")"; + } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/AtomWithAHoleNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/AtomWithAHoleNode.java index d462f44d42c7..58f75a25b85b 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/AtomWithAHoleNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/AtomWithAHoleNode.java @@ -73,7 +73,7 @@ Object doExecute( } @ExportLibrary(InteropLibrary.class) - static final class HoleInAtom implements EnsoObject { + static final class HoleInAtom extends EnsoObject { Atom result; int index; Function function; @@ -140,7 +140,8 @@ Object invokeMember( } @ExportMessage - String toDisplayString(boolean pure) { + @Override + public String toDisplayString(boolean pure) { return "Meta.atom_with_hole"; } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/Instrumentor.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/Instrumentor.java index c9a5c44f482f..ccae142fc7d2 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/Instrumentor.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/Instrumentor.java @@ -1,6 +1,7 @@ package org.enso.interpreter.node.expression.builtin.meta; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.instrumentation.EventBinding; import com.oracle.truffle.api.interop.InteropException; @@ -14,7 +15,7 @@ import org.enso.interpreter.runtime.instrument.Timer; import org.enso.polyglot.debugger.IdExecutionService; -final class Instrumentor implements EnsoObject, IdExecutionService.Callbacks { +final class Instrumentor extends EnsoObject implements IdExecutionService.Callbacks { private final IdExecutionService service; private final RootCallTarget target; @@ -125,4 +126,16 @@ public Object onFunctionReturn(IdExecutionService.Info info) { public Object getExecutionEnvironment(IdExecutionService.Info info) { return null; } + + @Override + @TruffleBoundary + public Object toDisplayString(boolean allowSideEffects) { + String rootName; + if (target.getRootNode() != null) { + rootName = target.getRootNode().getQualifiedName(); + } else { + rootName = ""; + } + return "Instrumentor(target = " + rootName + ")"; + } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/Module.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/Module.java index e7b0cbded6df..c46da21bab26 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/Module.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/Module.java @@ -1,6 +1,7 @@ package org.enso.interpreter.runtime; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.TruffleFile; import com.oracle.truffle.api.TruffleLogger; import com.oracle.truffle.api.dsl.Cached; @@ -53,7 +54,7 @@ /** Represents a source module with a known location. */ @ExportLibrary(InteropLibrary.class) -public final class Module implements EnsoObject { +public final class Module extends EnsoObject { private ModuleSources sources; private QualifiedName name; private ModuleScope.Builder scopeBuilder; @@ -772,6 +773,10 @@ boolean hasMembers() { boolean isMemberInvocable(String member) { return member.equals(MethodNames.Module.GET_METHOD) || member.equals(MethodNames.Module.REPARSE) + || member.equals(MethodNames.Module.GATHER_IMPORT_STATEMENTS) + || member.equals(MethodNames.Module.GENERATE_DOCS) + || member.equals(MethodNames.Module.GET_NAME) + || member.equals(MethodNames.Module.GET_TYPE) || member.equals(MethodNames.Module.SET_SOURCE) || member.equals(MethodNames.Module.SET_SOURCE_FILE) || member.equals(MethodNames.Module.GET_ASSOCIATED_TYPE) @@ -795,8 +800,15 @@ Object getMembers(boolean includeInternal) { MethodNames.Module.EVAL_EXPRESSION); } + @ExportMessage + @TruffleBoundary @Override - public String toString() { + public String toDisplayString(boolean allowSideEffects) { return "Module[" + name + ']'; } + + @Override + public String toString() { + return toDisplayString(false); + } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedConstructor.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedConstructor.java index e046741c0efb..0fe30d8990ad 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedConstructor.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedConstructor.java @@ -1,6 +1,7 @@ package org.enso.interpreter.runtime.callable; 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.Specialization; @@ -48,7 +49,7 @@ */ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) -public final class UnresolvedConstructor implements EnsoObject { +public final class UnresolvedConstructor extends EnsoObject { private static final CallArgumentInfo[] NONE = new CallArgumentInfo[0]; private final String name; private final Node where; @@ -75,13 +76,15 @@ final String getName() { } @Override - @CompilerDirectives.TruffleBoundary + @TruffleBoundary public String toString() { return ".." + name; } @ExportMessage - String toDisplayString(boolean allowSideEffects) { + @Override + @TruffleBoundary + public String toDisplayString(boolean allowSideEffects) { return toString(); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedConversion.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedConversion.java index ddc74e20574a..96d833f64fb5 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedConversion.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedConversion.java @@ -22,7 +22,7 @@ /** Simple runtime value representing a yet-unresolved by-name symbol. */ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) -public final class UnresolvedConversion implements EnsoObject { +public final class UnresolvedConversion extends EnsoObject { private final ModuleScope scope; /** @@ -71,7 +71,8 @@ public String toString() { } @ExportMessage - String toDisplayString(boolean allowSideEffects) { + @Override + public String toDisplayString(boolean allowSideEffects) { return this.toString(); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedSymbol.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedSymbol.java index 37a071256f65..1f823c6c2463 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedSymbol.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/UnresolvedSymbol.java @@ -24,7 +24,7 @@ /** Simple runtime value representing a yet-unresolved by-name symbol. */ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) -public final class UnresolvedSymbol implements EnsoObject { +public final class UnresolvedSymbol extends EnsoObject { private final String name; private final ModuleScope scope; @@ -85,7 +85,8 @@ public String toString() { @ExportMessage @TruffleBoundary - String toDisplayString(boolean allowSideEffects) { + @Override + public String toDisplayString(boolean allowSideEffects) { return this.toString(); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/function/Function.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/function/Function.java index 527c6e614844..f93932d807bc 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/function/Function.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/function/Function.java @@ -39,7 +39,7 @@ /** A runtime representation of a function object in Enso. */ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) -public final class Function implements EnsoObject { +public final class Function extends EnsoObject { private final RootCallTarget callTarget; private final MaterializedFrame scope; private final FunctionSchema schema; @@ -276,7 +276,9 @@ Object invokeMember(String member, Object... args) */ @ExportMessage boolean isMemberInvocable(String member) { - return member.equals(MethodNames.Function.EQUALS); + return member.equals(MethodNames.Function.EQUALS) + || member.equals(MethodNames.Function.GET_SOURCE_START) + || member.equals(MethodNames.Function.GET_SOURCE_LENGTH); } /** @@ -299,7 +301,10 @@ boolean hasMembers() { */ @ExportMessage Object getMembers(boolean includeInternal) { - return ArrayLikeHelpers.wrapStrings(MethodNames.Function.EQUALS); + return ArrayLikeHelpers.wrapStrings( + MethodNames.Function.EQUALS, + MethodNames.Function.GET_SOURCE_START, + MethodNames.Function.GET_SOURCE_LENGTH); } /** @@ -428,7 +433,8 @@ public boolean isFullyApplied() { } @ExportMessage - String toDisplayString(boolean sideEffects) { + @Override + public String toDisplayString(boolean sideEffects) { return toString(); } 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 2517ad1f5a2e..87d54ad80b7b 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 @@ -18,7 +18,7 @@ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) @Builtin(pkg = "date", name = "Date", stdlibName = "Standard.Base.Data.Time.Date.Date") -public final class EnsoDate implements EnsoObject { +public final class EnsoDate extends EnsoObject { private final LocalDate date; public EnsoDate(LocalDate date) { @@ -99,6 +99,7 @@ Type getType(@Bind("$node") Node node) { @CompilerDirectives.TruffleBoundary @ExportMessage + @Override public Object toDisplayString(boolean allowSideEffects) { return Core_Date_Utils.defaultLocalDateFormatter.format(date); } 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 8e4875a72683..637626e3c938 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 @@ -25,7 +25,7 @@ pkg = "date", name = "DateTime", stdlibName = "Standard.Base.Data.Time.Date_Time.Date_Time") -public final class EnsoDateTime implements EnsoObject { +public final class EnsoDateTime extends EnsoObject { private final ZonedDateTime dateTime; public EnsoDateTime(ZonedDateTime dateTime) { @@ -227,6 +227,7 @@ Type getType(@Bind("$node") Node node) { @ExportMessage @CompilerDirectives.TruffleBoundary + @Override public Object toDisplayString(boolean allowSideEffects) { return Core_Date_Utils.defaultZonedDateTimeFormatter.format(dateTime); } 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 b8c69738f74a..ef441702d61e 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 @@ -22,7 +22,7 @@ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) @Builtin(pkg = "date", name = "Duration", stdlibName = "Standard.Base.Data.Time.Duration.Duration") -public final class EnsoDuration implements EnsoObject { +public final class EnsoDuration extends EnsoObject { private final Duration duration; public EnsoDuration(Duration duration) { @@ -185,6 +185,7 @@ public Duration asDuration() { @ExportMessage @TruffleBoundary + @Override public String toDisplayString(boolean allowSideEffects) { return duration.toString(); } 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 43a16cd0a667..c99a6e067370 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 @@ -53,7 +53,7 @@ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) @Builtin(pkg = "io", name = "File", stdlibName = "Standard.Base.System.File.File") -public final class EnsoFile implements EnsoObject { +public final class EnsoFile extends EnsoObject { private final TruffleFile truffleFile; public EnsoFile(TruffleFile truffleFile) { @@ -79,7 +79,7 @@ public EnsoObject outputStream( } @ExportLibrary(InteropLibrary.class) - static final class EnsoOutputStream implements EnsoObject { + static final class EnsoOutputStream extends EnsoObject { private static final String[] MEMBERS = new String[] {"write", "flush", "close"}; private final OutputStream os; @@ -182,6 +182,12 @@ final void close() throws IOException { public String toString() { return "EnsoOutputStream"; } + + @Override + @ExportMessage + public Object toDisplayString(boolean allowSideEffects) { + return toString(); + } } @Builtin.Method(name = "input_stream_builtin") @@ -200,7 +206,7 @@ public EnsoObject inputStream( } @ExportLibrary(InteropLibrary.class) - static final class EnsoInputStream implements EnsoObject { + static final class EnsoInputStream extends EnsoObject { private static final String[] MEMBERS = new String[] { "read", "readAllBytes", "readNBytes", "skipNBytes", "markSupported", "available", "close" @@ -227,6 +233,12 @@ Object getMembers(boolean includeInternal) throws UnsupportedMessageException { return ArrayLikeHelpers.wrapStrings(MEMBERS); } + @ExportMessage + @Override + public Object toDisplayString(boolean allowSideEffects) { + return "EnsoInputStream"; + } + @TruffleBoundary(allowInlining = true) private int read() throws IOException { return delegate.read(); @@ -734,7 +746,8 @@ public boolean startsWith(EnsoFile parent) { autoRegister = false) @Builtin.Specialize @TruffleBoundary - public static EnsoObject fromString(EnsoContext context, String path) + @SuppressWarnings("generic-enso-builtin-type") + public static Object fromString(EnsoContext context, String path) throws IllegalArgumentException { try { TruffleFile file = context.getPublicTruffleFile(path); @@ -766,14 +779,22 @@ public static EnsoFile currentDirectory(EnsoContext context) { autoRegister = false) @Builtin.Specialize @TruffleBoundary - public static EnsoObject userHome(EnsoContext context) { + @SuppressWarnings("generic-enso-builtin-type") + public static Object userHome(EnsoContext context) { return fromString(context, System.getProperty("user.home")); } + @ExportMessage + @TruffleBoundary + @Override + public String toDisplayString(boolean allowSideEffects) { + return "(File " + truffleFile.getPath() + ")"; + } + @Override @TruffleBoundary public String toString() { - return "(File " + truffleFile.getPath() + ")"; + return toDisplayString(false); } @ExportMessage diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoMultiValue.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoMultiValue.java index 1be55e9a92a6..119e6dc1a4cb 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoMultiValue.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoMultiValue.java @@ -35,7 +35,7 @@ @ExportLibrary(TypesLibrary.class) @ExportLibrary(InteropLibrary.class) -public final class EnsoMultiValue implements EnsoObject { +public final class EnsoMultiValue extends EnsoObject { @CompilationFinal(dimensions = 1) private final Type[] types; @@ -73,7 +73,9 @@ public final Type[] allTypes() { } @ExportMessage - String toDisplayString(boolean ignore) { + @TruffleBoundary + @Override + public String toDisplayString(boolean ignore) { return toString(); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoObject.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoObject.java index ce601581161b..47c19783f36e 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoObject.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoObject.java @@ -1,6 +1,29 @@ package org.enso.interpreter.runtime.data; +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.library.ExportLibrary; +import com.oracle.truffle.api.library.ExportMessage; +import org.enso.interpreter.EnsoLanguage; /** All non-primitive Enso types extends from {@code EnsoObject}. */ -public interface EnsoObject extends TruffleObject {} +@ExportLibrary(InteropLibrary.class) +public abstract class EnsoObject implements TruffleObject { + @ExportMessage + public boolean hasLanguage() { + return true; + } + + @ExportMessage + public Class> getLanguage() { + return EnsoLanguage.class; + } + + /** + * This abstract method needs to be declared here with the annotation {@code @ExportMessage} so + * that the Truffle DSL is satisfied. + */ + @ExportMessage + public abstract Object toDisplayString(boolean allowSideEffects); +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoSource.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoSource.java index fae77b1e7697..5f0dd6e9d68b 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoSource.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoSource.java @@ -12,7 +12,7 @@ /** Wrapper for exposing sources to Enso. Delegates to original methods with no behavior changes. */ @ExportLibrary(InteropLibrary.class) -public final class EnsoSource implements EnsoObject { +public final class EnsoSource extends EnsoObject { private static final String[] MEMBERS = { "getLanguage", // "getName", // @@ -69,4 +69,11 @@ boolean isMemberReadable(String name) { Object getMembers(boolean includeInternal) { return ArrayLikeHelpers.wrapStrings(MEMBERS); } + + @Override + @TruffleBoundary + @ExportMessage + public Object toDisplayString(boolean allowSideEffects) { + return "EnsoSource{" + (source != null ? source.toString() : "") + "}"; + } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoSourceSection.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoSourceSection.java index a15ab53416a7..b003175a4304 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoSourceSection.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/EnsoSourceSection.java @@ -15,7 +15,7 @@ * changes. */ @ExportLibrary(InteropLibrary.class) -public final class EnsoSourceSection implements EnsoObject { +public final class EnsoSourceSection extends EnsoObject { private static final String[] MEMBERS = { "getStartLine", // "getEndLine", // @@ -34,6 +34,7 @@ public final class EnsoSourceSection implements EnsoObject { private final SourceSection sourceSection; public EnsoSourceSection(SourceSection sourceSection) { + assert sourceSection != null; this.sourceSection = sourceSection; } @@ -78,4 +79,11 @@ boolean isMemberReadable(String name) { Object getMembers(boolean includeInternal) { return ArrayLikeHelpers.wrapStrings(MEMBERS); } + + @Override + @TruffleBoundary + @ExportMessage + public Object toDisplayString(boolean allowSideEffects) { + return "EnsoSourceSection{" + sourceSection + "}"; + } } 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 eddfdd798711..29da641fe54c 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 @@ -23,7 +23,7 @@ pkg = "date", name = "TimeOfDay", stdlibName = "Standard.Base.Data.Time.Time_Of_Day.Time_Of_Day") -public final class EnsoTimeOfDay implements EnsoObject { +public final class EnsoTimeOfDay extends EnsoObject { private final LocalTime localTime; public EnsoTimeOfDay(LocalTime localTime) { @@ -165,6 +165,7 @@ Type getType(@Bind("$node") Node node) { @CompilerDirectives.TruffleBoundary @ExportMessage + @Override public Object toDisplayString(boolean allowSideEffects) { return DateTimeFormatter.ISO_LOCAL_TIME.format(localTime); } 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 c572e98d0d1c..3f9da89a3797 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 @@ -1,6 +1,7 @@ package org.enso.interpreter.runtime.data; 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; @@ -23,7 +24,7 @@ pkg = "date", name = "TimeZone", stdlibName = "Standard.Base.Data.Time.Time_Zone.Time_Zone") -public final class EnsoTimeZone implements EnsoObject { +public final class EnsoTimeZone extends EnsoObject { private final ZoneId zone; public EnsoTimeZone(ZoneId zone) { @@ -84,7 +85,9 @@ public static EnsoTimeZone system() { } @ExportMessage - String toDisplayString(boolean ignoreSideEffects) { + @Override + @TruffleBoundary + public String toDisplayString(boolean ignoreSideEffects) { return zone.toString(); } 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 d23537aea36a..424eac477f3c 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 @@ -1,5 +1,6 @@ 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.library.ExportLibrary; @@ -15,7 +16,7 @@ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) @Builtin(pkg = "resource", stdlibName = "Standard.Base.Runtime.Managed_Resource.Managed_Resource") -public final class ManagedResource implements EnsoObject { +public final class ManagedResource extends EnsoObject { private final Object resource; private final PhantomReference phantomReference; @@ -93,4 +94,11 @@ boolean hasType() { Type getType(@Bind("$node") Node node) { return EnsoContext.get(node).getBuiltins().managedResource(); } + + @ExportMessage + @TruffleBoundary + @Override + public String toDisplayString(boolean allowSideEffects) { + return resource.toString(); + } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/Ref.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/Ref.java index 8bf74270d09f..e9e1728cacc0 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/Ref.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/Ref.java @@ -1,7 +1,9 @@ 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.library.CachedLibrary; import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; import com.oracle.truffle.api.nodes.Node; @@ -13,7 +15,7 @@ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) @Builtin(pkg = "mutable", stdlibName = "Standard.Base.Runtime.Ref.Ref") -public final class Ref implements EnsoObject { +public final class Ref extends EnsoObject { private volatile Object value; /** @@ -68,4 +70,17 @@ boolean hasType() { Type getType(@Bind("$node") Node node) { return EnsoContext.get(node).getBuiltins().ref(); } + + @ExportMessage + Object toDisplayString( + boolean allowSideEffects, @CachedLibrary(limit = "3") InteropLibrary interop) { + return interop.toDisplayString(value, allowSideEffects); + } + + @TruffleBoundary + @Override + @ExportMessage.Ignore + public Object toDisplayString(boolean allowSideEffects) { + return toDisplayString(allowSideEffects, InteropLibrary.getUncached()); + } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/Type.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/Type.java index 53d1cf8a6e31..dedd9e4e55f9 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/Type.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/Type.java @@ -30,7 +30,7 @@ @ExportLibrary(TypesLibrary.class) @ExportLibrary(InteropLibrary.class) -public final class Type implements EnsoObject { +public final class Type extends EnsoObject { private final String name; private @CompilerDirectives.CompilationFinal ModuleScope.Builder definitionScope; @@ -279,7 +279,8 @@ boolean hasMetaParents(@CachedLibrary("this") InteropLibrary lib) { } @ExportMessage - String toDisplayString(boolean allowSideEffects) { + @Override + public String toDisplayString(boolean allowSideEffects) { return name; } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/atom/Atom.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/atom/Atom.java index 3ace353dc5b6..0666db5fdecf 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/atom/Atom.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/atom/Atom.java @@ -19,7 +19,6 @@ import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; -import org.enso.interpreter.EnsoLanguage; import org.enso.interpreter.runtime.callable.UnresolvedSymbol; import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition; import org.enso.interpreter.runtime.callable.function.Function; @@ -51,7 +50,7 @@ */ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) -public abstract class Atom implements EnsoObject { +public abstract class Atom extends EnsoObject { final AtomConstructor constructor; private Integer hashCode; @@ -383,6 +382,18 @@ static Object doUncached( } } + @Override + @TruffleBoundary + @ExportMessage.Ignore + public Object toDisplayString(boolean allowSideEffects) { + return toDisplayString( + allowSideEffects, + InteropLibrary.getUncached(), + WarningsLibrary.getUncached(), + InteropLibrary.getUncached(), + BranchProfile.getUncached()); + } + @ExportMessage Text toDisplayString( boolean allowSideEffects, @@ -419,16 +430,6 @@ Text toDisplayString( return Text.create(msg); } - @ExportMessage - Class getLanguage() { - return EnsoLanguage.class; - } - - @ExportMessage - boolean hasLanguage() { - return true; - } - @ExportMessage boolean hasType() { return true; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/atom/AtomConstructor.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/atom/AtomConstructor.java index 6f0a0a969c9b..c14a9ff7d995 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/atom/AtomConstructor.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/atom/AtomConstructor.java @@ -41,7 +41,7 @@ */ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) -public final class AtomConstructor implements EnsoObject { +public final class AtomConstructor extends EnsoObject { private final String name; private final Module definitionModule; @@ -414,7 +414,8 @@ Atom instantiate(Object... arguments) throws ArityException { @ExportMessage @TruffleBoundary - String toDisplayString(boolean allowSideEffects) { + @Override + public String toDisplayString(boolean allowSideEffects) { var sb = new StringBuilder(); sb.append("Constructor<").append(getDisplayName()).append(">"); for (var f : getFields()) { diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/atom/BoxingAtom.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/atom/BoxingAtom.java index 1ea74fb3326e..6f171807fa4f 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/atom/BoxingAtom.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/atom/BoxingAtom.java @@ -1,15 +1,19 @@ package org.enso.interpreter.runtime.data.atom; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; +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.profiles.BranchProfile; import java.util.List; import org.enso.interpreter.runtime.data.atom.UnboxingAtom.FieldGetterNode; import org.enso.interpreter.runtime.data.atom.UnboxingAtom.FieldSetterNode; +import org.enso.interpreter.runtime.warning.WarningsLibrary; /** * A version of {@link org.enso.interpreter.runtime.data.atom.Atom} that stores its fields in an @@ -82,6 +86,17 @@ void setField(int index, Object value) { fields[index] = value; } + @Override + @TruffleBoundary + public Object toDisplayString(boolean allowSideEffects) { + return toDisplayString( + allowSideEffects, + InteropLibrary.getUncached(), + WarningsLibrary.getUncached(), + InteropLibrary.getUncached(), + BranchProfile.getUncached()); + } + private static class InstantiatorNode extends UnboxingAtom.InstantiatorNode { @Override public Atom execute(AtomConstructor constructor, Layout layout, Object[] args) { diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/EnsoHashMap.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/EnsoHashMap.java index 2c761b1e214a..65261cebf96e 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/EnsoHashMap.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/EnsoHashMap.java @@ -36,7 +36,7 @@ @ExportLibrary(TypesLibrary.class) @ExportLibrary(InteropLibrary.class) @Builtin(stdlibName = "Standard.Base.Data.Dictionary.Dictionary", name = "Dictionary") -public final class EnsoHashMap implements EnsoObject { +public final class EnsoHashMap extends EnsoObject { private final EnsoHashMapBuilder mapBuilder; private final int generation; private final int size; @@ -166,7 +166,8 @@ Type getMetaObject(@Bind("$node") Node node) { @ExportMessage @TruffleBoundary - Object toDisplayString(boolean allowSideEffects) { + @Override + public Object toDisplayString(boolean allowSideEffects) { return toString(true); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashEntriesVector.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashEntriesVector.java index 3977dbcb8d70..d5db6d89d2cd 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashEntriesVector.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashEntriesVector.java @@ -15,7 +15,7 @@ * (array), and for Enso {@code Map.to_vector} method. May be empty. */ @ExportLibrary(InteropLibrary.class) -final class HashEntriesVector implements EnsoObject { +final class HashEntriesVector extends EnsoObject { private final EnsoObject[] entryPairs; private HashEntriesVector(Object[] keys, Object[] values) { @@ -73,8 +73,14 @@ void writeArrayElement(long index, Object value) throws UnsupportedMessageExcept throw UnsupportedMessageException.create(); } + @Override + @ExportMessage + public Object toDisplayString(boolean allowSideEffects) { + return "HashEntriesVector"; + } + @ExportLibrary(InteropLibrary.class) - static final class EntryPair implements EnsoObject { + static final class EntryPair extends EnsoObject { private final Object key; private final Object value; @@ -126,7 +132,8 @@ void writeArrayElement(long index, Object value) throws UnsupportedMessageExcept @TruffleBoundary @ExportMessage - Object toDisplayString(boolean sideEffectsAllowed) { + @Override + public String toDisplayString(boolean sideEffectsAllowed) { return "(" + key + ", " + value + ")"; } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapGetNode.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapGetNode.java index 414bdae224c4..d710c40be86b 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapGetNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapGetNode.java @@ -34,6 +34,10 @@ public static HashMapGetNode build() { return HashMapGetNodeGen.create(); } + public static HashMapGetNode getUncached() { + return HashMapGetNodeGen.getUncached(); + } + public abstract Object execute( VirtualFrame frame, State state, Object self, Object key, @Suspend Object defaultValue); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapInsertNode.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapInsertNode.java index d2cca32666e1..263a11125999 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapInsertNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapInsertNode.java @@ -32,6 +32,10 @@ public static HashMapInsertNode build() { return HashMapInsertNodeGen.create(); } + public static HashMapInsertNode getUncached() { + return HashMapInsertNodeGen.getUncached(); + } + public abstract EnsoHashMap execute(VirtualFrame frame, Object self, Object key, Object value); @Specialization 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 5a882bf17e02..7ae2fac6fbc1 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 @@ -25,7 +25,7 @@ /** The main runtime type for Enso's Text. */ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) -public final class Text implements EnsoObject { +public final class Text extends EnsoObject { private static final Lock LOCK = new ReentrantLock(); private static final Text EMPTY = new Text(""); private volatile Object contents; @@ -197,6 +197,12 @@ private int computeLength() { return Core_Text_Utils.computeGraphemeLength(toString()); } + @Override + @ExportMessage.Ignore + public Object toDisplayString(boolean allowSideEffects) { + return toDisplayString(allowSideEffects, ToJavaStringNode.getUncached()); + } + @CompilerDirectives.TruffleBoundary @ExportMessage String toDisplayString( 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 abebac6de618..d70ad6b44fda 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 @@ -1,6 +1,7 @@ package org.enso.interpreter.runtime.data.vector; 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; @@ -32,7 +33,7 @@ @ExportLibrary(TypesLibrary.class) @ExportLibrary(WarningsLibrary.class) @Builtin(pkg = "mutable", stdlibName = "Standard.Base.Data.Array.Array") -final class Array implements EnsoObject { +final class Array extends EnsoObject { private final Object[] items; /** If true, some elements contain warning, and thus, this Array contains warning. */ @@ -152,7 +153,9 @@ boolean isArrayElementReadable(long index) { } @ExportMessage - String toDisplayString(boolean b) { + @TruffleBoundary + @Override + public String toDisplayString(boolean b) { return toString(); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayBuilder.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayBuilder.java index c15ab12d5567..5da2ece85bdf 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayBuilder.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayBuilder.java @@ -15,7 +15,7 @@ import org.enso.interpreter.runtime.warning.WarningsLibrary; @ExportLibrary(InteropLibrary.class) -final class ArrayBuilder implements EnsoObject { +final class ArrayBuilder extends EnsoObject { private static final String[] MEMBERS = new String[] {"isEmpty", "add", "appendTo", "get", "getSize", "toArray"}; private final int initialCapacity; @@ -238,7 +238,8 @@ EnsoObject getMembers(boolean includeInternal) { } @ExportMessage - String toDisplayString(boolean ignore) { + @Override + public String toDisplayString(boolean ignore) { return "Array_Builder"; } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayOverBuffer.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayOverBuffer.java index 6e613ece6084..94fb20ec16c3 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayOverBuffer.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArrayOverBuffer.java @@ -1,5 +1,6 @@ package org.enso.interpreter.runtime.data.vector; +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.InvalidArrayIndexException; @@ -14,7 +15,7 @@ @ExportLibrary(TypesLibrary.class) @ExportLibrary(InteropLibrary.class) -final class ArrayOverBuffer implements EnsoObject { +final class ArrayOverBuffer extends EnsoObject { private final ByteBuffer buffer; private ArrayOverBuffer(ByteBuffer buffer) { @@ -61,7 +62,9 @@ static ArrayOverBuffer wrapBuffer(ByteBuffer buffer) { } @ExportMessage - String toDisplayString(boolean allowSideEffects) { + @TruffleBoundary + @Override + public String toDisplayString(boolean allowSideEffects) { final InteropLibrary iop = InteropLibrary.getUncached(); return DisplayArrayUtils.toDisplayString(this, allowSideEffects, iop); } 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 802c20949f2b..0aca184e7e45 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 @@ -1,6 +1,7 @@ package org.enso.interpreter.runtime.data.vector; 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; @@ -28,7 +29,7 @@ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) @ImportStatic(BranchProfile.class) -final class ArrayProxy implements EnsoObject { +final class ArrayProxy extends EnsoObject { private final long length; private final Object at; @@ -76,7 +77,9 @@ public Object readArrayElement( } @ExportMessage - String toDisplayString(boolean b) { + @TruffleBoundary + @Override + public String toDisplayString(boolean b) { return toString(); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArraySlice.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArraySlice.java index e21ff318945f..67b47a94e3a8 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArraySlice.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArraySlice.java @@ -1,6 +1,7 @@ package org.enso.interpreter.runtime.data.vector; 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; @@ -23,7 +24,7 @@ @ExportLibrary(TypesLibrary.class) @ExportLibrary(InteropLibrary.class) @ExportLibrary(WarningsLibrary.class) -final class ArraySlice implements EnsoObject { +final class ArraySlice extends EnsoObject { private final Object storage; private final long start; private final long end; @@ -184,4 +185,11 @@ Type getType(@Bind("$node") Node node) { var ctx = EnsoContext.get(node); return ctx.getBuiltins().array(); } + + @Override + @ExportMessage + @TruffleBoundary + public Object toDisplayString(boolean allowSideEffects) { + return "ArraySlice{" + start + ", " + end + "}"; + } } 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 01756437f110..9893427ad676 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 @@ -23,7 +23,7 @@ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) @Builtin(pkg = "immutable", stdlibName = "Standard.Base.Data.Vector.Vector") -abstract class Vector implements EnsoObject { +abstract class Vector extends EnsoObject { 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]); @@ -72,7 +72,8 @@ final void removeArrayElement(long index) throws UnsupportedMessageException { @ExportMessage @CompilerDirectives.TruffleBoundary - String toDisplayString(boolean allowSideEffects) { + @Override + public String toDisplayString(boolean allowSideEffects) { final InteropLibrary iop = InteropLibrary.getUncached(); return DisplayArrayUtils.toDisplayString(this, allowSideEffects, iop); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java index 46489bb3dbb3..1216a7c958f2 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java @@ -20,7 +20,6 @@ import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode; import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.callable.UnresolvedSymbol; -import org.enso.interpreter.runtime.data.EnsoObject; import org.enso.interpreter.runtime.data.Type; import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers; import org.enso.interpreter.runtime.library.dispatch.TypesLibrary; @@ -36,7 +35,7 @@ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) @ImportStatic(PanicException.class) -public final class DataflowError extends AbstractTruffleException implements EnsoObject { +public final class DataflowError extends AbstractTruffleException { /** Signals (local) values that haven't yet been initialized */ public static final DataflowError UNINITIALIZED = new DataflowError(null, (Node) null); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/PanicException.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/PanicException.java index c85698eef44b..a21f0ad9b0bf 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/PanicException.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/PanicException.java @@ -21,7 +21,6 @@ import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.callable.UnresolvedSymbol; import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo; -import org.enso.interpreter.runtime.data.EnsoObject; import org.enso.interpreter.runtime.data.Type; import org.enso.interpreter.runtime.data.atom.Atom; import org.enso.interpreter.runtime.data.text.Text; @@ -33,7 +32,7 @@ /** An exception type for user thrown panic exceptions. */ @ExportLibrary(value = InteropLibrary.class, delegateTo = "payload") @ExportLibrary(TypesLibrary.class) -public final class PanicException extends AbstractTruffleException implements EnsoObject { +public final class PanicException extends AbstractTruffleException { final Object payload; private String cacheMessage; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/PanicSentinel.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/PanicSentinel.java index 643c527f8ff9..2d64b1f5d21c 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/PanicSentinel.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/PanicSentinel.java @@ -4,7 +4,6 @@ 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.runtime.data.EnsoObject; import org.enso.interpreter.runtime.library.dispatch.TypesLibrary; /** @@ -14,7 +13,7 @@ * not function in textual mode. */ @ExportLibrary(TypesLibrary.class) -public final class PanicSentinel extends AbstractTruffleException implements EnsoObject { +public final class PanicSentinel extends AbstractTruffleException { final PanicException panic; /** 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 00dc63ae935e..961d31e88027 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 @@ -17,7 +17,7 @@ /** Internal wrapper for a {@link BigInteger}. */ @ExportLibrary(InteropLibrary.class) @ExportLibrary(TypesLibrary.class) -public final class EnsoBigInteger implements EnsoObject { +public final class EnsoBigInteger extends EnsoObject { private final BigInteger value; /** @@ -45,7 +45,8 @@ public String toString() { @CompilerDirectives.TruffleBoundary @ExportMessage - String toDisplayString(boolean allowSideEffects) { + @Override + public String toDisplayString(boolean allowSideEffects) { return value.toString(); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/DebugLocalScope.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/DebugLocalScope.java index dcec2f91e0a8..8a8bf4f4cfd5 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/DebugLocalScope.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/DebugLocalScope.java @@ -1,7 +1,6 @@ package org.enso.interpreter.runtime.scope; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.UnknownIdentifierException; @@ -17,7 +16,6 @@ import java.util.Map.Entry; import java.util.stream.Collectors; import org.enso.compiler.pass.analyse.FramePointer; -import org.enso.interpreter.EnsoLanguage; import org.enso.interpreter.node.EnsoRootNode; import org.enso.interpreter.runtime.callable.function.Function; import org.enso.interpreter.runtime.data.EnsoObject; @@ -35,7 +33,7 @@ * */ @ExportLibrary(InteropLibrary.class) -public class DebugLocalScope implements EnsoObject { +public class DebugLocalScope extends EnsoObject { private final EnsoRootNode rootNode; /** All the bindings, including the parent scopes. */ @@ -119,16 +117,6 @@ private static List> gatherBindingsByLevels(Map> getLanguage() { - return EnsoLanguage.class; - } - @ExportMessage boolean isScope() { return true; @@ -245,7 +233,8 @@ SourceSection getSourceLocation() { @ExportMessage @TruffleBoundary - String toDisplayString(boolean allowSideEffects) { + @Override + public String toDisplayString(boolean allowSideEffects) { return rootNode.toString(); } @@ -277,7 +266,7 @@ private MaterializedFrame getProperFrame(MaterializedFrame frame, FramePointer p /** Simple interop wrapper for a list of strings. */ @ExportLibrary(InteropLibrary.class) - static final class ScopeMembers implements EnsoObject { + static final class ScopeMembers extends EnsoObject { private final List memberNames; ScopeMembers(List memberNames) { @@ -308,5 +297,12 @@ String readArrayElement(long index) { public String toString() { return memberNames.toString(); } + + @Override + @ExportMessage + @TruffleBoundary + public Object toDisplayString(boolean allowSideEffects) { + return toString(); + } } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/ImportExportScope.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/ImportExportScope.java index 1b8637fd7e96..2d46bd8f8949 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/ImportExportScope.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/ImportExportScope.java @@ -1,5 +1,6 @@ package org.enso.interpreter.runtime.scope; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import java.util.List; import org.enso.compiler.context.CompilerContext; import org.enso.interpreter.runtime.Module; @@ -11,7 +12,7 @@ * A proxy scope delegating to the underlying module's scope. Additionally, `ImportExportScope` may * limit the number of types that are imported/exported. */ -public class ImportExportScope implements EnsoObject { +public class ImportExportScope extends EnsoObject { private final Module module; private final List typesOnlyNames; @@ -67,4 +68,10 @@ public Function getConversionForType(Type target, Type type) { return null; } } + + @Override + @TruffleBoundary + public Object toDisplayString(boolean allowSideEffects) { + return "ImportExportScope{" + module.getName().toString() + "}"; + } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/ModuleScope.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/ModuleScope.java index 8cfeb1837a2d..92d09901c40e 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/ModuleScope.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/ModuleScope.java @@ -1,6 +1,7 @@ package org.enso.interpreter.runtime.scope; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; @@ -20,7 +21,7 @@ /** A representation of Enso's per-file top-level scope. */ @ExportLibrary(TypesLibrary.class) -public final class ModuleScope implements EnsoObject { +public final class ModuleScope extends EnsoObject { private final Type associatedType; private final Module module; private final Map> polyglotSymbols; @@ -290,6 +291,12 @@ public String toString() { return "Scope" + module; } + @Override + @TruffleBoundary + public Object toDisplayString(boolean allowSideEffects) { + return toString(); + } + public static class Builder { @CompilerDirectives.CompilationFinal private ModuleScope moduleScope = null; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/TopLevelScope.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/TopLevelScope.java index c71f2c6315a6..444cf84032bf 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/TopLevelScope.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/scope/TopLevelScope.java @@ -17,7 +17,6 @@ import org.enso.common.MethodNames; import org.enso.compiler.PackageRepository; import org.enso.editions.LibraryName; -import org.enso.interpreter.EnsoLanguage; import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.Module; import org.enso.interpreter.runtime.builtin.Builtins; @@ -30,7 +29,7 @@ /** Represents the top scope of Enso execution, containing all the importable modules. */ @ExportLibrary(InteropLibrary.class) -public final class TopLevelScope implements EnsoObject { +public final class TopLevelScope extends EnsoObject { private final Builtins builtins; private final PackageRepository packageRepository; @@ -263,26 +262,6 @@ Object getScopeParent() throws UnsupportedMessageException { throw UnsupportedMessageException.create(); } - /** - * Checks if this value is associated with a language. - * - * @return {@code true} - */ - @ExportMessage - final boolean hasLanguage() { - return true; - } - - /** - * Returns the language associated with this scope value. - * - * @return the language with which this value is associated - */ - @ExportMessage - final Class getLanguage() { - return EnsoLanguage.class; - } - /** * Converts this scope to a human readable string. * @@ -290,7 +269,8 @@ final Class getLanguage() { * @return a string representation of this scope */ @ExportMessage - final Object toDisplayString(boolean allowSideEffects) { + @Override + public Object toDisplayString(boolean allowSideEffects) { return "Enso.Top_Scope"; } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/AppendWarningNode.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/AppendWarningNode.java index 1377816f5fd4..a4dda4e9d25e 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/AppendWarningNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/AppendWarningNode.java @@ -13,7 +13,6 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.ConditionProfile; import org.enso.interpreter.runtime.EnsoContext; -import org.enso.interpreter.runtime.data.EnsoObject; import org.enso.interpreter.runtime.data.hash.EnsoHashMap; import org.enso.interpreter.runtime.data.hash.HashMapInsertAllNode; import org.enso.interpreter.runtime.data.hash.HashMapInsertNode; @@ -42,7 +41,7 @@ public static AppendWarningNode getUncached() { * It is expected that all the elements in the container are of {@link Warning} class. * @return A wrapped object with warnings */ - public abstract EnsoObject executeAppend(VirtualFrame frame, Object object, Object warnings); + public abstract Object executeAppend(VirtualFrame frame, Object object, Object warnings); @Specialization(guards = "!isError(object)") WithWarnings doSingleWarning( @@ -175,8 +174,8 @@ WithWarnings doMultipleWarningsInterop( } @Specialization(guards = "isError(object)") - EnsoObject dontAnnotateError(Object object, Object ignoreWarnings) { - return (EnsoObject) object; + Object dontAnnotateError(Object object, Object ignoreWarnings) { + return object; } /** Inserts all {@code warnings} to the {@code initialWarningMap}. */ 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 84c2aa729ad3..27096e7881f5 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 @@ -20,8 +20,9 @@ @Builtin(pkg = "error", stdlibName = "Standard.Base.Warning.Warning") @ExportLibrary(TypesLibrary.class) -public final class Warning implements EnsoObject { - private final Object value; +@ExportLibrary(value = InteropLibrary.class, delegateTo = "value") +public final class Warning extends EnsoObject { + final Object value; private final Object origin; private final long sequenceId; @@ -57,7 +58,8 @@ public static Warning create(EnsoContext ctx, Object payload, Object origin) { description = "Attaches the given warning to the value.", autoRegister = false) @Builtin.Specialize - public static EnsoObject attach( + @SuppressWarnings("generic-enso-builtin-type") + public static Object attach( EnsoContext ctx, Object value, Object warning, @@ -105,6 +107,18 @@ public static EnsoHashMap fromArrayToMap(Warning[] warnings, HashMapInsertNode m return map; } + @ExportMessage + @TruffleBoundary + @Override + public Object toDisplayString(boolean enableSideEffects) { + return toString(); + } + + @ExportMessage + boolean isNull() { + return false; + } + @CompilerDirectives.TruffleBoundary @Override public String toString() { diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/WithWarnings.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/WithWarnings.java index 5bd99c29db4a..7af4a4d304ba 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/WithWarnings.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/warning/WithWarnings.java @@ -1,6 +1,7 @@ package org.enso.interpreter.runtime.warning; 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; @@ -54,7 +55,7 @@ @ExportLibrary(WarningsLibrary.class) @ExportLibrary(ReflectionLibrary.class) @ExportLibrary(value = InteropLibrary.class, delegateTo = "value") -public final class WithWarnings implements EnsoObject { +public final class WithWarnings extends EnsoObject { final Object value; /** @@ -270,6 +271,19 @@ RuntimeException throwException(@Bind("$node") Node node) { throw asException(node); } + @TruffleBoundary + @Override + @ExportMessage.Ignore + public Object toDisplayString(boolean allowSideEffects) { + return toDisplayString(allowSideEffects, InteropLibrary.getUncached()); + } + + @ExportMessage + public Object toDisplayString( + boolean allowSideEffects, @CachedLibrary("this.value") InteropLibrary interop) { + return interop.toDisplayString(value, allowSideEffects); + } + @Override public String toString() { return "WithWarnings{"