@@ -104,48 +104,35 @@ public final class IncrementalParseTransition {
104
104
guard let prevOffset = translateToPreEditOffset ( newOffset) else {
105
105
return nil
106
106
}
107
- let ( nodeOffset , node ) = lookUpFrom ( previousTree , nodeOffset : 0 ,
108
- prevOffset : prevOffset , kind: kind)
107
+ let prevPosition = AbsolutePosition ( utf8Offset : prevOffset )
108
+ let node = lookUpFrom ( previousTree , prevPosition : prevPosition , kind: kind)
109
109
if let delegate = reusedDelegate, let node = node {
110
110
delegate. parserReusedNode (
111
- range: ByteSourceRange ( offset: nodeOffset , length: node. byteSize) ,
111
+ range: ByteSourceRange ( offset: newOffset , length: node. byteSize) ,
112
112
previousNode: node)
113
113
}
114
114
return node
115
115
}
116
116
117
- fileprivate func lookUpFrom( _ node : _SyntaxBase , nodeOffset : Int , prevOffset : Int ,
118
- kind: SyntaxKind ) -> ( Int , _SyntaxBase ? ) {
119
- if nodeCanBeReused ( node , nodeOffset : nodeOffset , prevOffset : prevOffset ,
120
- kind: kind) {
121
- return ( nodeOffset , node)
117
+ fileprivate func lookUpFrom(
118
+ _ node : _SyntaxBase , prevPosition : AbsolutePosition , kind: SyntaxKind
119
+ ) -> _SyntaxBase ? {
120
+ if nodeCanBeReused ( node , prevPosition : prevPosition , kind: kind) {
121
+ return node
122
122
}
123
123
124
- // Compute the child's position on the fly
125
- var childOffset = nodeOffset
126
124
for child in node. children {
127
- if child. isMissing {
128
- continue
125
+ if child. position <= prevPosition && prevPosition < child . endPosition {
126
+ return lookUpFrom ( child , prevPosition : prevPosition , kind : kind )
129
127
}
130
- let childEnd = childOffset + child. byteSize
131
- if childOffset <= prevOffset && prevOffset < childEnd {
132
- return lookUpFrom ( child, nodeOffset: childOffset,
133
- prevOffset: prevOffset, kind: kind)
134
- }
135
- // The next child starts where the previous child ended
136
- childOffset = childEnd
137
128
}
138
- return ( 0 , nil )
129
+ return nil
139
130
}
140
131
141
- fileprivate func nodeCanBeReused( _ node: _SyntaxBase , nodeOffset: Int ,
142
- prevOffset: Int , kind: SyntaxKind ) -> Bool {
143
- // Computing the value of NodeStart on the fly is faster than determining a
144
- // node's absolute position, but make sure the values match in an assertion
145
- // build
146
- assert ( nodeOffset == node. position. utf8Offset) ;
147
-
148
- if nodeOffset != prevOffset {
132
+ fileprivate func nodeCanBeReused(
133
+ _ node: _SyntaxBase , prevPosition: AbsolutePosition , kind: SyntaxKind
134
+ ) -> Bool {
135
+ if node. position != prevPosition {
149
136
return false
150
137
}
151
138
if node. raw. kind != kind {
@@ -158,17 +145,20 @@ public final class IncrementalParseTransition {
158
145
// CodeBlockItems one for `private` and one for `struc Foo {}`
159
146
var nextLeafNodeLength = 0
160
147
if let nextToken = node. nextToken {
161
- let nextRawNode = nextToken. raw
162
- assert ( nextRawNode. isPresent)
163
- nextLeafNodeLength += nextRawNode. contentLength. utf8Length
164
- nextLeafNodeLength += nextRawNode. leadingTriviaLength. utf8Length
148
+ assert ( nextToken. isPresent)
149
+ nextLeafNodeLength = nextToken. byteSize - nextToken. trailingTriviaLength. utf8Length
165
150
}
166
151
167
152
for edit in edits {
168
153
// Check if this node or the trivia of the next node has been edited. If
169
154
// it has, we cannot reuse it.
170
- if edit. intersectsOrTouchesRange ( ByteSourceRange ( offset: nodeOffset,
171
- length: node. byteSize + nextLeafNodeLength) ) {
155
+ let nodeAffectRange = ByteSourceRange ( offset: node. position. utf8Offset,
156
+ length: node. byteSize + nextLeafNodeLength)
157
+ if edit. range. offset > nodeAffectRange. endOffset {
158
+ // Remaining edits don't affect the node. (Edits are sorted)
159
+ break
160
+ }
161
+ if edit. intersectsOrTouchesRange ( nodeAffectRange) {
172
162
return false
173
163
}
174
164
}
0 commit comments