Editing the node is not changing the placeholders and widgets (#7595)

close #7462

# Important Notes
https://github.com/enso-org/enso/assets/357683/c2e68042-f64c-419e-b36e-7e99f0b43cd8
This commit is contained in:
Dmitry Bushev 2023-08-18 15:22:26 +01:00 committed by GitHub
parent d4e69192fd
commit 1d67667792
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 98 additions and 1 deletions

View File

@ -1,5 +1,6 @@
package org.enso.interpreter.instrument; package org.enso.interpreter.instrument;
import com.oracle.truffle.api.CompilerDirectives;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -16,6 +17,7 @@ public final class MethodCallsCache {
private final Set<UUID> callsExecuted = new HashSet<>(); private final Set<UUID> callsExecuted = new HashSet<>();
/** Save the executed method call. */ /** Save the executed method call. */
@CompilerDirectives.TruffleBoundary
public void setExecuted(UUID call) { public void setExecuted(UUID call) {
callsExecuted.add(call); callsExecuted.add(call);
} }

View File

@ -569,7 +569,9 @@ object ProgramExecutionSupport {
*/ */
private def toMethodCall(value: ExpressionValue): Option[Api.MethodCall] = private def toMethodCall(value: ExpressionValue): Option[Api.MethodCall] =
for { for {
call <- Option(value.getCallInfo).orElse(Option(value.getCachedCallInfo)) call <-
if (Types.isPanic(value.getType)) Option(value.getCallInfo)
else Option(value.getCallInfo).orElse(Option(value.getCachedCallInfo))
methodPointer <- toMethodPointer(call.functionPointer) methodPointer <- toMethodPointer(call.functionPointer)
} yield { } yield {
Api.MethodCall(methodPointer, call.notAppliedArguments.toVector) Api.MethodCall(methodPointer, call.notAppliedArguments.toVector)

View File

@ -276,6 +276,10 @@ public class IdExecutionInstrument extends TruffleInstrument implements IdExecut
passExpressionValueToCallback(expressionValue); passExpressionValueToCallback(expressionValue);
if (isPanic) { if (isPanic) {
// We mark the node as executed so that it is not reported as not executed call after the
// program execution is complete. If we clear the call from the cache instead, it will mess
// up the `typeChanged` field of the expression update.
callsCache.setExecuted(nodeId);
throw context.createUnwind(result); throw context.createUnwind(result);
} }
} }

View File

@ -2158,4 +2158,93 @@ class RuntimeErrorsTest
context.consumeOut shouldEqual Seq() context.consumeOut shouldEqual Seq()
} }
it should "not return cached method pointer when node panics" in {
val contextId = UUID.randomUUID()
val requestId = UUID.randomUUID()
val moduleName = "Enso_Test.Test.Main"
val metadata = new Metadata
val operator1Id = metadata.addItem(54, 17)
val code =
"""from Standard.Base import all
|
|main =
| operator1 = Main.function1 42
| operator1
|
|function1 x = x
|""".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 the new 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, "Enso_Test.Test.Main", "main"),
None,
Vector()
)
)
)
)
context.receiveNIgnoreStdLib(4) should contain theSameElementsAs Seq(
Api.Response(Api.BackgroundJobsStartedNotification()),
Api.Response(requestId, Api.PushContextResponse(contextId)),
TestMessages.update(
contextId,
operator1Id,
ConstantsGen.INTEGER,
Api.MethodCall(
Api.MethodPointer(moduleName, moduleName, "function1")
)
),
context.executionComplete(contextId)
)
// Modify the file
context.send(
Api.Request(
Api.EditFileNotification(
mainFile,
Seq(
TextEdit(
model.Range(model.Position(3, 29), model.Position(3, 30)),
"2"
)
),
execute = true
)
)
)
context.receiveNIgnoreStdLib(3) should contain theSameElementsAs Seq(
TestMessages.pending(contextId, operator1Id),
TestMessages.panic(
contextId,
operator1Id,
Api.ExpressionUpdate.Payload.Panic(
"Method `function2` of type Main could not be found.",
Seq(operator1Id)
)
),
context.executionComplete(contextId)
)
}
} }