Skip to content

Commit

Permalink
Implement hasLanguage interop message for all enso objects (#11538)
Browse files Browse the repository at this point in the history
* EnsoObject is an abstract class, not an interface.

- Also, EnsoObject exports hasLanguage and getLanguage interop messages.
- BranchRecord converted to class

* Implement public getters in BranchResult

* Fix compilation of EnsoFile

* Add test that all enso values must have language

* Revert EnsoException - remove

* DataflowError and PanicException implement hasLanguage and getLanguage

* DataflowError is not EnsoObject - change signatures in some builtins

* Add more members to Module.isMemberInvocable.

Keep in sync with doInvoke.

* Revert "DataflowError and PanicException implement hasLanguage and getLanguage"

This reverts commit b30f396.

* Update the test - test only non-primitive and non-exception values

* Fix indexes in CodeLocationsTest

* Add more members to Function.isMemberInvocable

Keep in sync with doInvoke.

* EnsoObject.toDisplayString delegates to toString method

* EnsoObject.toDisplayString is behind TruffleBoundary

* Warning exports InteropLibrary which delegates to value.

With the exception of toDisplayString message.

* WithWarnings needs to explicitly export toDisplayString.

It is not automatically delegated because it is implemented in the super type.

* EnsoObject.toDisplayString just throws AssertionError

* AssertionError is behind TruffleBoundary

* Implement toDisplayString on some truffle objects

* Warning exports WarningsLibrary

* Revert "Warning exports WarningsLibrary"

This reverts commit a06c672.

* Add some warnings test

* Warning.isNull is always false

Even if it wraps Nothing

* Add some unnecessary methods to fix the compilation

* EnsoObject.toDisplayString is abstract

* ImportExportScope.toDisplayString is behind TruffleBoundary.

This fixes native-image build of engine-runner.

* Hide some toDisplayString methods behind TruffleBoundary

This fixes native-image build of engine-runner.
Bypassing failing test.
  • Loading branch information
Akirathan authored and somebody1234 committed Nov 21, 2024
1 parent 1ddf95a commit e8dc0c2
Show file tree
Hide file tree
Showing 50 changed files with 552 additions and 175 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -272,6 +274,33 @@ public void numbersAreEitherIntegerOrFloat() throws Exception {
}
}

/**
* Primitive values and exceptions currently don't have an associated language.
*
* <p>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<Value> 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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<Warning> warns) {
var map = EnsoHashMap.empty();
var mapInsertNode = HashMapInsertNode.getUncached();
for (var warn : warns) {
map = mapInsertNode.execute(null, map, warn.getSequenceId(), warn);
}
return map;
}
}
Loading

0 comments on commit e8dc0c2

Please sign in to comment.