Skip to content

Commit cb8d4fc

Browse files
committed
WIP: Port incremental parsing ability to CodeBlockItem
1 parent 1555299 commit cb8d4fc

File tree

5 files changed

+42
-5
lines changed

5 files changed

+42
-5
lines changed

Sources/SwiftParser/IncrementalParseTransition.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public struct IncrementalParseLookup {
109109
let node = cursorLookup(prevPosition: prevPosition, kind: kind)
110110
if let delegate = reusedDelegate, let node {
111111
delegate.parserReusedNode(
112-
range: ByteSourceRange(offset: newOffset, length: node.byteSize),
112+
range: ByteSourceRange(offset: newOffset, length: node.byteSizeAfterTrimmingTrivia),
113113
previousNode: node
114114
)
115115
}

Sources/SwiftParser/Lexer/LexemeSequence.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,19 @@ extension Lexer {
5050
return self.nextToken
5151
}
5252

53+
func getOffsetToStart(_ token: Lexer.Lexeme) -> Int {
54+
return self.sourceBufferStart.distance(to: token.cursor)
55+
}
56+
57+
mutating func advance(by offset: Int, currentToken: inout Lexer.Lexeme) {
58+
self.cursor = currentToken.cursor
59+
self.cursor.position = self.cursor.position.advanced(by: offset)
60+
61+
self.nextToken = self.cursor.nextToken(sourceBufferStart: self.sourceBufferStart, stateAllocator: lexerStateAllocator)
62+
63+
currentToken = self.advance()
64+
}
65+
5366
/// Reset the lexeme sequence to the state we were in when lexing `splitToken`
5467
/// but after we consumed `consumedPrefix` bytes from `splitToken`.
5568
/// - Warning: Do not add more usages of this function.

Sources/SwiftParser/Parser.swift

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ public struct Parser {
101101
/// When this nesting level is exceeded, the parser should stop parsing.
102102
let maximumNestingLevel: Int
103103

104+
let parseTransition: IncrementalParseTransition?
105+
104106
/// A default maximum nesting level that is used if the client didn't
105107
/// explicitly specify one. Debug builds of the parser comume a lot more stack
106108
/// space and thus have a lower default maximum nesting level.
@@ -111,7 +113,7 @@ public struct Parser {
111113
#endif
112114

113115
/// Initializes a ``Parser`` from the given string.
114-
public init(_ input: String, maximumNestingLevel: Int? = nil) {
116+
public init(_ input: String, maximumNestingLevel: Int? = nil, parseTransition: IncrementalParseTransition? = nil) {
115117
self.maximumNestingLevel = maximumNestingLevel ?? Self.defaultMaximumNestingLevel
116118

117119
self.arena = ParsingSyntaxArena(
@@ -124,6 +126,7 @@ public struct Parser {
124126
return arena.internSourceBuffer(buffer)
125127
}
126128

129+
self.parseTransition = parseTransition
127130
self.lexemes = Lexer.tokenize(interned)
128131
self.currentToken = self.lexemes.advance()
129132
}
@@ -142,7 +145,7 @@ public struct Parser {
142145
/// arena is created automatically, and `input` copied into the
143146
/// arena. If non-`nil`, `input` must be within its registered
144147
/// source buffer or allocator.
145-
public init(_ input: UnsafeBufferPointer<UInt8>, maximumNestingLevel: Int? = nil, arena: ParsingSyntaxArena? = nil) {
148+
public init(_ input: UnsafeBufferPointer<UInt8>, maximumNestingLevel: Int? = nil, arena: ParsingSyntaxArena? = nil, parseTransition: IncrementalParseTransition? = nil) {
146149
self.maximumNestingLevel = maximumNestingLevel ?? Self.defaultMaximumNestingLevel
147150

148151
var sourceBuffer: UnsafeBufferPointer<UInt8>
@@ -157,6 +160,7 @@ public struct Parser {
157160
sourceBuffer = self.arena.internSourceBuffer(input)
158161
}
159162

163+
self.parseTransition = parseTransition
160164
self.lexemes = Lexer.tokenize(sourceBuffer)
161165
self.currentToken = self.lexemes.advance()
162166
}
@@ -629,3 +633,19 @@ extension Parser {
629633
)
630634
}
631635
}
636+
637+
// MARK: Incremental Parsing
638+
extension Parser {
639+
mutating func loadCurrentSyntaxNodeFromCache(for kind: SyntaxKind) -> Syntax? {
640+
guard let parseTransition = self.parseTransition else { return nil }
641+
642+
var lookUpHelper = IncrementalParseLookup(transition: parseTransition)
643+
let currentOffset = self.lexemes.getOffsetToStart(self.currentToken)
644+
if let node = lookUpHelper.lookUp(currentOffset, kind: kind) {
645+
self.lexemes.advance(by: node.byteSize, currentToken: &self.currentToken)
646+
return node
647+
}
648+
649+
return nil
650+
}
651+
}

Sources/SwiftParser/TopLevel.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ extension Parser {
151151
/// statement → compiler-control-statement
152152
/// statements → statement statements?
153153
mutating func parseCodeBlockItem(isAtTopLevel: Bool, allowInitDecl: Bool) -> RawCodeBlockItemSyntax? {
154+
if let syntax = self.loadCurrentSyntaxNodeFromCache(for: .codeBlockItem) {
155+
return RawCodeBlockItemSyntax(syntax.raw)
156+
}
157+
154158
if let remainingTokens = remainingTokensIfMaximumNestingLevelReached() {
155159
return RawCodeBlockItemSyntax(
156160
remainingTokens,

Sources/SwiftParser/generated/Parser+Entry.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ extension Parser {
2121
source: String,
2222
parseTransition: IncrementalParseTransition? = nil
2323
) -> SourceFileSyntax {
24-
var parser = Parser(source)
24+
var parser = Parser(source, parseTransition: parseTransition)
2525
return SourceFileSyntax.parse(from: &parser)
2626
}
2727

@@ -32,7 +32,7 @@ extension Parser {
3232
maximumNestingLevel: Int? = nil,
3333
parseTransition: IncrementalParseTransition? = nil
3434
) -> SourceFileSyntax {
35-
var parser = Parser(source, maximumNestingLevel: maximumNestingLevel)
35+
var parser = Parser(source, maximumNestingLevel: maximumNestingLevel, parseTransition: parseTransition)
3636
return SourceFileSyntax.parse(from: &parser)
3737
}
3838
}

0 commit comments

Comments
 (0)