Skip to content

Commit ebf0b32

Browse files
committed
Add helper function for getting the ConcurrentEdits of two strings
Get rid of utils/incrparse
1 parent 8311d8d commit ebf0b32

File tree

4 files changed

+90
-600
lines changed

4 files changed

+90
-600
lines changed

Tests/SwiftParserTest/IncrementalParsingTests.swift

Lines changed: 90 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,108 @@ import XCTest
1414
import SwiftSyntax
1515
import SwiftParser
1616

17+
/// Returns the `ConcurrentEdits`s to transition from `base` to `new`.
18+
func getConcurrentEdits(from base: String, to new: String) -> ConcurrentEdits {
19+
let diffCollection = new.difference(from: base)
20+
21+
let diffArray: [(offset: Int, isInsert: Bool)] =
22+
diffCollection
23+
.map { diff in
24+
switch diff {
25+
case .remove(offset: let offset, element: _, associatedWith: _):
26+
return (offset, false)
27+
case .insert(offset: let offset, element: _, associatedWith: _):
28+
return (offset, true)
29+
}
30+
}
31+
.sorted {
32+
// Change.remove should prior to Change.insert
33+
if $0.0 < $1.0 {
34+
return true
35+
} else if $0.0 == $1.0 {
36+
return !$0.1
37+
} else {
38+
return false
39+
}
40+
}
41+
42+
let sourceEdits = diffArray.map({
43+
return $0.1 ? SourceEdit(offset: $0.0, length: 0, replacementLength: 1) : SourceEdit(offset: $0.0, length: 1, replacementLength: 0)
44+
})
45+
46+
return ConcurrentEdits(fromSequential: sourceEdits)
47+
}
48+
1749
public class IncrementalParsingTests: XCTestCase {
1850

51+
public func testDiffOfTwoStringsSimple() throws {
52+
let s1 = "struct A { func f() {"
53+
let s2 = "struct AA { func f() {"
54+
55+
let diffs = getConcurrentEdits(from: s1, to: s2)
56+
XCTAssertEqual(diffs.edits.count, 1)
57+
58+
let firstDiff = try XCTUnwrap(diffs.edits.first)
59+
XCTAssertEqual(firstDiff, SourceEdit(offset: 8, length: 0, replacementLength: 1))
60+
}
61+
62+
public func testDiffOfTwoSameStrings() {
63+
let s1 = "0123456"
64+
let s2 = "0123456"
65+
66+
let diffs = getConcurrentEdits(from: s1, to: s2)
67+
XCTAssert(diffs.edits.isEmpty)
68+
}
69+
70+
public func testDiffOfTwoStrings() {
71+
let s1 = "0123456"
72+
let s2 = "x12456yz"
73+
74+
let diffs = getConcurrentEdits(from: s1, to: s2)
75+
76+
let expectedDiffs: [SourceEdit] = [
77+
SourceEdit(offset: 0, length: 1, replacementLength: 1),
78+
SourceEdit(offset: 3, length: 1, replacementLength: 0),
79+
SourceEdit(offset: 7, length: 0, replacementLength: 2),
80+
]
81+
82+
XCTAssertEqual(diffs.edits, expectedDiffs)
83+
}
84+
1985
public func testIncrementalInvalid() {
2086
let original = "struct A { func f() {"
21-
let step: (String, (Int, Int, String)) =
22-
("struct AA { func f() {", (8, 0, "A"))
23-
24-
var tree = Parser.parse(source: original)
25-
let sourceEdit = SourceEdit(range: ByteSourceRange(offset: step.1.0, length: step.1.1), replacementLength: step.1.2.utf8.count)
26-
let lookup = IncrementalParseTransition(previousTree: tree, edits: ConcurrentEdits(sourceEdit))
27-
tree = Parser.parse(source: step.0, parseTransition: lookup)
28-
XCTAssertEqual("\(tree)", step.0)
87+
let newSource = "struct AA { func f() {"
88+
89+
let concurrentEdits = getConcurrentEdits(from: original, to: newSource)
90+
91+
let oldTree = Parser.parse(source: original)
92+
let lookup = IncrementalParseTransition(previousTree: oldTree, edits: concurrentEdits)
93+
let newTree = Parser.parse(source: newSource, parseTransition: lookup)
94+
95+
XCTAssertEqual("\(newTree)", "\(newSource)")
2996
}
3097

3198
public func testReusedNode() throws {
3299
try XCTSkipIf(true, "Swift parser does not handle node reuse yet")
33100

34-
let original = "struct A {}\nstruct B {}\n"
35-
let step: (String, (Int, Int, String)) =
36-
("struct AA {}\nstruct B {}\n", (8, 0, "A"))
101+
let original =
102+
"""
103+
struct A {}
104+
struct B {}
105+
"""
106+
107+
let newSource =
108+
"""
109+
struct A {}
110+
struct B {}
111+
"""
37112

38113
let origTree = Parser.parse(source: original)
39-
let sourceEdit = SourceEdit(range: ByteSourceRange(offset: step.1.0, length: step.1.1), replacementLength: step.1.2.utf8.count)
114+
let concurrentEdits = getConcurrentEdits(from: original, to: newSource)
40115
let reusedNodeCollector = IncrementalParseReusedNodeCollector()
41-
let transition = IncrementalParseTransition(previousTree: origTree, edits: ConcurrentEdits(sourceEdit), reusedNodeDelegate: reusedNodeCollector)
42-
let newTree = Parser.parse(source: step.0, parseTransition: transition)
43-
XCTAssertEqual("\(newTree)", step.0)
116+
let transition = IncrementalParseTransition(previousTree: origTree, edits: concurrentEdits, reusedNodeDelegate: reusedNodeCollector)
117+
let newTree = Parser.parse(source: newSource, parseTransition: transition)
118+
XCTAssertEqual("\(newTree)", "\(newSource)")
44119

45120
let origStructB = origTree.statements[1]
46121
let newStructB = newTree.statements[1]

utils/incrparse/incr_transfer_round_trip.py

Lines changed: 0 additions & 118 deletions
This file was deleted.

0 commit comments

Comments
 (0)