-
Notifications
You must be signed in to change notification settings - Fork 326
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Builtins expose Enso methods (#11687)
* Add BuiltinsExposeMethodsTest * typo in docs * Test iteartes all the builtins and checks that all methods are invocable member * Add TypesExposeConstructorsTest * Naive implementation of BuiltinObject base class. * Ref extends BuiltinObject * Builtin type anot processor ensures that a class must extend BuiltinObject * Enrich BuiltinsExposeMethodsTest * All builtin types extend BuiltinObject * Text is BuiltinObject * EnsoBigInteger is BuiltinObject * BuiltinObject does no asserts in constructor * ArrayProxy is BuiltinObject * Test skips host values and Nothing * fmt * Remove outdated test. No longer true what this test tested * EqualsComplexNode: Timezone and duration are not treated as object with members * Fix DebuggingEnsoTest - Date in js is date time, not date * Fix DateTest - ensoDate now has members * Add interop.readMember test to BuiltinsExposeMethodsTest * VectorSortTest is executed in context * Add tests that invoke builtin methods on particular builtin types * member methods on BuiltinObject are behind TruffleBoundary * Cache builtin type in BuiltinObject. This fixes native image build of engine-runner. * Reuse context in DebuggingEnsoTest. This fixes the AssertionError in invalid sharing layer. * Reuse hardcoded builtinName constants from annotation * Move BuiltinObject to package org.enso.interpreter.runtime.builtin * Fix FQN of BuiltinObject in the annotation processor * Make exported messages on BuiltinObject final * Update generated class names in Builtins. Fixes compilation after 8acb04a * Exported messages in BuiltinObject are not behind TruffleBoundary * [WIP] Add BuiltinsJavaInteropTest * Storage.vectorizedOrFallbackBinaryMap accepts Value as parameter * Builtin types expose methods, not BuiltinObject * BuiltinObject has no members * Remove test Text.is_empty Text is a builtin type with Builtins module scope, which does not have `is_empty` method. * Fix tests - invocation is done via static methods * Type.InvokeMember uses InvokeFunctionNode instead of UnresolvedSymbol * fmt * Type.InvokeMember prepends receiver argument * Test invocation of File.path * Test invocation of Vector.to_text * Method fetching is done behind truffle boundary * Reassigning @CompilationFinal field should deoptimize * Fixes after merge * Add TruffleBoundary * Revert DateTest * Fix PrivateConstructor test * Methods on Type are internal members * fmt * Add TruffleBoundary * Revert Storage to develop * Remove FIXME comment * Simplify usages of Ref.get and Pth.root --------- Co-authored-by: Jaroslav Tulach <jaroslav.tulach@enso.org>
- Loading branch information
1 parent
3543bd9
commit c2f0925
Showing
11 changed files
with
496 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
...tests/src/test/java/org/enso/interpreter/test/builtins/BuiltinTypesExposeMethodsTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
package org.enso.interpreter.test.builtins; | ||
|
||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.hamcrest.Matchers.is; | ||
import static org.hamcrest.Matchers.notNullValue; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import org.enso.interpreter.runtime.data.Type; | ||
import org.enso.interpreter.runtime.library.dispatch.TypeOfNode; | ||
import org.enso.interpreter.test.ValuesGenerator; | ||
import org.enso.interpreter.test.ValuesGenerator.Language; | ||
import org.enso.test.utils.ContextUtils; | ||
import org.graalvm.polyglot.Context; | ||
import org.graalvm.polyglot.Value; | ||
import org.junit.AfterClass; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.junit.runners.Parameterized; | ||
import org.junit.runners.Parameterized.Parameters; | ||
|
||
/** | ||
* Gathers all the builtin objects from {@link ValuesGenerator}. From their types, gathers all their | ||
* methods via their {@link org.enso.interpreter.runtime.scope.ModuleScope definition scope} and | ||
* checks that {@link Value#canInvokeMember(String)} returns true. | ||
*/ | ||
@RunWith(Parameterized.class) | ||
public class BuiltinTypesExposeMethodsTest { | ||
private static Context ctx; | ||
|
||
private final Value type; | ||
|
||
public BuiltinTypesExposeMethodsTest(Value type) { | ||
this.type = type; | ||
} | ||
|
||
private static Context ctx() { | ||
if (ctx == null) { | ||
ctx = ContextUtils.createDefaultContext(); | ||
} | ||
return ctx; | ||
} | ||
|
||
@Parameters(name = "{index}: {0}") | ||
public static Iterable<Value> generateBuiltinObjects() { | ||
var valuesGenerator = ValuesGenerator.create(ctx(), Language.ENSO); | ||
var builtinTypes = new ArrayList<Value>(); | ||
ContextUtils.executeInContext( | ||
ctx(), | ||
() -> { | ||
valuesGenerator.allTypes().stream() | ||
.filter( | ||
val -> { | ||
var asType = getType(val); | ||
return !shouldSkipType(asType); | ||
}) | ||
.forEach(builtinTypes::add); | ||
return null; | ||
}); | ||
return builtinTypes; | ||
} | ||
|
||
private static Type getType(Value object) { | ||
var unwrapped = ContextUtils.unwrapValue(ctx(), object); | ||
return TypeOfNode.getUncached().findTypeOrNull(unwrapped); | ||
} | ||
|
||
@AfterClass | ||
public static void disposeCtx() { | ||
if (ctx != null) { | ||
ctx.close(); | ||
ctx = null; | ||
} | ||
} | ||
|
||
@Test | ||
public void builtinExposeMethods() { | ||
ContextUtils.executeInContext( | ||
ctx(), | ||
() -> { | ||
assertThat(type, is(notNullValue())); | ||
var typeDefScope = getType(type).getDefinitionScope(); | ||
var methodsDefinedInScope = typeDefScope.getMethodsForType(getType(type)); | ||
if (methodsDefinedInScope != null) { | ||
for (var methodInScope : methodsDefinedInScope) { | ||
var methodName = methodInScope.getName(); | ||
if (methodName.contains(".")) { | ||
var items = methodName.split("\\."); | ||
methodName = items[items.length - 1]; | ||
} | ||
assertThat( | ||
"Builtin type " + type + " should have members", type.hasMembers(), is(true)); | ||
assertThat( | ||
"Member " + methodName + " should be present", | ||
type.hasMember(methodName), | ||
is(true)); | ||
assertThat( | ||
"Member " + methodName + " should be invocable", | ||
type.canInvokeMember(methodName), | ||
is(true)); | ||
} | ||
} | ||
return null; | ||
}); | ||
} | ||
|
||
private static boolean shouldSkipType(Type type) { | ||
if (type == null) { | ||
return true; | ||
} | ||
if (!type.isBuiltin()) { | ||
return true; | ||
} | ||
var builtins = ContextUtils.leakContext(ctx()).getBuiltins(); | ||
var typesToSkip = | ||
List.of( | ||
builtins.function(), builtins.dataflowError(), builtins.warning(), builtins.nothing()); | ||
var shouldBeSkipped = typesToSkip.stream().anyMatch(toSkip -> toSkip == type); | ||
return shouldBeSkipped; | ||
} | ||
} |
Oops, something went wrong.