Send method pointers of constructors (#5593)

Closes #5043

Expression updates of constructors contain method pointers.
This commit is contained in:
Dmitry Bushev 2023-02-09 14:49:39 +03:00 committed by GitHub
parent 4ddb2eca26
commit b58a5f458b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 101 additions and 9 deletions

View File

@ -552,7 +552,7 @@ class RuntimeServerTest
context.consumeOut shouldEqual List("1")
}
it should "send method pointer updates" in {
it should "send method pointer updates of methods" in {
val contextId = UUID.randomUUID()
val requestId = UUID.randomUUID()
val moduleName = "Enso_Test.Test.Main"
@ -621,7 +621,7 @@ class RuntimeServerTest
Api.PushContextRequest(
contextId,
Api.StackItem.ExplicitCall(
Api.MethodPointer(moduleName, "Enso_Test.Test.Main", "main"),
Api.MethodPointer(moduleName, moduleName, "main"),
None,
Vector()
)
@ -646,7 +646,12 @@ class RuntimeServerTest
ConstantsGen.INTEGER,
Api.MethodPointer("Enso_Test.Test.Main", "Enso_Test.Test.Main", "bar")
),
TestMessages.update(contextId, idMainM, "Enso_Test.Test.A.AT"),
TestMessages.update(
contextId,
idMainM,
"Enso_Test.Test.A.AT",
Api.MethodPointer("Enso_Test.Test.A", "Enso_Test.Test.A.AT", "A")
),
TestMessages.update(
contextId,
idMainP,
@ -666,6 +671,80 @@ class RuntimeServerTest
context.consumeOut shouldEqual List("79")
}
it should "send method pointer updates of constructors" in {
val contextId = UUID.randomUUID()
val requestId = UUID.randomUUID()
val moduleName = "Enso_Test.Test.Main"
val metadata = new Metadata
val idA = metadata.addItem(47, 3, "aa")
val idB = metadata.addItem(59, 6, "ab")
val idC = metadata.addItem(70, 7, "ac")
val code =
"""type T
| A
| B x
| C y z
|
|main =
| a = T.A
| b = T.B 42
| T.C a b
|""".stripMargin.linesIterator.mkString("\n")
val contents = metadata.appendToCode(code)
val mainFile = context.writeMain(contents)
// create context
context.send(Api.Request(requestId, Api.CreateContextRequest(contextId)))
context.receive shouldEqual Some(
Api.Response(requestId, Api.CreateContextResponse(contextId))
)
// open file
context.send(
Api.Request(Api.OpenFileNotification(mainFile, contents))
)
context.receiveNone shouldEqual None
// push main
context.send(
Api.Request(
requestId,
Api.PushContextRequest(
contextId,
Api.StackItem.ExplicitCall(
Api.MethodPointer(moduleName, moduleName, "main"),
None,
Vector()
)
)
)
)
context.receiveN(5) should contain theSameElementsAs Seq(
Api.Response(requestId, Api.PushContextResponse(contextId)),
TestMessages.update(
contextId,
idA,
"Enso_Test.Test.Main.T",
Api.MethodPointer("Enso_Test.Test.Main", "Enso_Test.Test.Main.T", "A")
),
TestMessages.update(
contextId,
idB,
"Enso_Test.Test.Main.T",
Api.MethodPointer("Enso_Test.Test.Main", "Enso_Test.Test.Main.T", "B")
),
TestMessages.update(
contextId,
idC,
"Enso_Test.Test.Main.T",
Api.MethodPointer("Enso_Test.Test.Main", "Enso_Test.Test.Main.T", "C")
),
context.executionComplete(contextId)
)
}
it should "send updates from last line" in {
val contextId = UUID.randomUUID()
val requestId = UUID.randomUUID()

View File

@ -3059,6 +3059,9 @@ class RuntimeVisualizationsTest
s"$moduleName.Newtype",
payload = Api.ExpressionUpdate.Payload.Value(
Some(Api.ExpressionUpdate.Payload.Value.Warnings(1, Some("'x'")))
),
methodPointer = Some(
Api.MethodPointer(moduleName, s"$moduleName.Newtype", "Mk_Newtype")
)
),
context.executionComplete(contextId)

View File

@ -15,7 +15,9 @@ import org.enso.interpreter.instrument.profiling.ProfilingInfo;
import org.enso.interpreter.node.EnsoRootNode;
import org.enso.interpreter.node.MethodRootNode;
import org.enso.interpreter.node.callable.FunctionCallInstrumentationNode;
import org.enso.interpreter.node.expression.atom.QualifiedAccessorNode;
import org.enso.interpreter.runtime.Module;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.logger.masking.MaskedString;
import org.enso.pkg.QualifiedName;
@ -214,6 +216,11 @@ public interface IdExecutionService {
moduleName = methodNode.getModuleScope().getModule().getName();
typeName = methodNode.getType().getQualifiedName();
functionName = methodNode.getMethodName();
} else if (rootNode instanceof QualifiedAccessorNode qualifiedAccessor) {
AtomConstructor atomConstructor = qualifiedAccessor.getAtomConstructor();
moduleName = atomConstructor.getDefinitionScope().getModule().getName();
typeName = atomConstructor.getType().getQualifiedName();
functionName = atomConstructor.getDisplayName();
} else if (rootNode instanceof EnsoRootNode ensoRootNode) {
moduleName = ensoRootNode.getModuleScope().getModule().getName();
typeName = null;

View File

@ -23,6 +23,11 @@ public class QualifiedAccessorNode extends RootNode {
this.atomConstructor = atomConstructor;
}
/** @return the atom constructor. */
public AtomConstructor getAtomConstructor() {
return atomConstructor;
}
/**
* Executes the node, returning the predefined constructor.
*

View File

@ -51,8 +51,8 @@ public final class AtomConstructor implements TruffleObject {
/**
* Creates a new Atom constructor for a given name. The constructor is not valid until {@link
* AtomConstructor#initializeFields(LocalScope, ExpressionNode[], ExpressionNode[], Annotation[],
* ArgumentDefinition...)} is called.
* AtomConstructor#initializeFields(EnsoLanguage, LocalScope, ExpressionNode[], ExpressionNode[],
* Annotation[], ArgumentDefinition...)} is called.
*
* @param name the name of the Atom constructor
* @param definitionScope the scope in which this constructor was defined
@ -63,8 +63,8 @@ public final class AtomConstructor implements TruffleObject {
/**
* Creates a new Atom constructor for a given name. The constructor is not valid until {@link
* AtomConstructor#initializeFields(LocalScope, ExpressionNode[], ExpressionNode[], Annotation[],
* ArgumentDefinition...)} is called.
* AtomConstructor#initializeFields(EnsoLanguage, LocalScope, ExpressionNode[], ExpressionNode[],
* Annotation[], ArgumentDefinition...)} is called.
*
* @param name the name of the Atom constructor
* @param definitionScope the scope in which this constructor was defined

View File

@ -1,9 +1,7 @@
package org.enso.interpreter.runtime.callable.atom;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
/**
* A version of {@link org.enso.interpreter.runtime.callable.atom.Atom} that stores its fields in an