From 34c504b09223b9eaab189a3cc42141c4d4252eb3 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Thu, 4 May 2023 10:20:25 +0200 Subject: [PATCH 1/6] Test to tease ChangesetBuilder.invalidated with complex line expression --- .../test/context/ChangesetBuilderTest.scala | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala b/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala index b0854b754274..2d753caed28d 100644 --- a/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala +++ b/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala @@ -375,6 +375,59 @@ class ChangesetBuilderTest extends CompilerTest { ) } + "toggle defaulted boolean parameter" in { + implicit val moduleContext: ModuleContext = freshModuleContext + + val code = + """ + |from Standard.Base import all + |from Standard.Base.Data.Boolean import Boolean + |import Standard.Visualization + | + |main = + | text2 = " B B B " + | text1 = "B" + | text3 = "@" + | operator2 = text2.replace text1 text3 (Case_Sensitivity.Insensitive) + | + | + | + | + |#### METADATA #### + |[[{"index":{"value":5},"size":{"value":8}},"6d97d061-2c1d-4540-8f7d-3d8aa765323d"],[{"index":{"value":13},"size":{"value":1}},"a6a1b572-4867-4317-8a6e-b496b286ea2d"],[{"index":{"value":14},"size":{"value":4}},"b82e52c6-e2f0-4e16-b835-59ab8838cb2c"],[{"index":{"value":5},"size":{"value":13}},"4dd74fbb-c6df-4109-8821-f4643d483355"],[{"index":{"value":0},"size":{"value":29}},"82014253-a4f5-431b-971b-2348f5a2ca1f"],[{"index":{"value":35},"size":{"value":8}},"b22aad40-a237-4d47-a140-930d731ca80e"],[{"index":{"value":43},"size":{"value":1}},"9d7f45f1-f537-480d-b65f-37a90c77455a"],[{"index":{"value":44},"size":{"value":4}},"c6ad377f-1fce-431d-bbd7-cfe88624c50d"],[{"index":{"value":35},"size":{"value":13}},"202d7fa4-c782-4bb8-900f-7bf5f9ebad99"],[{"index":{"value":48},"size":{"value":1}},"6847cb14-aa49-455d-be9d-e82a39460005"],[{"index":{"value":49},"size":{"value":4}},"36dcdde8-1667-495a-ab87-7154c8d3be67"],[{"index":{"value":35},"size":{"value":18}},"d67c4ce2-711a-4dd9-a1f8-b48f2730b141"],[{"index":{"value":53},"size":{"value":1}},"295fa6b1-260d-4f23-8bd6-64a1d60f01e5"],[{"index":{"value":54},"size":{"value":7}},"923a2769-ddc0-4339-b919-941155a4d1b7"],[{"index":{"value":35},"size":{"value":26}},"64ef6c8a-810e-42f4-8334-8b12c4ab14bc"],[{"index":{"value":69},"size":{"value":7}},"e8cf68da-2b41-4c70-b163-567a223459fd"],[{"index":{"value":30},"size":{"value":46}},"0b934140-6464-4a05-ae6c-416670e2c7e2"],[{"index":{"value":84},"size":{"value":8}},"eaa41303-7d43-420f-8d64-da8d376fab65"],[{"index":{"value":92},"size":{"value":1}},"d582d163-0d4b-4406-96a3-e4591766406d"],[{"index":{"value":93},"size":{"value":13}},"2649f663-b1b8-44a1-9158-f2cf23038471"],[{"index":{"value":84},"size":{"value":22}},"5b4e8628-e0b7-408e-8070-e5636514c7ac"],[{"index":{"value":77},"size":{"value":29}},"78558eb9-cfb0-41d1-8f9a-0f0c17db3b7c"],[{"index":{"value":108},"size":{"value":4}},"58c9224e-644d-40c1-be25-068b6b6dc947"],[{"index":{"value":113},"size":{"value":1}},"d01b8ec7-e780-40a3-b401-97e89e000484"],[{"index":{"value":120},"size":{"value":5}},"aa43682d-01ee-453d-9bcb-34c905d8d314"],[{"index":{"value":126},"size":{"value":1}},"2b5d6c3f-e030-4ee4-9102-b573f066efa0"],[{"index":{"value":128},"size":{"value":16}},"54493640-4981-4437-ad6e-fc80ab1b581f"],[{"index":{"value":120},"size":{"value":24}},"c04888d6-bc60-4534-aa7e-df3dd5d52410"],[{"index":{"value":149},"size":{"value":5}},"85ae1943-cfcf-4e53-97c7-f73fdae42529"],[{"index":{"value":155},"size":{"value":1}},"113ae47b-3a1d-497e-8a2a-b7775be6c66e"],[{"index":{"value":157},"size":{"value":3}},"c143e355-9d64-4780-b387-dd364eefa2f9"],[{"index":{"value":149},"size":{"value":11}},"73113bd8-d3cb-4b06-a4d7-425a88bca849"],[{"index":{"value":165},"size":{"value":5}},"a286047b-54a5-45bb-995e-60f207e2af65"],[{"index":{"value":171},"size":{"value":1}},"abace020-1a84-4fa4-a5ee-2f98f73dfcb1"],[{"index":{"value":173},"size":{"value":3}},"ed3e40fb-d19e-4fb6-bebd-f74ee179ae08"],[{"index":{"value":165},"size":{"value":11}},"8ac6594b-c472-41d5-9b00-f13e6f30d5f2"],[{"index":{"value":181},"size":{"value":9}},"25eaa42e-026d-4afd-a433-dde5804b7a5c"],[{"index":{"value":191},"size":{"value":1}},"799a83db-5893-40f7-9f1e-e07c7a3071cd"],[{"index":{"value":193},"size":{"value":5}},"49332623-fe9a-4fe5-9657-7c0ea2b23942"],[{"index":{"value":198},"size":{"value":1}},"7690e4c2-31e7-4a12-8f5c-78c4484b9553"],[{"index":{"value":199},"size":{"value":7}},"3606a45e-50be-49c5-9dda-415263145a15"],[{"index":{"value":193},"size":{"value":13}},"91640cfc-f985-49da-95c8-87181d725299"],[{"index":{"value":207},"size":{"value":5}},"afb24ea2-2f35-4c7e-8394-3ba34626484e"],[{"index":{"value":193},"size":{"value":19}},"86eb77c6-14cc-487a-8993-bf9998244321"],[{"index":{"value":213},"size":{"value":5}},"52a3e9b8-f8d0-43c9-9f6d-9785359c7ba7"],[{"index":{"value":193},"size":{"value":25}},"1cddcb6a-95c8-445b-9a6f-267093b2609c"],[{"index":{"value":220},"size":{"value":16}},"df114ed3-b64d-4e74-ad60-b43a7147ec19"],[{"index":{"value":236},"size":{"value":1}},"b6a14995-bb54-4956-9abd-9b8cff898ad3"],[{"index":{"value":237},"size":{"value":11}},"fdf942d8-8064-4067-ae38-131b80fa6e0c"],[{"index":{"value":220},"size":{"value":28}},"b8df7e14-9004-4f61-8076-09354f8dbd36"],[{"index":{"value":219},"size":{"value":30}},"e2f06568-a771-4c07-9504-6c123e55825a"],[{"index":{"value":193},"size":{"value":56}},"0d4b3071-3f7d-472a-bfa7-af118222894e"],[{"index":{"value":181},"size":{"value":68}},"d9ee4c00-74b3-4859-a252-6c9105085076"],[{"index":{"value":115},"size":{"value":135}},"3eba123a-ea77-4db5-89d8-800d35e102e7"],[{"index":{"value":108},"size":{"value":142}},"11d6a77c-3644-4a27-8e15-16808af51c19"],[{"index":{"value":0},"size":{"value":251}},"9eb9e27a-81e2-416d-8aa7-367720ecc256"]] + |{"ide":{"node":{"ed3e40fb-d19e-4fb6-bebd-f74ee179ae08":{"position":{"vector":[52.000004,140.00055]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":null},"0d4b3071-3f7d-472a-bfa7-af118222894e":{"position":{"vector":[-100.0,-40.0]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":{"name":{"content":{"content":"JSON"}},"project":"Builtin"}},"54493640-4981-4437-ad6e-fc80ab1b581f":{"position":{"vector":[-111.0,140.00055]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":null},"c143e355-9d64-4780-b387-dd364eefa2f9":{"position":{"vector":[9.723406,95.0]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":null}},"import":{},"project":null}} + |""".stripMargin.linesIterator.mkString("\n") + val edit = + TextEdit(Range(Position(8, 88), Position(8, 88)), "Boolean.True") + + val ir = code.preprocessModule + val atId = "0d4b3071-3f7d-472a-bfa7-af118222894e" + val at = findIR(ir, atId) + val atCode = findCode(code, at) + atCode shouldBe "text2.replace text1 text3 (Case_Sensitivity.Insensitive)" + + invalidated(ir, code, edit) should contain theSameElementsAs Seq( + UUID.fromString(atId) + ) + invalidatedAll(ir, code, edit) should contain theSameElementsAs Seq( + UUID.fromString(atId) + ) + } + } + + def findIR(ir: IR, uuid: String) = { + ir.preorder + .filter( + _.location + .map(_.id.map(_.toString() == uuid).getOrElse(false)) + .getOrElse(false) + ) + .head + } + + def findCode(code: String, at: IR) = { + val loc = at.location.get.location + code.substring(loc.start, loc.end) } def invalidated(ir: IR, code: String, edits: TextEdit*): Set[IR.Identifier] = From 97be52f23deffc490af2baa8bb25762b5e322fa8 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Thu, 4 May 2023 14:43:09 +0200 Subject: [PATCH 2/6] Fill the gaps between leaf IR elements with their parent IR containers --- .../compiler/context/ChangesetBuilder.scala | 41 ++++++++++++---- .../test/context/ChangesetBuilderTest.scala | 47 ++++++++++++------- 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/engine/runtime/src/main/scala/org/enso/compiler/context/ChangesetBuilder.scala b/engine/runtime/src/main/scala/org/enso/compiler/context/ChangesetBuilder.scala index 5445e48fec37..662569d38255 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/context/ChangesetBuilder.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/context/ChangesetBuilder.scala @@ -336,17 +336,40 @@ object ChangesetBuilder { * @return the tree representation of the IR */ private def buildTree(ir: IR): Tree = { - @scala.annotation.tailrec - def go(input: mutable.Queue[IR], acc: Tree): Tree = - if (input.isEmpty) acc - else { - val ir = input.dequeue() - if (ir.children.isEmpty) { - Node.fromIr(ir).foreach(acc.add) + def go(input: IR, acc: Tree): Unit = { + if (input.children.isEmpty) { + Node.fromIr(input).foreach(acc.add) + } else { + if (input.getExternalId.nonEmpty) { + val chTree = new Tree() + input.children.map(go(_, chTree)) + + def fillInHoles(p: Int, n: Node): Int = { + if (p < n.location.start) { + val inBetweenNode = + Node(NodeId(input), Location(p, n.location.start)) + acc += inBetweenNode + } + acc += n + n.location.end + } + val end = + chTree.foldLeft(input.location.get.location.start)(fillInHoles) + if (end < input.location.get.location.end) { + val lastNode = Node( + NodeId(input), + Location(end, input.location.get.location.end) + ) + acc += lastNode + } + } else { + input.children.map(go(_, acc)) } - go(input ++= ir.children, acc) } - go(mutable.Queue(ir), mutable.TreeSet()) + } + val acc = new Tree() + go(ir, acc) + acc } /** Update the tree locations after applying the edit. diff --git a/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala b/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala index 2d753caed28d..b6e0ae4e08fe 100644 --- a/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala +++ b/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala @@ -394,7 +394,7 @@ class ChangesetBuilderTest extends CompilerTest { | | |#### METADATA #### - |[[{"index":{"value":5},"size":{"value":8}},"6d97d061-2c1d-4540-8f7d-3d8aa765323d"],[{"index":{"value":13},"size":{"value":1}},"a6a1b572-4867-4317-8a6e-b496b286ea2d"],[{"index":{"value":14},"size":{"value":4}},"b82e52c6-e2f0-4e16-b835-59ab8838cb2c"],[{"index":{"value":5},"size":{"value":13}},"4dd74fbb-c6df-4109-8821-f4643d483355"],[{"index":{"value":0},"size":{"value":29}},"82014253-a4f5-431b-971b-2348f5a2ca1f"],[{"index":{"value":35},"size":{"value":8}},"b22aad40-a237-4d47-a140-930d731ca80e"],[{"index":{"value":43},"size":{"value":1}},"9d7f45f1-f537-480d-b65f-37a90c77455a"],[{"index":{"value":44},"size":{"value":4}},"c6ad377f-1fce-431d-bbd7-cfe88624c50d"],[{"index":{"value":35},"size":{"value":13}},"202d7fa4-c782-4bb8-900f-7bf5f9ebad99"],[{"index":{"value":48},"size":{"value":1}},"6847cb14-aa49-455d-be9d-e82a39460005"],[{"index":{"value":49},"size":{"value":4}},"36dcdde8-1667-495a-ab87-7154c8d3be67"],[{"index":{"value":35},"size":{"value":18}},"d67c4ce2-711a-4dd9-a1f8-b48f2730b141"],[{"index":{"value":53},"size":{"value":1}},"295fa6b1-260d-4f23-8bd6-64a1d60f01e5"],[{"index":{"value":54},"size":{"value":7}},"923a2769-ddc0-4339-b919-941155a4d1b7"],[{"index":{"value":35},"size":{"value":26}},"64ef6c8a-810e-42f4-8334-8b12c4ab14bc"],[{"index":{"value":69},"size":{"value":7}},"e8cf68da-2b41-4c70-b163-567a223459fd"],[{"index":{"value":30},"size":{"value":46}},"0b934140-6464-4a05-ae6c-416670e2c7e2"],[{"index":{"value":84},"size":{"value":8}},"eaa41303-7d43-420f-8d64-da8d376fab65"],[{"index":{"value":92},"size":{"value":1}},"d582d163-0d4b-4406-96a3-e4591766406d"],[{"index":{"value":93},"size":{"value":13}},"2649f663-b1b8-44a1-9158-f2cf23038471"],[{"index":{"value":84},"size":{"value":22}},"5b4e8628-e0b7-408e-8070-e5636514c7ac"],[{"index":{"value":77},"size":{"value":29}},"78558eb9-cfb0-41d1-8f9a-0f0c17db3b7c"],[{"index":{"value":108},"size":{"value":4}},"58c9224e-644d-40c1-be25-068b6b6dc947"],[{"index":{"value":113},"size":{"value":1}},"d01b8ec7-e780-40a3-b401-97e89e000484"],[{"index":{"value":120},"size":{"value":5}},"aa43682d-01ee-453d-9bcb-34c905d8d314"],[{"index":{"value":126},"size":{"value":1}},"2b5d6c3f-e030-4ee4-9102-b573f066efa0"],[{"index":{"value":128},"size":{"value":16}},"54493640-4981-4437-ad6e-fc80ab1b581f"],[{"index":{"value":120},"size":{"value":24}},"c04888d6-bc60-4534-aa7e-df3dd5d52410"],[{"index":{"value":149},"size":{"value":5}},"85ae1943-cfcf-4e53-97c7-f73fdae42529"],[{"index":{"value":155},"size":{"value":1}},"113ae47b-3a1d-497e-8a2a-b7775be6c66e"],[{"index":{"value":157},"size":{"value":3}},"c143e355-9d64-4780-b387-dd364eefa2f9"],[{"index":{"value":149},"size":{"value":11}},"73113bd8-d3cb-4b06-a4d7-425a88bca849"],[{"index":{"value":165},"size":{"value":5}},"a286047b-54a5-45bb-995e-60f207e2af65"],[{"index":{"value":171},"size":{"value":1}},"abace020-1a84-4fa4-a5ee-2f98f73dfcb1"],[{"index":{"value":173},"size":{"value":3}},"ed3e40fb-d19e-4fb6-bebd-f74ee179ae08"],[{"index":{"value":165},"size":{"value":11}},"8ac6594b-c472-41d5-9b00-f13e6f30d5f2"],[{"index":{"value":181},"size":{"value":9}},"25eaa42e-026d-4afd-a433-dde5804b7a5c"],[{"index":{"value":191},"size":{"value":1}},"799a83db-5893-40f7-9f1e-e07c7a3071cd"],[{"index":{"value":193},"size":{"value":5}},"49332623-fe9a-4fe5-9657-7c0ea2b23942"],[{"index":{"value":198},"size":{"value":1}},"7690e4c2-31e7-4a12-8f5c-78c4484b9553"],[{"index":{"value":199},"size":{"value":7}},"3606a45e-50be-49c5-9dda-415263145a15"],[{"index":{"value":193},"size":{"value":13}},"91640cfc-f985-49da-95c8-87181d725299"],[{"index":{"value":207},"size":{"value":5}},"afb24ea2-2f35-4c7e-8394-3ba34626484e"],[{"index":{"value":193},"size":{"value":19}},"86eb77c6-14cc-487a-8993-bf9998244321"],[{"index":{"value":213},"size":{"value":5}},"52a3e9b8-f8d0-43c9-9f6d-9785359c7ba7"],[{"index":{"value":193},"size":{"value":25}},"1cddcb6a-95c8-445b-9a6f-267093b2609c"],[{"index":{"value":220},"size":{"value":16}},"df114ed3-b64d-4e74-ad60-b43a7147ec19"],[{"index":{"value":236},"size":{"value":1}},"b6a14995-bb54-4956-9abd-9b8cff898ad3"],[{"index":{"value":237},"size":{"value":11}},"fdf942d8-8064-4067-ae38-131b80fa6e0c"],[{"index":{"value":220},"size":{"value":28}},"b8df7e14-9004-4f61-8076-09354f8dbd36"],[{"index":{"value":219},"size":{"value":30}},"e2f06568-a771-4c07-9504-6c123e55825a"],[{"index":{"value":193},"size":{"value":56}},"0d4b3071-3f7d-472a-bfa7-af118222894e"],[{"index":{"value":181},"size":{"value":68}},"d9ee4c00-74b3-4859-a252-6c9105085076"],[{"index":{"value":115},"size":{"value":135}},"3eba123a-ea77-4db5-89d8-800d35e102e7"],[{"index":{"value":108},"size":{"value":142}},"11d6a77c-3644-4a27-8e15-16808af51c19"],[{"index":{"value":0},"size":{"value":251}},"9eb9e27a-81e2-416d-8aa7-367720ecc256"]] + |[[{"index":{"value":5},"size":{"value":8}},"6d97d061-2c1d-4540-8f7d-3d8aa765323d"],[{"index":{"value":13},"size":{"value":1}},"a6a1b572-4867-4317-8a6e-b496b286ea2d"],[{"index":{"value":14},"size":{"value":4}},"b82e52c6-e2f0-4e16-b835-59ab8838cb2c"],[{"index":{"value":5},"size":{"value":13}},"4dd74fbb-c6df-4109-8821-f4643d483355"],[{"index":{"value":0},"size":{"value":29}},"82014253-a4f5-431b-971b-2348f5a2ca1f"],[{"index":{"value":35},"size":{"value":8}},"b22aad40-a237-4d47-a140-930d731ca80e"],[{"index":{"value":43},"size":{"value":1}},"9d7f45f1-f537-480d-b65f-37a90c77455a"],[{"index":{"value":44},"size":{"value":4}},"c6ad377f-1fce-431d-bbd7-cfe88624c50d"],[{"index":{"value":35},"size":{"value":13}},"202d7fa4-c782-4bb8-900f-7bf5f9ebad99"],[{"index":{"value":48},"size":{"value":1}},"6847cb14-aa49-455d-be9d-e82a39460005"],[{"index":{"value":49},"size":{"value":4}},"36dcdde8-1667-495a-ab87-7154c8d3be67"],[{"index":{"value":35},"size":{"value":18}},"d67c4ce2-711a-4dd9-a1f8-b48f2730b141"],[{"index":{"value":53},"size":{"value":1}},"295fa6b1-260d-4f23-8bd6-64a1d60f01e5"],[{"index":{"value":54},"size":{"value":7}},"923a2769-ddc0-4339-b919-941155a4d1b7"],[{"index":{"value":35},"size":{"value":26}},"64ef6c8a-810e-42f4-8334-8b12c4ab14bc"],[{"index":{"value":69},"size":{"value":7}},"e8cf68da-2b41-4c70-b163-567a223459fd"],[{"index":{"value":30},"size":{"value":46}},"0b934140-6464-4a05-ae6c-416670e2c7e2"],[{"index":{"value":84},"size":{"value":8}},"eaa41303-7d43-420f-8d64-da8d376fab65"],[{"index":{"value":92},"size":{"value":1}},"d582d163-0d4b-4406-96a3-e4591766406d"],[{"index":{"value":93},"size":{"value":13}},"2649f663-b1b8-44a1-9158-f2cf23038471"],[{"index":{"value":84},"size":{"value":22}},"5b4e8628-e0b7-408e-8070-e5636514c7ac"],[{"index":{"value":77},"size":{"value":29}},"78558eb9-cfb0-41d1-8f9a-0f0c17db3b7c"],[{"index":{"value":108},"size":{"value":4}},"58c9224e-644d-40c1-be25-068b6b6dc947"],[{"index":{"value":113},"size":{"value":1}},"d01b8ec7-e780-40a3-b401-97e89e000484"],[{"index":{"value":120},"size":{"value":5}},"aa43682d-01ee-453d-9bcb-34c905d8d314"],[{"index":{"value":126},"size":{"value":1}},"2b5d6c3f-e030-4ee4-9102-b573f066efa0"],[{"index":{"value":128},"size":{"value":16}},"54493640-4981-4437-ad6e-fc80ab1b581f"],[{"index":{"value":120},"size":{"value":24}},"c04888d6-bc60-4534-aa7e-df3dd5d52410"],[{"index":{"value":149},"size":{"value":5}},"85ae1943-cfcf-4e53-97c7-f73fdae42529"],[{"index":{"value":155},"size":{"value":1}},"113ae47b-3a1d-497e-8a2a-b7775be6c66e"],[{"index":{"value":157},"size":{"value":3}},"c143e355-9d64-4780-b387-dd364eefa2f9"],[{"index":{"value":149},"size":{"value":11}},"73113bd8-d3cb-4b06-a4d7-425a88bca849"],[{"index":{"value":165},"size":{"value":5}},"a286047b-54a5-45bb-995e-60f207e2af65"],[{"index":{"value":171},"size":{"value":1}},"abace020-1a84-4fa4-a5ee-2f98f73dfcb1"],[{"index":{"value":173},"size":{"value":3}},"ed3e40fb-d19e-4fb6-bebd-f74ee179ae08"],[{"index":{"value":165},"size":{"value":11}},"8ac6594b-c472-41d5-9b00-f13e6f30d5f2"],[{"index":{"value":181},"size":{"value":9}},"25eaa42e-026d-4afd-a433-dde5804b7a5c"],[{"index":{"value":191},"size":{"value":1}},"799a83db-5893-40f7-9f1e-e07c7a3071cd"],[{"index":{"value":193},"size":{"value":5}},"49332623-fe9a-4fe5-9657-7c0ea2b23942"],[{"index":{"value":198},"size":{"value":1}},"7690e4c2-31e7-4a12-8f5c-78c4484b9553"],[{"index":{"value":199},"size":{"value":7}},"3606a45e-50be-49c5-9dda-415263145a15"],[{"index":{"value":193},"size":{"value":13}},"91640cfc-f985-49da-95c8-87181d725299"],[{"index":{"value":207},"size":{"value":5}},"afb24ea2-2f35-4c7e-8394-3ba34626484e"],[{"index":{"value":193},"size":{"value":19}},"86eb77c6-14cc-487a-8993-bf9998244321"],[{"index":{"value":213},"size":{"value":5}},"52a3e9b8-f8d0-43c9-9f6d-9785359c7ba7"],[{"index":{"value":193},"size":{"value":25}},"1cddcb6a-95c8-445b-9a6f-267093b2609c"],[{"index":{"value":220},"size":{"value":16}},"df114ed3-b64d-4e74-ad60-b43a7147ec19"],[{"index":{"value":236},"size":{"value":1}},"b6a14995-bb54-4956-9abd-9b8cff898ad3"],[{"index":{"value":237},"size":{"value":11}},"fdf942d8-8064-4067-ae38-131b80fa6e0c"],[{"index":{"value":220},"size":{"value":28}},"b8df7e14-9004-4f61-8076-09354f8dbd36"],[{"index":{"value":193},"size":{"value":56}},"0d4b3071-3f7d-472a-bfa7-af118222894e"],[{"index":{"value":181},"size":{"value":68}},"d9ee4c00-74b3-4859-a252-6c9105085076"],[{"index":{"value":115},"size":{"value":135}},"3eba123a-ea77-4db5-89d8-800d35e102e7"],[{"index":{"value":108},"size":{"value":142}},"11d6a77c-3644-4a27-8e15-16808af51c19"]] |{"ide":{"node":{"ed3e40fb-d19e-4fb6-bebd-f74ee179ae08":{"position":{"vector":[52.000004,140.00055]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":null},"0d4b3071-3f7d-472a-bfa7-af118222894e":{"position":{"vector":[-100.0,-40.0]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":{"name":{"content":{"content":"JSON"}},"project":"Builtin"}},"54493640-4981-4437-ad6e-fc80ab1b581f":{"position":{"vector":[-111.0,140.00055]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":null},"c143e355-9d64-4780-b387-dd364eefa2f9":{"position":{"vector":[9.723406,95.0]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":null}},"import":{},"project":null}} |""".stripMargin.linesIterator.mkString("\n") val edit = @@ -406,32 +406,47 @@ class ChangesetBuilderTest extends CompilerTest { val atCode = findCode(code, at) atCode shouldBe "text2.replace text1 text3 (Case_Sensitivity.Insensitive)" - invalidated(ir, code, edit) should contain theSameElementsAs Seq( - UUID.fromString(atId) - ) - invalidatedAll(ir, code, edit) should contain theSameElementsAs Seq( - UUID.fromString(atId) + val all = new ChangesetBuilder(Rope(code), ir).invalidated(Seq(edit)) + + all + .map(n => n.externalId.getOrElse(n.internalId)) + .map(findCode(code, ir, _)) should contain theSameElementsAs Seq( + atCode ) } } - def findIR(ir: IR, uuid: String) = { - ir.preorder - .filter( - _.location - .map(_.id.map(_.toString() == uuid).getOrElse(false)) - .getOrElse(false) - ) - .head + def findIR(ir: IR, uuid: String): IR = { + val list = ir.preorder.filter( + _.location + .map(_.id.map(_.toString() == uuid).getOrElse(false)) + .getOrElse(false) + ) + if (list.isEmpty) { + null + } else { + list.head + } } - def findCode(code: String, at: IR) = { + def findCode(code: String, at: IR): String = { val loc = at.location.get.location code.substring(loc.start, loc.end) } + def findCode(code: String, ir: IR, uuid: UUID): String = { + val at = findIR(ir, uuid.toString()) + if (at == null) { + uuid.toString + } else { + findCode(code, at) + } + } + def invalidated(ir: IR, code: String, edits: TextEdit*): Set[IR.Identifier] = - new ChangesetBuilder(Rope(code), ir).invalidated(edits).map(_.internalId) + new ChangesetBuilder(Rope(code), ir) + .invalidated(edits) + .map(n => n.externalId.getOrElse(n.internalId)) def invalidatedAll( ir: IR, From f8673136bc6c09c11f0848a4eed7bca4362b37e3 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Thu, 4 May 2023 15:41:18 +0200 Subject: [PATCH 3/6] Prefer old behavior when it delivers its results --- .../compiler/context/ChangesetBuilder.scala | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/engine/runtime/src/main/scala/org/enso/compiler/context/ChangesetBuilder.scala b/engine/runtime/src/main/scala/org/enso/compiler/context/ChangesetBuilder.scala index 662569d38255..5c7c6078c06f 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/context/ChangesetBuilder.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/context/ChangesetBuilder.scala @@ -194,8 +194,12 @@ final class ChangesetBuilder[A: TextEditor: IndexedSource]( else { val edit = edits.dequeue() val locationEdit = ChangesetBuilder.toLocationEdit(edit, source) - val invalidatedSet = - ChangesetBuilder.invalidated(tree, locationEdit.location) + var invalidatedSet = + ChangesetBuilder.invalidated(tree, locationEdit.location, true) + if (invalidatedSet.isEmpty) { + invalidatedSet = + ChangesetBuilder.invalidated(tree, locationEdit.location, false) + } val newTree = ChangesetBuilder.updateLocations(tree, locationEdit) val newSource = TextEditor[A].edit(source, edit) go(newTree, newSource, edits, ids ++= invalidatedSet.map(_.id)) @@ -278,7 +282,7 @@ object ChangesetBuilder { * @param id the node id * @param location the node location */ - private case class Node(id: NodeId, location: Location) { + private case class Node(id: NodeId, location: Location, leaf: Boolean) { /** Shift the node location. * @@ -302,7 +306,7 @@ object ChangesetBuilder { * @return the node if `ir` contains a location */ def fromIr(ir: IR): Option[Node] = - ir.location.map(loc => Node(NodeId(ir), loc.location)) + ir.location.map(loc => Node(NodeId(ir), loc.location, true)) /** Create an artificial node with fixed [[NodeId]]. It is used to select * nodes by location in the tree. @@ -311,7 +315,11 @@ object ChangesetBuilder { * @return a select node */ def select(location: Location): Node = - new Node(NodeId(UUID.nameUUIDFromBytes(Array()), None, None), location) + new Node( + NodeId(UUID.nameUUIDFromBytes(Array()), None, None), + location, + false + ) implicit val ordering: Ordering[Node] = (x: Node, y: Node) => { val compareStart = @@ -347,7 +355,7 @@ object ChangesetBuilder { def fillInHoles(p: Int, n: Node): Int = { if (p < n.location.start) { val inBetweenNode = - Node(NodeId(input), Location(p, n.location.start)) + Node(NodeId(input), Location(p, n.location.start), false) acc += inBetweenNode } acc += n @@ -358,7 +366,8 @@ object ChangesetBuilder { if (end < input.location.get.location.end) { val lastNode = Node( NodeId(input), - Location(end, input.location.get.location.end) + Location(end, input.location.get.location.end), + false ) acc += lastNode } @@ -394,12 +403,18 @@ object ChangesetBuilder { * @param edit the location of the edit * @return the invalidated nodes of the tree */ - private def invalidated(tree: Tree, edit: Location): Tree = { + private def invalidated( + tree: Tree, + edit: Location, + onlyLeafs: Boolean + ): Tree = { val invalidated = mutable.TreeSet[ChangesetBuilder.Node]() tree.iterator.foreach { node => - if (intersect(edit, node)) { - invalidated += node - tree -= node + if (!onlyLeafs || node.leaf) { + if (intersect(edit, node)) { + invalidated += node + tree -= node + } } } invalidated From 491bad7e391785c5ff44db47bcbad624eab6a2e1 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 5 May 2023 06:10:29 +0200 Subject: [PATCH 4/6] Line 9 column 72 Co-authored-by: Dmitry Bushev --- .../org/enso/compiler/test/context/ChangesetBuilderTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala b/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala index b6e0ae4e08fe..03182a41692a 100644 --- a/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala +++ b/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala @@ -398,7 +398,7 @@ class ChangesetBuilderTest extends CompilerTest { |{"ide":{"node":{"ed3e40fb-d19e-4fb6-bebd-f74ee179ae08":{"position":{"vector":[52.000004,140.00055]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":null},"0d4b3071-3f7d-472a-bfa7-af118222894e":{"position":{"vector":[-100.0,-40.0]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":{"name":{"content":{"content":"JSON"}},"project":"Builtin"}},"54493640-4981-4437-ad6e-fc80ab1b581f":{"position":{"vector":[-111.0,140.00055]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":null},"c143e355-9d64-4780-b387-dd364eefa2f9":{"position":{"vector":[9.723406,95.0]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":null}},"import":{},"project":null}} |""".stripMargin.linesIterator.mkString("\n") val edit = - TextEdit(Range(Position(8, 88), Position(8, 88)), "Boolean.True") + TextEdit(Range(Position(9, 72), Position(9, 72)), " Boolean.True") val ir = code.preprocessModule val atId = "0d4b3071-3f7d-472a-bfa7-af118222894e" From 8a2671b40aa44af944f49863c38f4cec6d4390e4 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 5 May 2023 06:13:11 +0200 Subject: [PATCH 5/6] Removing the IDE metadata line --- .../org/enso/compiler/test/context/ChangesetBuilderTest.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala b/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala index 03182a41692a..106031134eb1 100644 --- a/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala +++ b/engine/runtime/src/test/scala/org/enso/compiler/test/context/ChangesetBuilderTest.scala @@ -395,7 +395,6 @@ class ChangesetBuilderTest extends CompilerTest { | |#### METADATA #### |[[{"index":{"value":5},"size":{"value":8}},"6d97d061-2c1d-4540-8f7d-3d8aa765323d"],[{"index":{"value":13},"size":{"value":1}},"a6a1b572-4867-4317-8a6e-b496b286ea2d"],[{"index":{"value":14},"size":{"value":4}},"b82e52c6-e2f0-4e16-b835-59ab8838cb2c"],[{"index":{"value":5},"size":{"value":13}},"4dd74fbb-c6df-4109-8821-f4643d483355"],[{"index":{"value":0},"size":{"value":29}},"82014253-a4f5-431b-971b-2348f5a2ca1f"],[{"index":{"value":35},"size":{"value":8}},"b22aad40-a237-4d47-a140-930d731ca80e"],[{"index":{"value":43},"size":{"value":1}},"9d7f45f1-f537-480d-b65f-37a90c77455a"],[{"index":{"value":44},"size":{"value":4}},"c6ad377f-1fce-431d-bbd7-cfe88624c50d"],[{"index":{"value":35},"size":{"value":13}},"202d7fa4-c782-4bb8-900f-7bf5f9ebad99"],[{"index":{"value":48},"size":{"value":1}},"6847cb14-aa49-455d-be9d-e82a39460005"],[{"index":{"value":49},"size":{"value":4}},"36dcdde8-1667-495a-ab87-7154c8d3be67"],[{"index":{"value":35},"size":{"value":18}},"d67c4ce2-711a-4dd9-a1f8-b48f2730b141"],[{"index":{"value":53},"size":{"value":1}},"295fa6b1-260d-4f23-8bd6-64a1d60f01e5"],[{"index":{"value":54},"size":{"value":7}},"923a2769-ddc0-4339-b919-941155a4d1b7"],[{"index":{"value":35},"size":{"value":26}},"64ef6c8a-810e-42f4-8334-8b12c4ab14bc"],[{"index":{"value":69},"size":{"value":7}},"e8cf68da-2b41-4c70-b163-567a223459fd"],[{"index":{"value":30},"size":{"value":46}},"0b934140-6464-4a05-ae6c-416670e2c7e2"],[{"index":{"value":84},"size":{"value":8}},"eaa41303-7d43-420f-8d64-da8d376fab65"],[{"index":{"value":92},"size":{"value":1}},"d582d163-0d4b-4406-96a3-e4591766406d"],[{"index":{"value":93},"size":{"value":13}},"2649f663-b1b8-44a1-9158-f2cf23038471"],[{"index":{"value":84},"size":{"value":22}},"5b4e8628-e0b7-408e-8070-e5636514c7ac"],[{"index":{"value":77},"size":{"value":29}},"78558eb9-cfb0-41d1-8f9a-0f0c17db3b7c"],[{"index":{"value":108},"size":{"value":4}},"58c9224e-644d-40c1-be25-068b6b6dc947"],[{"index":{"value":113},"size":{"value":1}},"d01b8ec7-e780-40a3-b401-97e89e000484"],[{"index":{"value":120},"size":{"value":5}},"aa43682d-01ee-453d-9bcb-34c905d8d314"],[{"index":{"value":126},"size":{"value":1}},"2b5d6c3f-e030-4ee4-9102-b573f066efa0"],[{"index":{"value":128},"size":{"value":16}},"54493640-4981-4437-ad6e-fc80ab1b581f"],[{"index":{"value":120},"size":{"value":24}},"c04888d6-bc60-4534-aa7e-df3dd5d52410"],[{"index":{"value":149},"size":{"value":5}},"85ae1943-cfcf-4e53-97c7-f73fdae42529"],[{"index":{"value":155},"size":{"value":1}},"113ae47b-3a1d-497e-8a2a-b7775be6c66e"],[{"index":{"value":157},"size":{"value":3}},"c143e355-9d64-4780-b387-dd364eefa2f9"],[{"index":{"value":149},"size":{"value":11}},"73113bd8-d3cb-4b06-a4d7-425a88bca849"],[{"index":{"value":165},"size":{"value":5}},"a286047b-54a5-45bb-995e-60f207e2af65"],[{"index":{"value":171},"size":{"value":1}},"abace020-1a84-4fa4-a5ee-2f98f73dfcb1"],[{"index":{"value":173},"size":{"value":3}},"ed3e40fb-d19e-4fb6-bebd-f74ee179ae08"],[{"index":{"value":165},"size":{"value":11}},"8ac6594b-c472-41d5-9b00-f13e6f30d5f2"],[{"index":{"value":181},"size":{"value":9}},"25eaa42e-026d-4afd-a433-dde5804b7a5c"],[{"index":{"value":191},"size":{"value":1}},"799a83db-5893-40f7-9f1e-e07c7a3071cd"],[{"index":{"value":193},"size":{"value":5}},"49332623-fe9a-4fe5-9657-7c0ea2b23942"],[{"index":{"value":198},"size":{"value":1}},"7690e4c2-31e7-4a12-8f5c-78c4484b9553"],[{"index":{"value":199},"size":{"value":7}},"3606a45e-50be-49c5-9dda-415263145a15"],[{"index":{"value":193},"size":{"value":13}},"91640cfc-f985-49da-95c8-87181d725299"],[{"index":{"value":207},"size":{"value":5}},"afb24ea2-2f35-4c7e-8394-3ba34626484e"],[{"index":{"value":193},"size":{"value":19}},"86eb77c6-14cc-487a-8993-bf9998244321"],[{"index":{"value":213},"size":{"value":5}},"52a3e9b8-f8d0-43c9-9f6d-9785359c7ba7"],[{"index":{"value":193},"size":{"value":25}},"1cddcb6a-95c8-445b-9a6f-267093b2609c"],[{"index":{"value":220},"size":{"value":16}},"df114ed3-b64d-4e74-ad60-b43a7147ec19"],[{"index":{"value":236},"size":{"value":1}},"b6a14995-bb54-4956-9abd-9b8cff898ad3"],[{"index":{"value":237},"size":{"value":11}},"fdf942d8-8064-4067-ae38-131b80fa6e0c"],[{"index":{"value":220},"size":{"value":28}},"b8df7e14-9004-4f61-8076-09354f8dbd36"],[{"index":{"value":193},"size":{"value":56}},"0d4b3071-3f7d-472a-bfa7-af118222894e"],[{"index":{"value":181},"size":{"value":68}},"d9ee4c00-74b3-4859-a252-6c9105085076"],[{"index":{"value":115},"size":{"value":135}},"3eba123a-ea77-4db5-89d8-800d35e102e7"],[{"index":{"value":108},"size":{"value":142}},"11d6a77c-3644-4a27-8e15-16808af51c19"]] - |{"ide":{"node":{"ed3e40fb-d19e-4fb6-bebd-f74ee179ae08":{"position":{"vector":[52.000004,140.00055]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":null},"0d4b3071-3f7d-472a-bfa7-af118222894e":{"position":{"vector":[-100.0,-40.0]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":{"name":{"content":{"content":"JSON"}},"project":"Builtin"}},"54493640-4981-4437-ad6e-fc80ab1b581f":{"position":{"vector":[-111.0,140.00055]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":null},"c143e355-9d64-4780-b387-dd364eefa2f9":{"position":{"vector":[9.723406,95.0]},"intended_method":null,"uploading_file":null,"selected":false,"visualization":null}},"import":{},"project":null}} |""".stripMargin.linesIterator.mkString("\n") val edit = TextEdit(Range(Position(9, 72), Position(9, 72)), " Boolean.True") From 07fc59c87730d5ceda1d4bf2d284e27f5f0b0e17 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 5 May 2023 07:14:16 +0200 Subject: [PATCH 6/6] More descriptive identifiers --- .../compiler/context/ChangesetBuilder.scala | 64 +++++++++++-------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/engine/runtime/src/main/scala/org/enso/compiler/context/ChangesetBuilder.scala b/engine/runtime/src/main/scala/org/enso/compiler/context/ChangesetBuilder.scala index 5c7c6078c06f..a49c3a3c3619 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/context/ChangesetBuilder.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/context/ChangesetBuilder.scala @@ -344,41 +344,55 @@ object ChangesetBuilder { * @return the tree representation of the IR */ private def buildTree(ir: IR): Tree = { - def go(input: IR, acc: Tree): Unit = { - if (input.children.isEmpty) { - Node.fromIr(input).foreach(acc.add) + def depthFirstSearch(currentIr: IR, acc: Tree): Unit = { + if (currentIr.children.isEmpty) { + Node.fromIr(currentIr).foreach(acc.add) } else { - if (input.getExternalId.nonEmpty) { - val chTree = new Tree() - input.children.map(go(_, chTree)) - - def fillInHoles(p: Int, n: Node): Int = { - if (p < n.location.start) { - val inBetweenNode = - Node(NodeId(input), Location(p, n.location.start), false) - acc += inBetweenNode + val hasImportantId = currentIr.getExternalId.nonEmpty + if (hasImportantId) { + val collectChildrenIntervals = new Tree() + currentIr.children.map(depthFirstSearch(_, collectChildrenIntervals)) + + def fillGapsInChildrenNodesWithNonLeafNodes( + previousPosition: Int, + nextNode: Node + ): Int = { + if (previousPosition < nextNode.location.start) { + val nodeBetweenPreviousPositionAndNextNode = + Node( + NodeId(currentIr), + Location(previousPosition, nextNode.location.start), + false + ) + acc += nodeBetweenPreviousPositionAndNextNode } - acc += n - n.location.end + acc += nextNode + nextNode.location.end } - val end = - chTree.foldLeft(input.location.get.location.start)(fillInHoles) - if (end < input.location.get.location.end) { - val lastNode = Node( - NodeId(input), - Location(end, input.location.get.location.end), + val beginOfNonLeafIr = currentIr.location.get.location.start + val endOfNonLeafIr = currentIr.location.get.location.end + val lastCoveredPosition = + collectChildrenIntervals.foldLeft(beginOfNonLeafIr)( + fillGapsInChildrenNodesWithNonLeafNodes + ) + val hasRemainingTextAfterLastChild = + lastCoveredPosition < endOfNonLeafIr + if (hasRemainingTextAfterLastChild) { + val nodeAfterLastChild = Node( + NodeId(currentIr), + Location(lastCoveredPosition, endOfNonLeafIr), false ) - acc += lastNode + acc += nodeAfterLastChild } } else { - input.children.map(go(_, acc)) + currentIr.children.map(depthFirstSearch(_, acc)) } } } - val acc = new Tree() - go(ir, acc) - acc + val collectNodes = new Tree() + depthFirstSearch(ir, collectNodes) + collectNodes } /** Update the tree locations after applying the edit.