mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 13:02:07 +03:00
DataflowAnalysis preserves dependencies order (#6493)
close #6324 Changelog - feat: DataflowAnalysis compiler pass preserves the order of dependencies. This way when attaching the visualization to the sub-expression, the engine can find the first cached parent node, and properly invalidate it. - update: runtime visualization test is updated to reproduce the issue # Important Notes The dropdown for the column `"LOCATION"` is available right after the Restaurants project startup. ![2023-05-01-171700_1386x975_scrot](https://user-images.githubusercontent.com/357683/235466166-9d25cfa5-0e39-49a3-9c41-93cda59edb81.png)
This commit is contained in:
parent
5eb9c3a843
commit
84e59f1403
@ -3138,8 +3138,12 @@ class RuntimeVisualizationsTest
|
||||
val moduleName = "Enso_Test.Test.Main"
|
||||
val metadata = new Metadata
|
||||
|
||||
val idX = metadata.addItem(65, 1, "aa")
|
||||
val idY = metadata.addItem(65, 7, "ab")
|
||||
val idX = metadata.addItem(65, 1, "aa")
|
||||
val idY = metadata.addItem(65, 7, "ab")
|
||||
val idS = metadata.addItem(81, 1)
|
||||
val idZ = metadata.addItem(91, 5, "ac")
|
||||
val idZexprS = metadata.addItem(93, 1)
|
||||
val idZexpr1 = metadata.addItem(95, 1)
|
||||
|
||||
val code =
|
||||
"""type T
|
||||
@ -3150,7 +3154,11 @@ class RuntimeVisualizationsTest
|
||||
|main =
|
||||
| x = T.C
|
||||
| y = x.inc 7
|
||||
| y
|
||||
| s = 1
|
||||
| z = p y s
|
||||
| z
|
||||
|
|
||||
|p x y = x + y
|
||||
|""".stripMargin.linesIterator.mkString("\n")
|
||||
val contents = metadata.appendToCode(code)
|
||||
val mainFile = context.writeMain(contents)
|
||||
@ -3177,7 +3185,7 @@ class RuntimeVisualizationsTest
|
||||
Api.Request(requestId, Api.PushContextRequest(contextId, item1))
|
||||
)
|
||||
context.receiveNIgnorePendingExpressionUpdates(
|
||||
5
|
||||
9
|
||||
) should contain theSameElementsAs Seq(
|
||||
Api.Response(Api.BackgroundJobsStartedNotification()),
|
||||
Api.Response(requestId, Api.PushContextResponse(contextId)),
|
||||
@ -3188,6 +3196,15 @@ class RuntimeVisualizationsTest
|
||||
ConstantsGen.INTEGER_BUILTIN,
|
||||
Api.MethodPointer(moduleName, s"$moduleName.T", "inc")
|
||||
),
|
||||
TestMessages.update(contextId, idS, ConstantsGen.INTEGER_BUILTIN),
|
||||
TestMessages.update(
|
||||
contextId,
|
||||
idZ,
|
||||
ConstantsGen.INTEGER_BUILTIN,
|
||||
Api.MethodPointer(moduleName, moduleName, "p")
|
||||
),
|
||||
TestMessages.update(contextId, idZexprS, ConstantsGen.INTEGER_BUILTIN),
|
||||
TestMessages.update(contextId, idZexpr1, ConstantsGen.INTEGER_BUILTIN),
|
||||
context.executionComplete(contextId)
|
||||
)
|
||||
|
||||
|
@ -10,6 +10,7 @@ import org.enso.compiler.exception.CompilerError
|
||||
import org.enso.compiler.pass.IRPass
|
||||
import org.enso.compiler.pass.analyse.DataflowAnalysis.DependencyInfo.Type.asStatic
|
||||
|
||||
import scala.collection.immutable.ListSet
|
||||
import scala.collection.mutable
|
||||
|
||||
/** This pass implements dataflow analysis for Enso.
|
||||
@ -826,23 +827,39 @@ case object DataflowAnalysis extends IRPass {
|
||||
* @return the set of all associations with `key`, if key exists
|
||||
*/
|
||||
def get(key: DependencyInfo.Type): Option[Set[DependencyInfo.Type]] = {
|
||||
val visited = mutable.LinkedHashSet[DependencyInfo.Type]()
|
||||
|
||||
def go(key: DependencyInfo.Type): Set[DependencyInfo.Type] = {
|
||||
if (!visited.contains(key)) {
|
||||
visited += key
|
||||
|
||||
mapping.get(key) match {
|
||||
case Some(deps) => deps ++ deps.map(go).reduceLeft(_ ++ _)
|
||||
case None => Set()
|
||||
@scala.annotation.tailrec
|
||||
def go(
|
||||
queue: mutable.Queue[DependencyInfo.Type],
|
||||
visited: mutable.Set[DependencyInfo.Type],
|
||||
result: mutable.Set[DependencyInfo.Type]
|
||||
): Set[DependencyInfo.Type] =
|
||||
if (queue.isEmpty) result.to(ListSet)
|
||||
else {
|
||||
val elem = queue.dequeue()
|
||||
if (visited.contains(elem)) go(queue, visited, result)
|
||||
else {
|
||||
mapping.get(elem) match {
|
||||
case Some(deps) =>
|
||||
go(
|
||||
queue.enqueueAll(deps),
|
||||
visited.addOne(elem),
|
||||
result.addAll(deps)
|
||||
)
|
||||
case None =>
|
||||
go(queue, visited.addOne(elem), result)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Set()
|
||||
}
|
||||
}
|
||||
|
||||
if (mapping.contains(key)) {
|
||||
Some(go(key))
|
||||
Some(
|
||||
go(
|
||||
mutable.Queue(key),
|
||||
mutable.HashSet(),
|
||||
mutable.LinkedHashSet()
|
||||
)
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user