@@ -625,6 +625,10 @@ func assertParse<S: SyntaxProtocol>(
625
625
)
626
626
}
627
627
628
+ if expectedDiagnostics. isEmpty {
629
+ assertBasicFormat ( source: source, parse: parse, file: file, line: line)
630
+ }
631
+
628
632
#if SWIFTPARSER_ENABLE_ALTERNATE_TOKEN_INTROSPECTION
629
633
if enableTestCaseMutation {
630
634
let mutations : [ ( offset: Int , replacement: TokenSpec ) ] = parser. alternativeTokenChoices. flatMap { offset, replacements in
@@ -659,3 +663,54 @@ func assertParse<S: SyntaxProtocol>(
659
663
}
660
664
#endif
661
665
}
666
+
667
+ class TriviaRemover : SyntaxRewriter {
668
+ override func visit( _ token: TokenSyntax ) -> TokenSyntax {
669
+ var ancestor = Syntax ( token)
670
+ while let parent = ancestor. parent {
671
+ ancestor = parent
672
+ if ancestor. is ( StringLiteralExprSyntax . self) || ancestor. is ( RegexLiteralExprSyntax . self) {
673
+ // Don't mess with indentation inside string or regex literals.
674
+ // BasicFormat doesn't know where to re-apply newlines and how much to indent the string literal contents.
675
+ return token
676
+ }
677
+ }
678
+ if token. parent? . is ( StringSegmentSyntax . self) ?? false {
679
+ return token
680
+ }
681
+ return token. with ( \. leadingTrivia, [ ] ) . with ( \. trailingTrivia, [ ] )
682
+ }
683
+ }
684
+
685
+ func assertBasicFormat< S: SyntaxProtocol > (
686
+ source: String ,
687
+ parse: ( inout Parser ) -> S ,
688
+ file: StaticString = #file,
689
+ line: UInt = #line
690
+ ) {
691
+ var parser = Parser ( source)
692
+ let sourceTree = Syntax ( parse ( & parser) )
693
+ let withoutTrivia = TriviaRemover ( ) . visit ( sourceTree)
694
+ let formatted = withoutTrivia. formatted ( )
695
+
696
+ var formattedParser = Parser ( formatted. description)
697
+ let formattedReparsed = Syntax ( parse ( & formattedParser) )
698
+
699
+ do {
700
+ let subtreeMatcher = SubtreeMatcher ( Syntax ( formattedReparsed) , markers: [ : ] )
701
+ try subtreeMatcher. assertSameStructure (
702
+ Syntax ( sourceTree) ,
703
+ includeTrivia: false ,
704
+ additionalInfo: """
705
+ Removing trivia, formatting using BasicFormat and re-parsing did not produce the same syntax tree.
706
+
707
+ Formatted source:
708
+ \( formatted)
709
+ """ ,
710
+ file: file,
711
+ line: line
712
+ )
713
+ } catch {
714
+ XCTFail ( " Matching for a subtree failed with error: \( error) " , file: file, line: line)
715
+ }
716
+ }
0 commit comments