mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 06:01:37 +03:00
Execute foreign function and check autoscoped constructor result (#10187)
Fixes #10151 and also fixes #10180 and fixes #10186.
This commit is contained in:
parent
d21140e422
commit
396d70ddc0
@ -1307,7 +1307,7 @@ class RuntimeServerTest
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "send method pointer updates of partially applied autoscope constructors" in {
|
it should "send error updates for partially applied autoscope constructors" in {
|
||||||
val contextId = UUID.randomUUID()
|
val contextId = UUID.randomUUID()
|
||||||
val requestId = UUID.randomUUID()
|
val requestId = UUID.randomUUID()
|
||||||
val moduleName = "Enso_Test.Test.Main"
|
val moduleName = "Enso_Test.Test.Main"
|
||||||
@ -1361,7 +1361,7 @@ class RuntimeServerTest
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
context.receiveN(4) should contain theSameElementsAs Seq(
|
context.receiveN(3) should contain theSameElementsAs Seq(
|
||||||
Api.Response(requestId, Api.PushContextResponse(contextId)),
|
Api.Response(requestId, Api.PushContextResponse(contextId)),
|
||||||
TestMessages.update(
|
TestMessages.update(
|
||||||
contextId,
|
contextId,
|
||||||
@ -1382,26 +1382,31 @@ class RuntimeServerTest
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
TestMessages.update(
|
Api.Response(
|
||||||
|
Api.ExecutionFailed(
|
||||||
contextId,
|
contextId,
|
||||||
id_x_1,
|
Api.ExecutionResult.Diagnostic.error(
|
||||||
ConstantsGen.FUNCTION_BUILTIN,
|
"Type_Error.Error",
|
||||||
methodCall = Some(
|
Some(mainFile),
|
||||||
Api.MethodCall(
|
Some(model.Range(model.Position(8, 0), model.Position(8, 12))),
|
||||||
Api.MethodPointer(moduleName, s"$moduleName.T", "A"),
|
None,
|
||||||
Vector(1)
|
Vector(
|
||||||
)
|
Api.StackTraceElement(
|
||||||
|
"Main.test",
|
||||||
|
Some(mainFile),
|
||||||
|
Some(model.Range(model.Position(8, 0), model.Position(8, 12))),
|
||||||
|
None
|
||||||
),
|
),
|
||||||
payload = Api.ExpressionUpdate.Payload.Value(
|
Api.StackTraceElement(
|
||||||
functionSchema = Some(
|
"Main.main",
|
||||||
Api.FunctionSchema(
|
Some(mainFile),
|
||||||
Api.MethodPointer(moduleName, s"$moduleName.T", "A"),
|
Some(model.Range(model.Position(4, 10), model.Position(4, 18))),
|
||||||
Vector(1)
|
None
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
|
||||||
context.executionComplete(contextId)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ public abstract class EnsoRootNode extends RootNode {
|
|||||||
super(language, buildFrameDescriptor(localScope));
|
super(language, buildFrameDescriptor(localScope));
|
||||||
Objects.requireNonNull(language);
|
Objects.requireNonNull(language);
|
||||||
Objects.requireNonNull(localScope);
|
Objects.requireNonNull(localScope);
|
||||||
|
Objects.requireNonNull(moduleScope);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.localScope = localScope;
|
this.localScope = localScope;
|
||||||
this.moduleScope = moduleScope;
|
this.moduleScope = moduleScope;
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
package org.enso.interpreter.node.callable;
|
package org.enso.interpreter.node.callable;
|
||||||
|
|
||||||
import com.oracle.truffle.api.CompilerDirectives;
|
import com.oracle.truffle.api.CompilerDirectives;
|
||||||
|
import com.oracle.truffle.api.dsl.Cached;
|
||||||
|
import com.oracle.truffle.api.dsl.Cached.Shared;
|
||||||
import com.oracle.truffle.api.dsl.Fallback;
|
import com.oracle.truffle.api.dsl.Fallback;
|
||||||
import com.oracle.truffle.api.dsl.Specialization;
|
import com.oracle.truffle.api.dsl.Specialization;
|
||||||
import com.oracle.truffle.api.frame.VirtualFrame;
|
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||||
|
import com.oracle.truffle.api.interop.ArityException;
|
||||||
|
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||||
import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
||||||
|
import com.oracle.truffle.api.interop.UnsupportedTypeException;
|
||||||
import com.oracle.truffle.api.library.CachedLibrary;
|
import com.oracle.truffle.api.library.CachedLibrary;
|
||||||
import com.oracle.truffle.api.nodes.Node;
|
import com.oracle.truffle.api.nodes.Node;
|
||||||
import com.oracle.truffle.api.source.SourceSection;
|
import com.oracle.truffle.api.source.SourceSection;
|
||||||
@ -12,6 +17,7 @@ import java.util.UUID;
|
|||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import org.enso.interpreter.Constants;
|
import org.enso.interpreter.Constants;
|
||||||
import org.enso.interpreter.node.BaseNode;
|
import org.enso.interpreter.node.BaseNode;
|
||||||
|
import org.enso.interpreter.node.BaseNode.TailStatus;
|
||||||
import org.enso.interpreter.node.callable.dispatch.InvokeFunctionNode;
|
import org.enso.interpreter.node.callable.dispatch.InvokeFunctionNode;
|
||||||
import org.enso.interpreter.node.callable.thunk.ThunkExecutorNode;
|
import org.enso.interpreter.node.callable.thunk.ThunkExecutorNode;
|
||||||
import org.enso.interpreter.runtime.EnsoContext;
|
import org.enso.interpreter.runtime.EnsoContext;
|
||||||
@ -29,6 +35,7 @@ import org.enso.interpreter.runtime.error.PanicSentinel;
|
|||||||
import org.enso.interpreter.runtime.error.Warning;
|
import org.enso.interpreter.runtime.error.Warning;
|
||||||
import org.enso.interpreter.runtime.error.WarningsLibrary;
|
import org.enso.interpreter.runtime.error.WarningsLibrary;
|
||||||
import org.enso.interpreter.runtime.error.WithWarnings;
|
import org.enso.interpreter.runtime.error.WithWarnings;
|
||||||
|
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
||||||
import org.enso.interpreter.runtime.state.State;
|
import org.enso.interpreter.runtime.state.State;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -278,7 +285,7 @@ public abstract class InvokeCallableNode extends BaseNode {
|
|||||||
VirtualFrame callerFrame,
|
VirtualFrame callerFrame,
|
||||||
State state,
|
State state,
|
||||||
Object[] arguments,
|
Object[] arguments,
|
||||||
@CachedLibrary(limit = "3") WarningsLibrary warnings) {
|
@Shared("warnings") @CachedLibrary(limit = "3") WarningsLibrary warnings) {
|
||||||
|
|
||||||
Warning[] extracted;
|
Warning[] extracted;
|
||||||
Object callable;
|
Object callable;
|
||||||
@ -323,6 +330,42 @@ public abstract class InvokeCallableNode extends BaseNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Specialization(
|
||||||
|
guards = {
|
||||||
|
"!warnings.hasWarnings(self)",
|
||||||
|
"!types.hasType(self)",
|
||||||
|
"!types.hasSpecialDispatch(self)",
|
||||||
|
"iop.isExecutable(self)",
|
||||||
|
})
|
||||||
|
Object doPolyglot(
|
||||||
|
Object self,
|
||||||
|
VirtualFrame frame,
|
||||||
|
State state,
|
||||||
|
Object[] arguments,
|
||||||
|
@CachedLibrary(limit = "3") InteropLibrary iop,
|
||||||
|
@Shared("warnings") @CachedLibrary(limit = "3") WarningsLibrary warnings,
|
||||||
|
@CachedLibrary(limit = "3") TypesLibrary types,
|
||||||
|
@Cached ThunkExecutorNode thunkNode) {
|
||||||
|
var errors = EnsoContext.get(this).getBuiltins().error();
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < arguments.length; i++) {
|
||||||
|
arguments[i] = thunkNode.executeThunk(frame, arguments[i], state, TailStatus.NOT_TAIL);
|
||||||
|
}
|
||||||
|
return iop.execute(self, arguments);
|
||||||
|
} catch (UnsupportedTypeException ex) {
|
||||||
|
var err = errors.makeUnsupportedArgumentsError(ex.getSuppliedValues(), ex.getMessage());
|
||||||
|
throw new PanicException(err, this);
|
||||||
|
} catch (ArityException ex) {
|
||||||
|
var err =
|
||||||
|
errors.makeArityError(
|
||||||
|
ex.getExpectedMinArity(), ex.getExpectedMaxArity(), arguments.length);
|
||||||
|
throw new PanicException(err, this);
|
||||||
|
} catch (UnsupportedMessageException ex) {
|
||||||
|
var err = errors.makeNotInvokable(self);
|
||||||
|
throw new PanicException(err, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
public Object invokeGeneric(
|
public Object invokeGeneric(
|
||||||
Object callable, VirtualFrame callerFrame, State state, Object[] arguments) {
|
Object callable, VirtualFrame callerFrame, State state, Object[] arguments) {
|
||||||
|
@ -30,9 +30,10 @@ import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
|
|||||||
import org.enso.interpreter.runtime.callable.function.Function;
|
import org.enso.interpreter.runtime.callable.function.Function;
|
||||||
import org.enso.interpreter.runtime.data.EnsoObject;
|
import org.enso.interpreter.runtime.data.EnsoObject;
|
||||||
import org.enso.interpreter.runtime.data.Type;
|
import org.enso.interpreter.runtime.data.Type;
|
||||||
|
import org.enso.interpreter.runtime.data.atom.Atom;
|
||||||
import org.enso.interpreter.runtime.data.atom.AtomConstructor;
|
import org.enso.interpreter.runtime.data.atom.AtomConstructor;
|
||||||
|
import org.enso.interpreter.runtime.error.PanicException;
|
||||||
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
||||||
import org.enso.interpreter.runtime.scope.ModuleScope;
|
|
||||||
import org.enso.interpreter.runtime.state.State;
|
import org.enso.interpreter.runtime.state.State;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -171,7 +172,8 @@ public final class UnresolvedConstructor implements EnsoObject {
|
|||||||
static DirectCallNode buildApplication(UnresolvedConstructor prototype) {
|
static DirectCallNode buildApplication(UnresolvedConstructor prototype) {
|
||||||
UUID id = null;
|
UUID id = null;
|
||||||
SourceSection section = null;
|
SourceSection section = null;
|
||||||
ModuleScope scope = null;
|
var scope =
|
||||||
|
prototype.where.getRootNode() instanceof EnsoRootNode root ? root.getModuleScope() : null;
|
||||||
for (var where = prototype.where; where != null; where = where.getParent()) {
|
for (var where = prototype.where; where != null; where = where.getParent()) {
|
||||||
if (where instanceof ExpressionNode withId && withId.getId() != null) {
|
if (where instanceof ExpressionNode withId && withId.getId() != null) {
|
||||||
id = withId.getId();
|
id = withId.getId();
|
||||||
@ -235,7 +237,7 @@ public final class UnresolvedConstructor implements EnsoObject {
|
|||||||
return invokeConstructor(c, unresolved.asPrototype(), unresolved, state, callNode);
|
return invokeConstructor(c, unresolved.asPrototype(), unresolved, state, callNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object invokeConstructor(
|
private Object invokeConstructor(
|
||||||
AtomConstructor c,
|
AtomConstructor c,
|
||||||
UnresolvedConstructor prototype,
|
UnresolvedConstructor prototype,
|
||||||
UnresolvedConstructor unresolved,
|
UnresolvedConstructor unresolved,
|
||||||
@ -254,7 +256,13 @@ public final class UnresolvedConstructor implements EnsoObject {
|
|||||||
args[0] = fn;
|
args[0] = fn;
|
||||||
var helper = Function.ArgumentsHelper.buildArguments(fn, null, state, args);
|
var helper = Function.ArgumentsHelper.buildArguments(fn, null, state, args);
|
||||||
var r = callNode.call(helper);
|
var r = callNode.call(helper);
|
||||||
|
if (r instanceof Atom) {
|
||||||
return r;
|
return r;
|
||||||
|
} else {
|
||||||
|
var ctx = EnsoContext.get(this);
|
||||||
|
var err = ctx.getBuiltins().error().makeTypeError(c.getType(), r, prototype.toString());
|
||||||
|
throw new PanicException(err, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object checkSingleton(Type c, UnresolvedConstructor unresolved) {
|
private static Object checkSingleton(Type c, UnresolvedConstructor unresolved) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from Standard.Base import all
|
from Standard.Base import all
|
||||||
|
import Standard.Base.Errors.Common.Not_Invokable
|
||||||
from Standard.Test import all
|
from Standard.Test import all
|
||||||
|
|
||||||
|
|
||||||
@ -34,6 +34,18 @@ add_specs suite_builder = suite_builder.group "Polyglot" group_builder->
|
|||||||
group_builder.specify "access Integer field from Polyglot object" <|
|
group_builder.specify "access Integer field from Polyglot object" <|
|
||||||
js_meaning.meaning . should_equal 42
|
js_meaning.meaning . should_equal 42
|
||||||
|
|
||||||
|
group_builder.specify "Execute JavaScript function" <|
|
||||||
|
js_plus 3 5 . should_equal 8
|
||||||
|
|
||||||
|
group_builder.specify "Execute JavaScript with insufficient number of arguments" <|
|
||||||
|
r = js_plus 3
|
||||||
|
r.is_nan . should_be_true
|
||||||
|
|
||||||
|
group_builder.specify "Cannot Execute JavaScript number" <|
|
||||||
|
fourty_two = js_meaning.meaning
|
||||||
|
Test.expect_panic Not_Invokable <|
|
||||||
|
fourty_two "Cannot invoke"
|
||||||
|
|
||||||
group_builder.specify "use Integer obtained from a call" <|
|
group_builder.specify "use Integer obtained from a call" <|
|
||||||
Java_Integer.parseInt "42" . should_equal 42
|
Java_Integer.parseInt "42" . should_equal 42
|
||||||
|
|
||||||
@ -50,6 +62,9 @@ add_specs suite_builder = suite_builder.group "Polyglot" group_builder->
|
|||||||
foreign js js_meaning = """
|
foreign js js_meaning = """
|
||||||
return { meaning : 6 * 7 };
|
return { meaning : 6 * 7 };
|
||||||
|
|
||||||
|
foreign js js_plus = """
|
||||||
|
return (a, b) => a + b;
|
||||||
|
|
||||||
main filter=Nothing =
|
main filter=Nothing =
|
||||||
suite = Test.build suite_builder->
|
suite = Test.build suite_builder->
|
||||||
add_specs suite_builder
|
add_specs suite_builder
|
||||||
|
@ -448,6 +448,21 @@ add_specs suite_builder =
|
|||||||
foo = v:Foo
|
foo = v:Foo
|
||||||
Foo.Value 10 . should_equal foo
|
Foo.Value 10 . should_equal foo
|
||||||
|
|
||||||
|
group_builder.specify "Foo.Value constructor is not autoscoped" <|
|
||||||
|
|
||||||
|
v = ..Value
|
||||||
|
err = Test.expect_panic Type_Error <|
|
||||||
|
f = v:Foo
|
||||||
|
f
|
||||||
|
|
||||||
|
msg = err.to_text
|
||||||
|
|
||||||
|
msg . should_contain "Type error:"
|
||||||
|
msg . should_contain "Expected `..Value` to be Foo"
|
||||||
|
msg . should_contain "got Foo.Value["
|
||||||
|
msg . should_contain "foo=_"
|
||||||
|
msg . should_contain "Try to apply foo argument"
|
||||||
|
|
||||||
group_builder.specify "..False can be autoscoped" <|
|
group_builder.specify "..False can be autoscoped" <|
|
||||||
|
|
||||||
bool b:Boolean = b
|
bool b:Boolean = b
|
||||||
|
Loading…
Reference in New Issue
Block a user