Skip to content

Commit 705acf9

Browse files
committed
Move SwiftSyntaxParser related code to its own module
* Remove `_SyntaxParserInterop.swift` * Use `RawSyntax.toOpaque()`/`RawSyntax.fromOpaque(:_)` to interop * Move `RawSyntax.createFromCSyntaxNode()` to the module * Moved SyntaxKind/RawTokenKind/RawTriviaPiece creation the C serialization code to the module * Tweaked some RawSyntax API visibility * Refoctored materialized token creation API to efficiently create a token from SyntaxParser modules * Introduce `Syntax.withUnsafeRawSyntax(_:)` API
1 parent 71f1af4 commit 705acf9

20 files changed

+966
-837
lines changed

Package.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ let package = Package(
9393
name: "SwiftSyntaxParser",
9494
dependencies: ["SwiftSyntax"],
9595
exclude: [
96-
"NodeDeclarationHash.swift.gyb"
96+
"NodeDeclarationHash.swift.gyb",
97+
"Serialization.swift.gyb",
9798
],
9899
linkerSettings: swiftSyntaxParserLinkerSettings
99100
),

Sources/SwiftSyntax/CNodes.swift

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

Sources/SwiftSyntax/IncrementalParseTransition.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,13 @@ public struct IncrementalParseLookup {
249249
/// - Returns: A `SyntaxNode` node from the previous parse invocation,
250250
/// representing the contents of this region, if it is still valid
251251
/// to re-use. `nil` otherwise.
252-
public mutating func lookUp(_ newOffset: Int, kind: CSyntaxKind) -> SyntaxNode? {
252+
@_spi(RawSyntax)
253+
public mutating func lookUp(_ newOffset: Int, kind: SyntaxKind) -> SyntaxNode? {
253254
guard let prevOffset = translateToPreEditOffset(newOffset) else {
254255
return nil
255256
}
256257
let prevPosition = AbsolutePosition(utf8Offset: prevOffset)
257-
let node = cursorLookup(prevPosition: prevPosition, kind: .fromRawValue(kind))
258+
let node = cursorLookup(prevPosition: prevPosition, kind: kind)
258259
if let delegate = reusedDelegate, let node = node {
259260
delegate.parserReusedNode(
260261
range: ByteSourceRange(offset: newOffset, length: node.byteSize),

Sources/SwiftSyntax/Raw/RawSyntax+CSwiftSyntax.swift

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

Sources/SwiftSyntax/Raw/RawSyntax.swift

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,11 @@ extension RawSyntax {
262262
}
263263

264264
extension RawSyntax {
265-
func toOpaque() -> UnsafeRawPointer {
265+
public func toOpaque() -> UnsafeRawPointer {
266266
UnsafeRawPointer(pointer)
267267
}
268268

269-
static func fromOpaque(_ pointer: UnsafeRawPointer) -> RawSyntax {
269+
public static func fromOpaque(_ pointer: UnsafeRawPointer) -> RawSyntax {
270270
Self(pointer: pointer.assumingMemoryBound(to: RawSyntaxData.self))
271271
}
272272
}
@@ -377,24 +377,6 @@ extension RawSyntax {
377377

378378
// MARK: - Factories.
379379

380-
private func makeRawTriviaPieces(leadingTrivia: Trivia, trailingTrivia: Trivia, arena: SyntaxArena) -> (pieces: RawTriviaPieceBuffer, byteLength: Int) {
381-
let totalTriviaCount = leadingTrivia.count + trailingTrivia.count
382-
383-
if totalTriviaCount != 0 {
384-
var byteLength = 0
385-
let buffer = arena.allocateRawTriviaPieceBuffer(count: totalTriviaCount)
386-
var ptr = buffer.baseAddress!
387-
for piece in leadingTrivia + trailingTrivia {
388-
byteLength += piece.sourceLength.utf8Length
389-
ptr.initialize(to: .make(piece, arena: arena))
390-
ptr = ptr.advanced(by: 1)
391-
}
392-
return (pieces: .init(buffer), byteLength: byteLength)
393-
} else {
394-
return (pieces: .init(start: nil, count: 0), byteLength: 0)
395-
}
396-
}
397-
398380
extension RawSyntax {
399381
/// "Designated" factory method to create a parsed token node.
400382
///
@@ -409,6 +391,8 @@ extension RawSyntax {
409391
textRange: Range<SyntaxText.Index>,
410392
arena: SyntaxArena
411393
) -> RawSyntax {
394+
assert(arena.contains(text: wholeText),
395+
"token text must be managed by the arena")
412396
let payload = RawSyntaxData.ParsedToken(
413397
tokenKind: kind, wholeText: wholeText, textRange: textRange)
414398
return RawSyntax(arena: arena, payload: .parsedToken(payload))
@@ -435,6 +419,9 @@ extension RawSyntax {
435419
byteLength: UInt32,
436420
arena: SyntaxArena
437421
) -> RawSyntax {
422+
assert(arena.contains(text: text), "token text must be managed by the arena")
423+
assert(triviaPieces.allSatisfy({$0.storedText.map({arena.contains(text: $0)}) ?? true}),
424+
"trivia text must be managed by the arena")
438425
let payload = RawSyntaxData.MaterializedToken(
439426
tokenKind: kind, tokenText: text,
440427
triviaPieces: triviaPieces,
@@ -443,6 +430,30 @@ extension RawSyntax {
443430
return RawSyntax(arena: arena, payload: .materializedToken(payload))
444431
}
445432

433+
public static func makeMaterializedToken(
434+
kind: RawTokenKind,
435+
text: SyntaxText,
436+
leadingTriviaPieceCount: Int,
437+
trailingTriviaPieceCount: Int,
438+
arena: SyntaxArena,
439+
initializeLeadingTriviaWith: (UnsafeMutableBufferPointer<RawTriviaPiece>) -> Void,
440+
initializingTrailingTriviaWith : (UnsafeMutableBufferPointer<RawTriviaPiece>) -> Void
441+
) -> RawSyntax {
442+
let totalTriviaCount = leadingTriviaPieceCount + trailingTriviaPieceCount
443+
let triviaBuffer = arena.allocateRawTriviaPieceBuffer(count: totalTriviaCount)
444+
initializeLeadingTriviaWith(
445+
UnsafeMutableBufferPointer(rebasing: triviaBuffer[..<leadingTriviaPieceCount]))
446+
initializingTrailingTriviaWith(
447+
UnsafeMutableBufferPointer(rebasing: triviaBuffer[leadingTriviaPieceCount...]))
448+
449+
let byteLength = text.count + triviaBuffer.reduce(0, { $0 + $1.byteLength })
450+
return .materializedToken(
451+
kind: kind, text: text, triviaPieces: RawTriviaPieceBuffer(triviaBuffer),
452+
numLeadingTrivia: numericCast(leadingTriviaPieceCount),
453+
byteLength: numericCast(byteLength),
454+
arena: arena)
455+
}
456+
446457
/// Factory method to create a materialized token node.
447458
///
448459
/// - Parameters:
@@ -470,18 +481,25 @@ extension RawSyntax {
470481
text = SyntaxText()
471482
}
472483

473-
var byteLength = text.count
474-
475-
let triviaPieces = makeRawTriviaPieces(
476-
leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia, arena: arena)
477-
478-
byteLength += triviaPieces.byteLength
479-
480-
return .materializedToken(
481-
kind: rawKind, text: text, triviaPieces: triviaPieces.pieces,
482-
numLeadingTrivia: numericCast(leadingTrivia.count),
483-
byteLength: numericCast(byteLength),
484-
arena: arena)
484+
return .makeMaterializedToken(
485+
kind: rawKind, text: text,
486+
leadingTriviaPieceCount: leadingTrivia.count,
487+
trailingTriviaPieceCount: trailingTrivia.count,
488+
arena: arena,
489+
initializeLeadingTriviaWith: { buffer in
490+
guard var ptr = buffer.baseAddress else { return }
491+
for piece in leadingTrivia {
492+
ptr.initialize(to: .make(piece, arena: arena))
493+
ptr += 1
494+
}
495+
},
496+
initializingTrailingTriviaWith: { buffer in
497+
guard var ptr = buffer.baseAddress else { return }
498+
for piece in trailingTrivia {
499+
ptr.initialize(to: .make(piece, arena: arena))
500+
ptr += 1
501+
}
502+
})
485503
}
486504

487505
static func makeMissingToken(
@@ -531,7 +549,7 @@ extension RawSyntax {
531549
/// - kind: Syntax kind.
532550
/// - count: Number of children.
533551
/// - initializer: A closure that initializes elements.
534-
static func makeLayout(
552+
public static func makeLayout(
535553
kind: SyntaxKind,
536554
uninitializedCount count: Int,
537555
arena: SyntaxArena,
@@ -564,7 +582,7 @@ extension RawSyntax {
564582
)
565583
}
566584

567-
static func makeEmptyLayout(
585+
public static func makeEmptyLayout(
568586
kind: SyntaxKind,
569587
arena: SyntaxArena
570588
) -> RawSyntax {
@@ -582,7 +600,7 @@ extension RawSyntax {
582600
)
583601
}
584602

585-
static func makeLayout<C: Collection>(
603+
public static func makeLayout<C: Collection>(
586604
kind: SyntaxKind,
587605
from collection: C,
588606
arena: SyntaxArena

0 commit comments

Comments
 (0)