Skip to content

Commit b97b41f

Browse files
authored
Merge pull request swiftlang#1478 from bnbarham/merge-trivia
Add a function to merge trivia from a node into an existing trivia
2 parents db88373 + ca6d6b5 commit b97b41f

File tree

9 files changed

+244
-434
lines changed

9 files changed

+244
-434
lines changed

CodeGeneration/Sources/generate-swiftsyntax/GenerateSwiftSyntax.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ struct GenerateSwiftSyntax: ParsableCommand {
106106
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["SyntaxVisitor.swift"], syntaxVisitorFile),
107107
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["TokenKind.swift"], tokenKindFile),
108108
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["Tokens.swift"], tokensFile),
109-
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["Trivia.swift"], triviaFile),
109+
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["TriviaPieces.swift"], triviaPiecesFile),
110110

111111
// SwiftSyntaxBuilder
112112
GeneratedFileSpec(swiftSyntaxBuilderGeneratedDir + ["BuildableCollectionNodes.swift"], buildableCollectionNodesFile),

CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/TriviaFile.swift renamed to CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/TriviaPiecesFile.swift

Lines changed: 3 additions & 220 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,7 @@ import SwiftSyntaxBuilder
1515
import SyntaxSupport
1616
import Utils
1717

18-
let triviaFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
19-
DeclSyntax(
20-
"""
21-
public enum TriviaPosition {
22-
case leading
23-
case trailing
24-
}
25-
"""
26-
)
27-
18+
let triviaPiecesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
2819
try! EnumDeclSyntax(
2920
"""
3021
/// A contiguous stretch of a single kind of trivia. The constituent part of
@@ -115,88 +106,11 @@ let triviaFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
115106
}
116107
}
117108

118-
DeclSyntax(
119-
"""
120-
extension TriviaPiece {
121-
/// Returns true if the trivia is `.newlines`, `.carriageReturns` or `.carriageReturnLineFeeds`
122-
public var isNewline: Bool {
123-
switch self {
124-
case .newlines,
125-
.carriageReturns,
126-
.carriageReturnLineFeeds:
127-
return true
128-
default:
129-
return false
130-
}
131-
}
132-
}
133-
"""
134-
)
135-
136-
try! StructDeclSyntax(
109+
try! ExtensionDeclSyntax(
137110
"""
138-
/// A collection of leading or trailing trivia. This is the main data structure
139-
/// for thinking about trivia.
140-
public struct Trivia
111+
extension Trivia
141112
"""
142113
) {
143-
DeclSyntax("public let pieces: [TriviaPiece]")
144-
145-
DeclSyntax(
146-
"""
147-
/// Creates Trivia with the provided underlying pieces.
148-
public init<S: Sequence>(pieces: S) where S.Element == TriviaPiece {
149-
self.pieces = Array(pieces)
150-
}
151-
"""
152-
)
153-
154-
DeclSyntax(
155-
"""
156-
/// Creates Trivia with no pieces.
157-
public static var zero: Trivia {
158-
return Trivia(pieces: [])
159-
}
160-
"""
161-
)
162-
163-
DeclSyntax(
164-
"""
165-
/// Whether the Trivia contains no pieces.
166-
public var isEmpty: Bool {
167-
pieces.isEmpty
168-
}
169-
"""
170-
)
171-
172-
DeclSyntax(
173-
"""
174-
/// Creates a new `Trivia` by appending the provided `TriviaPiece` to the end.
175-
public func appending(_ piece: TriviaPiece) -> Trivia {
176-
var copy = pieces
177-
copy.append(piece)
178-
return Trivia(pieces: copy)
179-
}
180-
"""
181-
)
182-
183-
DeclSyntax(
184-
"""
185-
public var sourceLength: SourceLength {
186-
return pieces.map({ $0.sourceLength }).reduce(.zero, +)
187-
}
188-
"""
189-
)
190-
191-
DeclSyntax(
192-
"""
193-
/// Get the byteSize of this trivia
194-
public var byteSize: Int {
195-
return sourceLength.utf8Length
196-
}
197-
"""
198-
)
199-
200114
for trivia in TRIVIAS {
201115
if trivia.isCollection {
202116
let joined = trivia.characters.map { "\($0)" }.joined()
@@ -231,99 +145,6 @@ let triviaFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
231145
}
232146
}
233147

234-
DeclSyntax(
235-
#"""
236-
extension Trivia: CustomDebugStringConvertible {
237-
public var debugDescription: String {
238-
if count == 1, let first = first {
239-
return first.debugDescription
240-
}
241-
return "[" + map(\.debugDescription).joined(separator: ", ") + "]"
242-
}
243-
}
244-
"""#
245-
)
246-
247-
DeclSyntax("extension Trivia: Equatable {}")
248-
249-
DeclSyntax(
250-
"""
251-
/// Conformance for Trivia to the Collection protocol.
252-
extension Trivia: Collection {
253-
public var startIndex: Int {
254-
return pieces.startIndex
255-
}
256-
257-
public var endIndex: Int {
258-
return pieces.endIndex
259-
}
260-
261-
public func index(after i: Int) -> Int {
262-
return pieces.index(after: i)
263-
}
264-
265-
public subscript(_ index: Int) -> TriviaPiece {
266-
return pieces[index]
267-
}
268-
}
269-
"""
270-
)
271-
272-
DeclSyntax(
273-
"""
274-
extension Trivia: ExpressibleByArrayLiteral {
275-
/// Creates Trivia from the provided pieces.
276-
public init(arrayLiteral elements: TriviaPiece...) {
277-
self.pieces = elements
278-
}
279-
}
280-
"""
281-
)
282-
283-
DeclSyntax(
284-
"""
285-
extension Trivia: TextOutputStreamable {
286-
/// Prints the provided trivia as they would be written in a source file.
287-
///
288-
/// - Parameter stream: The stream to which to print the trivia.
289-
public func write<Target>(to target: inout Target)
290-
where Target: TextOutputStream {
291-
for piece in pieces {
292-
piece.write(to: &target)
293-
}
294-
}
295-
}
296-
"""
297-
)
298-
299-
DeclSyntax(
300-
"""
301-
extension Trivia: CustomStringConvertible {
302-
public var description: String {
303-
var description = ""
304-
self.write(to: &description)
305-
return description
306-
}
307-
}
308-
"""
309-
)
310-
311-
DeclSyntax(
312-
"""
313-
extension Trivia {
314-
/// Concatenates two collections of `Trivia` into one collection.
315-
public static func +(lhs: Trivia, rhs: Trivia) -> Trivia {
316-
return Trivia(pieces: lhs.pieces + rhs.pieces)
317-
}
318-
319-
/// Concatenates two collections of `Trivia` into the left-hand side.
320-
public static func +=(lhs: inout Trivia, rhs: Trivia) {
321-
lhs = lhs + rhs
322-
}
323-
}
324-
"""
325-
)
326-
327148
DeclSyntax("extension TriviaPiece: Equatable {}")
328149

329150
try! ExtensionDeclSyntax("extension TriviaPiece") {
@@ -388,26 +209,6 @@ let triviaFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
388209
}
389210
}
390211

391-
DeclSyntax(
392-
"""
393-
extension RawTriviaPiece: TextOutputStreamable {
394-
public func write<Target: TextOutputStream>(to target: inout Target) {
395-
TriviaPiece(raw: self).write(to: &target)
396-
}
397-
}
398-
"""
399-
)
400-
401-
DeclSyntax(
402-
"""
403-
extension RawTriviaPiece: CustomDebugStringConvertible {
404-
public var debugDescription: String {
405-
TriviaPiece(raw: self).debugDescription
406-
}
407-
}
408-
"""
409-
)
410-
411212
try! ExtensionDeclSyntax("extension TriviaPiece") {
412213
try InitializerDeclSyntax("@_spi(RawSyntax) public init(raw: RawTriviaPiece)") {
413214
try SwitchExprSyntax("switch raw") {
@@ -463,22 +264,4 @@ let triviaFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
463264
}
464265
}
465266
}
466-
467-
DeclSyntax(
468-
"""
469-
extension RawTriviaPiece {
470-
/// Returns true if the trivia is `.newlines`, `.carriageReturns` or `.carriageReturnLineFeeds`
471-
public var isNewline: Bool {
472-
switch self {
473-
case .newlines,
474-
.carriageReturns,
475-
.carriageReturnLineFeeds:
476-
return true
477-
default:
478-
return false
479-
}
480-
}
481-
}
482-
"""
483-
)
484267
}

Sources/SwiftParserDiagnostics/DiagnosticExtensions.swift

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,9 @@ extension FixIt.MultiNodeChange {
169169
/// where it makes sense and refusing to add e.g. a space after punctuation,
170170
/// where it usually doesn't make sense.
171171
static func transferTriviaAtSides<SyntaxType: SyntaxProtocol>(from nodes: [SyntaxType]) -> Self {
172-
let removedTriviaAtSides = Trivia.merged(nodes.first?.leadingTrivia ?? [], nodes.last?.trailingTrivia ?? [])
172+
let removedTriviaAtSides = (nodes.first?.leadingTrivia ?? []).merging(nodes.last?.trailingTrivia ?? [])
173173
if !removedTriviaAtSides.isEmpty, let previousToken = nodes.first?.previousToken(viewMode: .sourceAccurate) {
174-
let mergedTrivia = Trivia.merged(previousToken.trailingTrivia, removedTriviaAtSides)
174+
let mergedTrivia = previousToken.trailingTrivia.merging(removedTriviaAtSides)
175175
if previousToken.tokenKind.isPunctuation, mergedTrivia.allSatisfy({ $0.isSpaceOrTab }) {
176176
// Punctuation is generally not followed by spaces in Swift.
177177
// If this action would only add spaces to the punctuation, drop it.
@@ -185,49 +185,6 @@ extension FixIt.MultiNodeChange {
185185
}
186186
}
187187

188-
extension Trivia {
189-
/// Decomposes the trivia into pieces that all have count 1
190-
var decomposed: Trivia {
191-
let pieces = self.flatMap({ (piece: TriviaPiece) -> [TriviaPiece] in
192-
switch piece {
193-
case .spaces(let count):
194-
return Array(repeating: TriviaPiece.spaces(1), count: count)
195-
case .tabs(let count):
196-
return Array(repeating: TriviaPiece.tabs(1), count: count)
197-
case .verticalTabs(let count):
198-
return Array(repeating: TriviaPiece.verticalTabs(1), count: count)
199-
case .formfeeds(let count):
200-
return Array(repeating: TriviaPiece.formfeeds(1), count: count)
201-
case .newlines(let count):
202-
return Array(repeating: TriviaPiece.newlines(1), count: count)
203-
case .backslashes(let count):
204-
return Array(repeating: TriviaPiece.backslashes(1), count: count)
205-
case .pounds(let count):
206-
return Array(repeating: TriviaPiece.pounds(1), count: count)
207-
case .carriageReturns(let count):
208-
return Array(repeating: TriviaPiece.carriageReturns(1), count: count)
209-
case .carriageReturnLineFeeds(let count):
210-
return Array(repeating: TriviaPiece.carriageReturnLineFeeds(1), count: count)
211-
case .lineComment, .blockComment, .docLineComment, .docBlockComment, .unexpectedText, .shebang:
212-
return [piece]
213-
}
214-
})
215-
return Trivia(pieces: pieces)
216-
}
217-
218-
/// Concatenate `lhs` and `rhs`, merging an infix that is shared between both trivia pieces.
219-
static func merged(_ lhs: Trivia, _ rhs: Trivia) -> Self {
220-
let lhs = lhs.decomposed
221-
let rhs = rhs.decomposed
222-
for infixLength in (0...Swift.min(lhs.count, rhs.count)).reversed() {
223-
if lhs.suffix(infixLength) == rhs.suffix(infixLength) {
224-
return lhs + Trivia(pieces: Array(rhs.dropFirst(infixLength)))
225-
}
226-
}
227-
return lhs + rhs
228-
}
229-
}
230-
231188
extension TriviaPiece {
232189
var isSpaceOrTab: Bool {
233190
switch self {

Sources/SwiftParserDiagnostics/MultiLineStringLiteralDiagnosticsGenerator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import SwiftDiagnostics
14-
import SwiftSyntax
14+
@_spi(RawSyntax) import SwiftSyntax
1515

1616
/// A diagnostic that `MultiLineStringLiteralIndentatinDiagnosticsGenerator` is building.
1717
/// As indentation errors are found on more lines, this diagnostic is modified

Sources/SwiftSyntax/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ add_swift_host_library(SwiftSyntax
1212
BumpPtrAllocator.swift
1313
CommonAncestor.swift
1414
IncrementalParseTransition.swift
15+
Trivia.swift
1516
SourceLength.swift
1617
SourceLocation.swift
1718
SourcePresence.swift
@@ -46,7 +47,7 @@ add_swift_host_library(SwiftSyntax
4647
generated/SyntaxVisitor.swift
4748
generated/TokenKind.swift
4849
generated/Tokens.swift
49-
generated/Trivia.swift
50+
generated/TriviaPieces.swift
5051

5152
generated/syntaxNodes/SyntaxDeclNodes.swift
5253
generated/syntaxNodes/SyntaxExprNodes.swift

0 commit comments

Comments
 (0)