1414import SwiftDiagnostics
1515import SwiftSyntax
1616import SwiftParser
17+ import SwiftOperators
1718import Foundation
1819import ArgumentParser
1920#if os(Windows)
@@ -51,6 +52,19 @@ class SwiftParserTest: ParsableCommand {
5152 )
5253}
5354
55+ /// Fold all of the sequences in the given source file.
56+ func foldAllSequences( _ tree: SourceFileSyntax ) -> ( Syntax , [ Diagnostic ] ) {
57+ var diags : [ Diagnostic ] = [ ]
58+
59+ let recordOperatorError : ( OperatorError ) -> Void = { error in
60+ diags. append ( error. asDiagnostic)
61+ }
62+ var operatorTable = OperatorTable . standardOperators
63+ operatorTable. addSourceFile ( tree, errorHandler: recordOperatorError)
64+ let resultTree = operatorTable. foldAll ( tree, errorHandler: recordOperatorError)
65+ return ( Syntax ( resultTree) , diags)
66+ }
67+
5468class VerifyRoundTrip : ParsableCommand {
5569 required init ( ) { }
5670
@@ -69,6 +83,10 @@ class VerifyRoundTrip: ParsableCommand {
6983 @Option ( name: . long, help: " Enable or disable the use of forward slash regular-expression literal syntax " )
7084 var enableBareSlashRegex : Bool ?
7185
86+ @Flag ( name: . long,
87+ help: " Perform sequence folding with the standard operators " )
88+ var foldSequences : Bool = false
89+
7290 enum Error : Swift . Error , CustomStringConvertible {
7391 case roundTripFailed
7492
@@ -86,21 +104,30 @@ class VerifyRoundTrip: ParsableCommand {
86104 try source. withUnsafeBufferPointer { sourceBuffer in
87105 try Self . run (
88106 source: sourceBuffer, swiftVersion: swiftVersion,
89- enableBareSlashRegex: enableBareSlashRegex
107+ enableBareSlashRegex: enableBareSlashRegex,
108+ foldSequences: foldSequences
90109 )
91110 }
92111 }
93112
94113 static func run(
95114 source: UnsafeBufferPointer < UInt8 > , swiftVersion: String ? ,
96- enableBareSlashRegex: Bool ?
115+ enableBareSlashRegex: Bool ? , foldSequences : Bool
97116 ) throws {
98117 let tree = try Parser . parse (
99118 source: source,
100119 languageVersion: swiftVersion,
101120 enableBareSlashRegexLiteral: enableBareSlashRegex
102121 )
103- if tree. syntaxTextBytes != [ UInt8] ( source) {
122+
123+ let resultTree : Syntax
124+ if foldSequences {
125+ resultTree = foldAllSequences ( tree) . 0
126+ } else {
127+ resultTree = Syntax ( tree)
128+ }
129+
130+ if resultTree. syntaxTextBytes != [ UInt8] ( source) {
104131 throw Error . roundTripFailed
105132 }
106133 }
@@ -118,6 +145,10 @@ class PrintDiags: ParsableCommand {
118145 @Option ( name: . long, help: " Enable or disable the use of forward slash regular-expression literal syntax " )
119146 var enableBareSlashRegex : Bool ?
120147
148+ @Flag ( name: . long,
149+ help: " Perform sequence folding with the standard operators " )
150+ var foldSequences : Bool = false
151+
121152 func run( ) throws {
122153 let source = try getContentsOfSourceFile ( at: sourceFile)
123154
@@ -127,7 +158,12 @@ class PrintDiags: ParsableCommand {
127158 languageVersion: swiftVersion,
128159 enableBareSlashRegexLiteral: enableBareSlashRegex
129160 )
130- let diags = ParseDiagnosticsGenerator . diagnostics ( for: tree)
161+ var diags = ParseDiagnosticsGenerator . diagnostics ( for: tree)
162+
163+ if foldSequences {
164+ diags += foldAllSequences ( tree) . 1
165+ }
166+
131167 if diags. isEmpty {
132168 print ( " No diagnostics produced " )
133169 }
@@ -150,6 +186,10 @@ class DumpTree: ParsableCommand {
150186 @Option ( name: . long, help: " Enable or disable the use of forward slash regular-expression literal syntax " )
151187 var enableBareSlashRegex : Bool ?
152188
189+ @Flag ( name: . long,
190+ help: " Perform sequence folding with the standard operators " )
191+ var foldSequences : Bool = false
192+
153193 func run( ) throws {
154194 let source = try getContentsOfSourceFile ( at: sourceFile)
155195
@@ -159,7 +199,15 @@ class DumpTree: ParsableCommand {
159199 languageVersion: swiftVersion,
160200 enableBareSlashRegexLiteral: enableBareSlashRegex
161201 )
162- print ( tree. recursiveDescription)
202+
203+ let resultTree : Syntax
204+ if foldSequences {
205+ resultTree = foldAllSequences ( tree) . 0
206+ } else {
207+ resultTree = Syntax ( tree)
208+ }
209+
210+ print ( resultTree. recursiveDescription)
163211 }
164212 }
165213}
@@ -176,6 +224,10 @@ class Reduce: ParsableCommand {
176224 @Option ( name: . long, help: " Enable or disable the use of forward slash regular-expression literal syntax " )
177225 var enableBareSlashRegex : Bool ?
178226
227+ @Flag ( name: . long,
228+ help: " Perform sequence folding with the standard operators " )
229+ var foldSequences : Bool = false
230+
179231 @Flag ( help: " Print status updates while reducing the test case " )
180232 var verbose : Bool = false
181233
@@ -220,6 +272,10 @@ class Reduce: ParsableCommand {
220272 " --swift-version " , swiftVersion
221273 ]
222274 }
275+ if foldSequences {
276+ process. arguments! += [ " --fold-sequences " ]
277+ }
278+
223279 let sema = DispatchSemaphore ( value: 0 )
224280 process. standardOutput = FileHandle . nullDevice
225281 process. standardError = FileHandle . nullDevice
@@ -252,7 +308,8 @@ class Reduce: ParsableCommand {
252308 private func runVerifyRoundTripInCurrentProcess( source: [ UInt8 ] ) throws -> Bool {
253309 do {
254310 try source. withUnsafeBufferPointer { sourceBuffer in
255- try VerifyRoundTrip . run ( source: sourceBuffer, swiftVersion: self . swiftVersion, enableBareSlashRegex: self . enableBareSlashRegex)
311+ try VerifyRoundTrip . run ( source: sourceBuffer, swiftVersion: self . swiftVersion, enableBareSlashRegex: self . enableBareSlashRegex,
312+ foldSequences: foldSequences)
256313 }
257314 } catch {
258315 return false
0 commit comments