feat: multi type expression update

This commit is contained in:
Dmitry Bushev 2024-11-15 18:08:17 +00:00
parent 6b810ee1e6
commit de884a40e2
No known key found for this signature in database
GPG Key ID: 87C16090D6910E91
11 changed files with 422 additions and 353 deletions

View File

@ -108,20 +108,18 @@ object Runtime {
/** An update about the computed expression.
*
* @param expressionId the expression id
* @param expressionType the type of expression
* @param expressionTypes the type of expression
* @param methodCall the underlying method call of this expression
* @param profilingInfo profiling information about the execution of this
* expression
* @param fromCache whether or not the value for this expression came
* from the cache
* @param typeChanged whether or not the type of the value or method definition
* @param profilingInfo profiling information about the execution of this expression
* @param fromCache whether the value for this expression came from the cache
* @param typeChanged whether the type of the value or method definition
* has changed from the one that was cached, if any
* @param payload an extra information about the computed value
*/
@named("expressionUpdate")
case class ExpressionUpdate(
expressionId: ExpressionId,
expressionType: Option[String],
expressionTypes: Option[Vector[String]],
methodCall: Option[MethodCall],
profilingInfo: Vector[ProfilingInfo],
fromCache: Boolean,

View File

@ -17,7 +17,7 @@ import org.enso.interpreter.service.ExecutionService;
public final class RuntimeCache implements java.util.function.Function<String, Object> {
private final Map<UUID, Reference<Object>> cache = new HashMap<>();
private final Map<UUID, Reference<Object>> expressions = new HashMap<>();
private final Map<UUID, String> types = new HashMap<>();
private final Map<UUID, String[]> types = new HashMap<>();
private final Map<UUID, ExecutionService.FunctionCallInfo> calls = new HashMap<>();
private CachePreferences preferences = CachePreferences.empty();
private Consumer<UUID> observer;
@ -107,15 +107,15 @@ public final class RuntimeCache implements java.util.function.Function<String, O
* @return the previously cached type.
*/
@CompilerDirectives.TruffleBoundary
public String putType(UUID key, String typeName) {
return types.put(key, typeName);
public String[] putTypes(UUID key, String[] typeNames) {
return types.put(key, typeNames);
}
/**
* @return the cached type of the expression
*/
@CompilerDirectives.TruffleBoundary
public String getType(UUID key) {
public String[] getTypes(UUID key) {
return types.get(key);
}

View File

@ -15,6 +15,7 @@ import org.enso.interpreter.instrument.profiling.ExecutionTime;
import org.enso.interpreter.instrument.profiling.ProfilingInfo;
import org.enso.interpreter.node.callable.FunctionCallInstrumentationNode;
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
import org.enso.interpreter.runtime.data.EnsoMultiValue;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.library.dispatch.TypeOfNode;
import org.enso.interpreter.runtime.type.Constants;
@ -98,16 +99,16 @@ final class ExecutionCallbacks implements IdExecutionService.Callbacks {
@Override
public void updateCachedResult(IdExecutionService.Info info) {
Object result = info.getResult();
String resultType = typeOf(result);
String[] resultTypes = typeOf(result);
UUID nodeId = info.getId();
String cachedType = cache.getType(nodeId);
String[] cachedTypes = cache.getTypes(nodeId);
FunctionCallInfo call = functionCallInfoById(nodeId);
FunctionCallInfo cachedCall = cache.getCall(nodeId);
ProfilingInfo[] profilingInfo = new ProfilingInfo[] {new ExecutionTime(info.getElapsedTime())};
ExpressionValue expressionValue =
new ExpressionValue(
nodeId, result, resultType, cachedType, call, cachedCall, profilingInfo, false);
nodeId, result, resultTypes, cachedTypes, call, cachedCall, profilingInfo, false);
syncState.setExpressionUnsync(nodeId);
syncState.setVisualizationUnsync(nodeId);
@ -119,7 +120,7 @@ final class ExecutionCallbacks implements IdExecutionService.Callbacks {
cache.offer(nodeId, result);
cache.putCall(nodeId, call);
}
cache.putType(nodeId, resultType);
cache.putTypes(nodeId, resultTypes);
callOnComputedCallback(expressionValue);
executeOneshotExpressions(nodeId, result, info);
@ -165,7 +166,7 @@ final class ExecutionCallbacks implements IdExecutionService.Callbacks {
new ExpressionValue(
nodeId,
result,
cache.getType(nodeId),
cache.getTypes(nodeId),
typeOf(result),
calls.get(nodeId),
cache.getCall(nodeId),
@ -214,20 +215,29 @@ final class ExecutionCallbacks implements IdExecutionService.Callbacks {
return calls.get(nodeId);
}
private String typeOf(Object value) {
String resultType;
private String[] typeOf(Object value) {
if (value instanceof UnresolvedSymbol) {
resultType = Constants.UNRESOLVED_SYMBOL;
} else {
var typeOfNode = TypeOfNode.getUncached();
Object typeResult = value == null ? null : typeOfNode.execute(value);
if (typeResult instanceof Type t) {
resultType = getTypeQualifiedName(t);
} else {
resultType = null;
}
return new String[] {Constants.UNRESOLVED_SYMBOL};
}
return resultType;
if (value instanceof EnsoMultiValue multiValue) {
var valueTypes = multiValue.allTypes();
var resultTypes = new String[valueTypes.length];
for (int i = 0; i < valueTypes.length; i++) {
resultTypes[i] = getTypeQualifiedName(valueTypes[i]);
}
return resultTypes;
}
var typeOfNode = TypeOfNode.getUncached();
Object typeResult = value == null ? null : typeOfNode.execute(value);
if (typeResult instanceof Type t) {
return new String[] {getTypeQualifiedName(t)};
}
return null;
}
@CompilerDirectives.TruffleBoundary

View File

@ -661,8 +661,8 @@ public final class ExecutionService {
public static final class ExpressionValue {
private final UUID expressionId;
private final Object value;
private final String type;
private final String cachedType;
private final String[] types;
private final String[] cachedTypes;
private final FunctionCallInfo callInfo;
private final FunctionCallInfo cachedCallInfo;
private final ProfilingInfo[] profilingInfo;
@ -673,8 +673,8 @@ public final class ExecutionService {
*
* @param expressionId the id of the expression being computed.
* @param value the value returned by computing the expression.
* @param type the type of the returned value.
* @param cachedType the cached type of the value.
* @param types the type of the returned value.
* @param cachedTypes the cached type of the value.
* @param callInfo the function call data.
* @param cachedCallInfo the cached call data.
* @param profilingInfo the profiling information associated with this node
@ -683,16 +683,16 @@ public final class ExecutionService {
public ExpressionValue(
UUID expressionId,
Object value,
String type,
String cachedType,
String[] types,
String[] cachedTypes,
FunctionCallInfo callInfo,
FunctionCallInfo cachedCallInfo,
ProfilingInfo[] profilingInfo,
boolean wasCached) {
this.expressionId = expressionId;
this.value = value;
this.type = type;
this.cachedType = cachedType;
this.types = types;
this.cachedTypes = cachedTypes;
this.callInfo = callInfo;
this.cachedCallInfo = cachedCallInfo;
this.profilingInfo = profilingInfo;
@ -707,11 +707,11 @@ public final class ExecutionService {
+ expressionId
+ ", value="
+ (value == null ? "null" : new MaskedString(value.toString()).applyMasking())
+ ", type='"
+ type
+ ", types='"
+ Arrays.toString(types)
+ '\''
+ ", cachedType='"
+ cachedType
+ ", cachedTypes='"
+ Arrays.toString(cachedTypes)
+ '\''
+ ", callInfo="
+ callInfo
@ -734,15 +734,15 @@ public final class ExecutionService {
/**
* @return the type of the returned value.
*/
public String getType() {
return type;
public String[] getTypes() {
return types;
}
/**
* @return the cached type of the value.
*/
public String getCachedType() {
return cachedType;
public String[] getCachedTypes() {
return cachedTypes;
}
/**
@ -784,7 +784,7 @@ public final class ExecutionService {
* @return {@code true} when the type differs from the cached value.
*/
public boolean isTypeChanged() {
return !Objects.equals(type, cachedType);
return !Arrays.equals(types, cachedTypes);
}
/**

View File

@ -198,14 +198,14 @@ object ProgramExecutionSupport {
val notExecuted =
methodCallsCache.getNotExecuted(executionFrame.cache.getCalls)
notExecuted.forEach { expressionId =>
val expressionType = executionFrame.cache.getType(expressionId)
val expressionCall = executionFrame.cache.getCall(expressionId)
val expressionTypes = executionFrame.cache.getTypes(expressionId)
val expressionCall = executionFrame.cache.getCall(expressionId)
onCachedMethodCallCallback.accept(
new ExpressionValue(
expressionId,
null,
expressionType,
expressionType,
expressionTypes,
expressionTypes,
expressionCall,
expressionCall,
Array(ExecutionTime.empty()),
@ -391,7 +391,7 @@ object ProgramExecutionSupport {
expressionId
)
) ||
Types.isPanic(value.getType)
Types.isPanic(value.getTypes)
) {
val payload = value.getValue match {
case sentinel: PanicSentinel =>
@ -503,7 +503,7 @@ object ProgramExecutionSupport {
Set(
Api.ExpressionUpdate(
value.getExpressionId,
Option(value.getType),
Option(value.getTypes).map(_.toVector),
methodCall,
value.getProfilingInfo.map { case e: ExecutionTime =>
Api.ProfilingInfo.ExecutionTime(e.getNanoTimeElapsed)
@ -758,7 +758,7 @@ object ProgramExecutionSupport {
!value.wasCached() && !value.getValue.isInstanceOf[DataflowError]
for {
call <-
if (Types.isPanic(value.getType) || notCachedAndNotDataflowError)
if (Types.isPanic(value.getTypes) || notCachedAndNotDataflowError)
Option(value.getCallInfo)
else Option(value.getCallInfo).orElse(Option(value.getCachedCallInfo))
methodPointer <- toMethodPointer(call.functionPointer)

View File

@ -212,22 +212,11 @@ class RuntimeExecutionEnvironmentTest
)
context.receiveNIgnoreStdLib(3) should contain theSameElementsAs Seq(
Api.Response(requestId, Api.SetExecutionEnvironmentResponse(contextId)),
Api.Response(
None,
Api.ExpressionUpdates(
contextId,
Set(
Api.ExpressionUpdate(
idRes,
Some(ConstantsGen.NOTHING),
Some(IF_ENABLED_METH_CALL),
Vector(Api.ProfilingInfo.ExecutionTime(0)),
false,
true,
Api.ExpressionUpdate.Payload.Value()
)
)
)
TestMessages.update(
contextId,
idRes,
ConstantsGen.NOTHING,
IF_ENABLED_METH_CALL
),
context.executionComplete(contextId)
)
@ -334,22 +323,11 @@ class RuntimeExecutionEnvironmentTest
)
context.receiveNIgnoreStdLib(3) should contain theSameElementsAs Seq(
Api.Response(requestId, Api.SetExecutionEnvironmentResponse(contextId)),
Api.Response(
None,
Api.ExpressionUpdates(
contextId,
Set(
Api.ExpressionUpdate(
idRes,
Some(ConstantsGen.INTEGER),
Some(IF_ENABLED_METH_CALL),
Vector(Api.ProfilingInfo.ExecutionTime(0)),
false,
true,
Api.ExpressionUpdate.Payload.Value()
)
)
)
TestMessages.update(
contextId,
idRes,
ConstantsGen.INTEGER,
IF_ENABLED_METH_CALL
),
context.executionComplete(contextId)
)

View File

@ -0,0 +1,174 @@
package org.enso.interpreter.test.instrument
import org.apache.commons.io.output.TeeOutputStream
import org.enso.common.{LanguageInfo, MethodNames, RuntimeOptions}
import org.enso.interpreter.runtime.EnsoContext
import org.enso.interpreter.runtime.`type`.ConstantsGen
import org.enso.interpreter.test.Metadata
import org.enso.polyglot.RuntimeServerInfo
import org.enso.polyglot.runtime.Runtime.Api
import org.graalvm.polyglot.Context
import org.scalatest.BeforeAndAfterEach
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import java.io.{ByteArrayOutputStream, File}
import java.nio.file.{Files, Paths}
import java.util.UUID
@scala.annotation.nowarn("msg=multiarg infix syntax")
class RuntimeIntersectionTypesTest
extends AnyFlatSpec
with Matchers
with BeforeAndAfterEach {
// === Test Utilities =======================================================
var context: TestContext = _
class TestContext(packageName: String)
extends InstrumentTestContext(packageName) {
val out: ByteArrayOutputStream = new ByteArrayOutputStream()
val logOut: ByteArrayOutputStream = new ByteArrayOutputStream()
val context =
Context
.newBuilder(LanguageInfo.ID)
.allowExperimentalOptions(true)
.allowAllAccess(true)
.option(RuntimeOptions.PROJECT_ROOT, pkg.root.getAbsolutePath)
.option(
RuntimeOptions.LOG_LEVEL,
java.util.logging.Level.WARNING.getName
)
.option(RuntimeOptions.INTERPRETER_SEQUENTIAL_COMMAND_EXECUTION, "true")
.option(RuntimeOptions.ENABLE_PROJECT_SUGGESTIONS, "false")
.option(RuntimeOptions.ENABLE_GLOBAL_SUGGESTIONS, "false")
.option(RuntimeOptions.ENABLE_EXECUTION_TIMER, "false")
.option(RuntimeOptions.STRICT_ERRORS, "false")
.option(
RuntimeOptions.DISABLE_IR_CACHES,
InstrumentTestContext.DISABLE_IR_CACHE
)
.option(RuntimeServerInfo.ENABLE_OPTION, "true")
.option(RuntimeOptions.INTERACTIVE_MODE, "true")
.option(
RuntimeOptions.LANGUAGE_HOME_OVERRIDE,
Paths
.get("../../test/micro-distribution/component")
.toFile
.getAbsolutePath
)
.option(RuntimeOptions.EDITION_OVERRIDE, "0.0.0-dev")
.logHandler(new TeeOutputStream(logOut, System.err))
.out(new TeeOutputStream(out, System.err))
.serverTransport(runtimeServerEmulator.makeServerTransport)
.build()
lazy val languageContext = executionContext.context
.getBindings(LanguageInfo.ID)
.invokeMember(MethodNames.TopScope.LEAK_CONTEXT)
.asHostObject[EnsoContext]
def writeMain(contents: String): File =
Files.write(pkg.mainFile.toPath, contents.getBytes).toFile
def writeFile(file: File, contents: String): File =
Files.write(file.toPath, contents.getBytes).toFile
def writeInSrcDir(moduleName: String, contents: String): File = {
val file = new File(pkg.sourceDir, s"$moduleName.enso")
Files.write(file.toPath, contents.getBytes).toFile
}
def send(msg: Api.Request): Unit = runtimeServerEmulator.sendToRuntime(msg)
def consumeOut: List[String] = {
val result = out.toString
out.reset()
result.linesIterator.toList
}
def executionComplete(contextId: UUID): Api.Response =
Api.Response(Api.ExecutionComplete(contextId))
}
override protected def beforeEach(): Unit = {
context = new TestContext("Test")
context.init()
val Some(Api.Response(_, Api.InitializedNotification())) = context.receive
}
override protected def afterEach(): Unit = {
if (context != null) {
context.close()
context.out.reset()
context = null
}
}
it should "send expression updates" in {
val contextId = UUID.randomUUID()
val requestId = UUID.randomUUID()
val moduleName = "Enso_Test.Test.Main"
val metadata = new Metadata
val id_x = metadata.addItem(46, 3, "aa")
val code =
"""from Standard.Base import all
|
|main =
| x = foo
| x
|
|foo : Text & Integer
|foo = (42 : Text & Integer)
|
|Text.from that:Integer = that.to_text
|""".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(requestId, Api.OpenFileRequest(mainFile, contents))
)
context.receive shouldEqual Some(
Api.Response(Some(requestId), Api.OpenFileResponse)
)
// push main
context.send(
Api.Request(
requestId,
Api.PushContextRequest(
contextId,
Api.StackItem.ExplicitCall(
Api.MethodPointer(moduleName, moduleName, "main"),
None,
Vector()
)
)
)
)
context.receiveNIgnoreStdLib(3) should contain theSameElementsAs Seq(
Api.Response(requestId, Api.PushContextResponse(contextId)),
TestMessages.updateMultiType(
contextId,
id_x,
Vector(ConstantsGen.TEXT, ConstantsGen.INTEGER),
methodCall =
Some(Api.MethodCall(Api.MethodPointer(moduleName, moduleName, "foo")))
),
context.executionComplete(contextId)
)
}
}

View File

@ -7704,21 +7704,13 @@ object RuntimeServerTest {
fromCache: Boolean = false,
typeChanged: Boolean = true
): Api.Response =
Api.Response(
Api.ExpressionUpdates(
contextId,
Set(
Api.ExpressionUpdate(
Main.idMainX,
Some(ConstantsGen.INTEGER),
None,
Vector(Api.ProfilingInfo.ExecutionTime(0)),
fromCache,
typeChanged,
Api.ExpressionUpdate.Payload.Value()
)
)
)
TestMessages.update(
contextId,
Main.idMainX,
ConstantsGen.INTEGER,
fromCache,
typeChanged,
methodCall = None
)
def pendingZ(): Api.ExpressionUpdate =
@ -7748,29 +7740,19 @@ object RuntimeServerTest {
fromCache: Boolean = false,
typeChanged: Boolean = true
): Api.Response =
Api.Response(
Api.ExpressionUpdates(
contextId,
Set(
Api.ExpressionUpdate(
Main.idMainY,
Some(ConstantsGen.INTEGER),
Some(
Api.MethodCall(
Api.MethodPointer(
"Enso_Test.Test.Main",
ConstantsGen.NUMBER,
"foo"
)
)
),
Vector(Api.ProfilingInfo.ExecutionTime(0)),
fromCache,
typeChanged,
Api.ExpressionUpdate.Payload.Value()
)
TestMessages.update(
contextId,
Main.idMainY,
ConstantsGen.INTEGER,
Api.MethodCall(
Api.MethodPointer(
"Enso_Test.Test.Main",
ConstantsGen.NUMBER,
"foo"
)
)
),
fromCache,
typeChanged
)
def mainZ(
@ -7778,29 +7760,19 @@ object RuntimeServerTest {
fromCache: Boolean = false,
typeChanged: Boolean = true
): Api.Response =
Api.Response(
Api.ExpressionUpdates(
contextId,
Set(
Api.ExpressionUpdate(
Main.idMainZ,
Some(ConstantsGen.INTEGER),
Some(
Api.MethodCall(
Api.MethodPointer(
"Standard.Base.Data.Numbers",
ConstantsGen.INTEGER,
"+"
)
)
),
Vector(Api.ProfilingInfo.ExecutionTime(0)),
fromCache,
typeChanged,
Api.ExpressionUpdate.Payload.Value()
)
TestMessages.update(
contextId,
Main.idMainZ,
ConstantsGen.INTEGER,
Api.MethodCall(
Api.MethodPointer(
"Standard.Base.Data.Numbers",
ConstantsGen.INTEGER,
"+"
)
)
),
fromCache,
typeChanged
)
def fooY(
@ -7808,29 +7780,19 @@ object RuntimeServerTest {
fromCache: Boolean = false,
typeChanged: Boolean = true
): Api.Response =
Api.Response(
Api.ExpressionUpdates(
contextId,
Set(
Api.ExpressionUpdate(
Main.idFooY,
Some(ConstantsGen.INTEGER),
Some(
Api.MethodCall(
Api.MethodPointer(
"Standard.Base.Data.Numbers",
ConstantsGen.INTEGER,
"+"
)
)
),
Vector(Api.ProfilingInfo.ExecutionTime(0)),
fromCache,
typeChanged,
Api.ExpressionUpdate.Payload.Value()
)
TestMessages.update(
contextId,
Main.idFooY,
ConstantsGen.INTEGER,
Api.MethodCall(
Api.MethodPointer(
"Standard.Base.Data.Numbers",
ConstantsGen.INTEGER,
"+"
)
)
),
fromCache,
typeChanged
)
def fooZ(
@ -7838,29 +7800,19 @@ object RuntimeServerTest {
fromCache: Boolean = false,
typeChanged: Boolean = true
): Api.Response =
Api.Response(
Api.ExpressionUpdates(
contextId,
Set(
Api.ExpressionUpdate(
Main.idFooZ,
Some(ConstantsGen.INTEGER),
Some(
Api.MethodCall(
Api.MethodPointer(
"Standard.Base.Data.Numbers",
ConstantsGen.INTEGER,
"*"
)
)
),
Vector(Api.ProfilingInfo.ExecutionTime(0)),
fromCache,
typeChanged,
Api.ExpressionUpdate.Payload.Value()
)
TestMessages.update(
contextId,
Main.idFooZ,
ConstantsGen.INTEGER,
Api.MethodCall(
Api.MethodPointer(
"Standard.Base.Data.Numbers",
ConstantsGen.INTEGER,
"*"
)
)
),
fromCache,
typeChanged
)
}
}
@ -7893,53 +7845,29 @@ object RuntimeServerTest {
object Update {
def mainY(contextId: UUID) =
Api.Response(
Api.ExpressionUpdates(
contextId,
Set(
Api.ExpressionUpdate(
idMainY,
Some(ConstantsGen.INTEGER),
Some(
Api.MethodCall(
Api.MethodPointer(
"Enso_Test.Test.Main",
"Enso_Test.Test.Main",
"foo"
)
)
),
Vector(Api.ProfilingInfo.ExecutionTime(0)),
false,
true,
Api.ExpressionUpdate.Payload.Value()
)
TestMessages.update(
contextId,
idMainY,
ConstantsGen.INTEGER,
Api.MethodCall(
Api.MethodPointer(
"Enso_Test.Test.Main",
"Enso_Test.Test.Main",
"foo"
)
)
)
def mainZ(contextId: UUID) =
Api.Response(
Api.ExpressionUpdates(
contextId,
Set(
Api.ExpressionUpdate(
idMainZ,
Some(ConstantsGen.INTEGER),
Some(
Api.MethodCall(
Api.MethodPointer(
"Enso_Test.Test.Main",
"Enso_Test.Test.Main",
"bar"
)
)
),
Vector(Api.ProfilingInfo.ExecutionTime(0)),
false,
true,
Api.ExpressionUpdate.Payload.Value()
)
TestMessages.update(
contextId,
idMainZ,
ConstantsGen.INTEGER,
Api.MethodCall(
Api.MethodPointer(
"Enso_Test.Test.Main",
"Enso_Test.Test.Main",
"bar"
)
)
)

View File

@ -120,21 +120,13 @@ class RuntimeVisualizationsTest extends AnyFlatSpec with Matchers {
fromCache: Boolean = false,
typeChanged: Boolean = true
): Api.Response =
Api.Response(
Api.ExpressionUpdates(
contextId,
Set(
Api.ExpressionUpdate(
Main.idMainX,
Some(ConstantsGen.INTEGER),
None,
Vector(Api.ProfilingInfo.ExecutionTime(0)),
fromCache,
typeChanged,
Api.ExpressionUpdate.Payload.Value()
)
)
)
TestMessages.update(
contextId,
Main.idMainX,
ConstantsGen.INTEGER,
fromCache,
typeChanged,
methodCall = None
)
def mainY(
@ -142,29 +134,19 @@ class RuntimeVisualizationsTest extends AnyFlatSpec with Matchers {
fromCache: Boolean = false,
typeChanged: Boolean = true
): Api.Response =
Api.Response(
Api.ExpressionUpdates(
contextId,
Set(
Api.ExpressionUpdate(
Main.idMainY,
Some(ConstantsGen.INTEGER),
Some(
Api.MethodCall(
Api.MethodPointer(
"Enso_Test.Test.Main",
ConstantsGen.NUMBER,
"foo"
)
)
),
Vector(Api.ProfilingInfo.ExecutionTime(0)),
fromCache,
typeChanged,
Api.ExpressionUpdate.Payload.Value()
)
TestMessages.update(
contextId,
Main.idMainY,
ConstantsGen.INTEGER,
Api.MethodCall(
Api.MethodPointer(
"Enso_Test.Test.Main",
ConstantsGen.NUMBER,
"foo"
)
)
),
fromCache,
typeChanged
)
def mainZ(
@ -172,29 +154,19 @@ class RuntimeVisualizationsTest extends AnyFlatSpec with Matchers {
fromCache: Boolean = false,
typeChanged: Boolean = true
): Api.Response =
Api.Response(
Api.ExpressionUpdates(
contextId,
Set(
Api.ExpressionUpdate(
Main.idMainZ,
Some(ConstantsGen.INTEGER),
Some(
Api.MethodCall(
Api.MethodPointer(
"Standard.Base.Data.Numbers",
"Standard.Base.Data.Numbers.Integer",
"+"
)
)
),
Vector(Api.ProfilingInfo.ExecutionTime(0)),
fromCache,
typeChanged,
Api.ExpressionUpdate.Payload.Value()
)
TestMessages.update(
contextId,
Main.idMainZ,
ConstantsGen.INTEGER,
Api.MethodCall(
Api.MethodPointer(
"Standard.Base.Data.Numbers",
"Standard.Base.Data.Numbers.Integer",
"+"
)
)
),
fromCache,
typeChanged
)
def fooY(
@ -202,29 +174,19 @@ class RuntimeVisualizationsTest extends AnyFlatSpec with Matchers {
fromCache: Boolean = false,
typeChanged: Boolean = true
): Api.Response =
Api.Response(
Api.ExpressionUpdates(
contextId,
Set(
Api.ExpressionUpdate(
Main.idFooY,
Some(ConstantsGen.INTEGER),
Some(
Api.MethodCall(
Api.MethodPointer(
"Standard.Base.Data.Numbers",
"Standard.Base.Data.Numbers.Integer",
"+"
)
)
),
Vector(Api.ProfilingInfo.ExecutionTime(0)),
fromCache,
typeChanged,
Api.ExpressionUpdate.Payload.Value()
)
TestMessages.update(
contextId,
Main.idFooY,
ConstantsGen.INTEGER,
Api.MethodCall(
Api.MethodPointer(
"Standard.Base.Data.Numbers",
"Standard.Base.Data.Numbers.Integer",
"+"
)
)
),
fromCache,
typeChanged
)
def fooZ(
@ -232,29 +194,19 @@ class RuntimeVisualizationsTest extends AnyFlatSpec with Matchers {
fromCache: Boolean = false,
typeChanged: Boolean = true
): Api.Response =
Api.Response(
Api.ExpressionUpdates(
contextId,
Set(
Api.ExpressionUpdate(
Main.idFooZ,
Some(ConstantsGen.INTEGER),
Some(
Api.MethodCall(
Api.MethodPointer(
"Standard.Base.Data.Numbers",
"Standard.Base.Data.Numbers.Integer",
"*"
)
)
),
Vector(Api.ProfilingInfo.ExecutionTime(0)),
fromCache,
typeChanged,
Api.ExpressionUpdate.Payload.Value()
)
TestMessages.update(
contextId,
Main.idFooZ,
ConstantsGen.INTEGER,
Api.MethodCall(
Api.MethodPointer(
"Standard.Base.Data.Numbers",
"Standard.Base.Data.Numbers.Integer",
"*"
)
)
),
fromCache,
typeChanged
)
}
}

View File

@ -53,7 +53,7 @@ object TestMessages {
Set(
Api.ExpressionUpdate(
expressionId,
Some(expressionType),
Some(Vector(expressionType)),
None,
Vector(Api.ProfilingInfo.ExecutionTime(0)),
false,
@ -69,8 +69,8 @@ object TestMessages {
* @param contextId an identifier of the context
* @param expressionId an identifier of the expression
* @param expressionType a type of the expression
* @param fromCache whether or not the value for this expression came from cache
* @param typeChanged a flag indicating whether the the type of expression has changed
* @param fromCache whether the value for this expression came from cache
* @param typeChanged a flag indicating whether the type of expression has changed
* @param methodCall the method call
* @param payload the update payload
* @return the expression update response
@ -83,6 +83,36 @@ object TestMessages {
typeChanged: Boolean = true,
methodCall: Option[Api.MethodCall] = None,
payload: Api.ExpressionUpdate.Payload = Api.ExpressionUpdate.Payload.Value()
): Api.Response =
updateMultiType(
contextId,
expressionId,
Vector(expressionType),
fromCache,
typeChanged,
methodCall,
payload
)
/** Create an update response.
*
* @param contextId an identifier of the context
* @param expressionId an identifier of the expression
* @param expressionTypes types of the expression
* @param fromCache whether the value for this expression came from cache
* @param typeChanged a flag indicating whether the type of expression has changed
* @param methodCall the method call
* @param payload the update payload
* @return the expression update response
*/
def updateMultiType(
contextId: UUID,
expressionId: UUID,
expressionTypes: Vector[String],
fromCache: Boolean = false,
typeChanged: Boolean = true,
methodCall: Option[Api.MethodCall] = None,
payload: Api.ExpressionUpdate.Payload = Api.ExpressionUpdate.Payload.Value()
): Api.Response =
Api.Response(
Api.ExpressionUpdates(
@ -90,7 +120,7 @@ object TestMessages {
Set(
Api.ExpressionUpdate(
expressionId,
Some(expressionType),
Some(expressionTypes),
methodCall,
Vector(Api.ProfilingInfo.ExecutionTime(0)),
fromCache,
@ -123,9 +153,8 @@ object TestMessages {
* @param expressionId an identifier of the expression
* @param expressionType a type of the expression
* @param methodCall a pointer to the method definition
* @param fromCache whether or not the value for this expression came
* from the cache
* @param typeChanged a flag indicating whether the the type of expression has changed
* @param fromCache whether the value for this expression came from the cache
* @param typeChanged a flag indicating whether the type of expression has changed
* @return the expression update response
*/
def update(
@ -142,7 +171,7 @@ object TestMessages {
Set(
Api.ExpressionUpdate(
expressionId,
Some(expressionType),
Some(Vector(expressionType)),
Some(methodCall),
Vector(Api.ProfilingInfo.ExecutionTime(0)),
fromCache,
@ -158,9 +187,9 @@ object TestMessages {
* @param contextId an identifier of the context
* @param expressionId an identifier of the expression
* @param payload the error payload
* @param fromCache whether or not the value for this expression came
* @param fromCache whether the value for this expression came
* from the cache
* @param typeChanged a flag indicating whether the the type of expression has changed
* @param typeChanged a flag indicating whether the type of expression has changed
* @return the expression update response
*/
def error(
@ -207,9 +236,8 @@ object TestMessages {
* @param contextId an identifier of the context
* @param expressionId an identifier of the expression
* @param methodCall a pointer to the method definition
* @param fromCache whether or not the value for this expression came
* from the cache
* @param typeChanged a flag indicating whether the the type of expression has changed
* @param fromCache whether the value for this expression came from the cache
* @param typeChanged a flag indicating whether the type of expression has changed
* @param payload the error payload
* @return the expression update response
*/
@ -235,9 +263,8 @@ object TestMessages {
* @param contextId an identifier of the context
* @param expressionId an identifier of the expression
* @param methodCallOpt a pointer to the method definition
* @param fromCache whether or not the value for this expression came
* from the cache
* @param typeChanged a flag indicating whether the the type of expression has changed
* @param fromCache whether the value for this expression came from the cache
* @param typeChanged a flag indicating whether the type of expression has changed
* @param payload the error payload
* @return the expression update response
*/
@ -255,7 +282,7 @@ object TestMessages {
Set(
Api.ExpressionUpdate(
expressionId,
Some(ConstantsGen.ERROR),
Some(Vector(ConstantsGen.ERROR)),
methodCallOpt,
Vector(Api.ProfilingInfo.ExecutionTime(0)),
fromCache,
@ -379,7 +406,7 @@ object TestMessages {
* @param methodCall a pointer to the method definition
* @param payload the error payload
* @param builtin a flag indicating what is the type of Panic (a builtin Panic type or stdlib Panic)
* @param typeChanged a flag indicating whether the the type of expression has changed
* @param typeChanged a flag indicating whether the type of expression has changed
* @return the expression update response
*/
private def panicBuilder(
@ -414,7 +441,7 @@ object TestMessages {
Set(
Api.ExpressionUpdate(
expressionId,
builtin,
builtin.map(Vector(_)),
methodCall,
Vector(Api.ProfilingInfo.ExecutionTime(0)),
false,

View File

@ -3,6 +3,7 @@ package org.enso.interpreter.runtime.type;
import com.oracle.truffle.api.dsl.TypeSystem;
import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
import java.util.Arrays;
import org.enso.interpreter.runtime.callable.UnresolvedConversion;
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
import org.enso.interpreter.runtime.callable.function.Function;
@ -71,6 +72,7 @@ import org.enso.polyglot.data.TypeGraph;
public class Types {
private static final TypeGraph typeHierarchy = buildTypeHierarchy();
private static final String[] PANIC_TYPE = new String[] {ConstantsGen.PANIC};
/**
* A simple pair type
@ -119,8 +121,8 @@ public class Types {
}
/** Check if the given type is a panic. */
public static boolean isPanic(String typeName) {
return ConstantsGen.PANIC.equals(typeName);
public static boolean isPanic(String[] typeNames) {
return Arrays.equals(PANIC_TYPE, typeNames);
}
/**