diff --git a/Sources/SwiftFormat/Pipelines+Generated.swift b/Sources/SwiftFormat/Pipelines+Generated.swift index bc748aa1..8fb86cbd 100644 --- a/Sources/SwiftFormat/Pipelines+Generated.swift +++ b/Sources/SwiftFormat/Pipelines+Generated.swift @@ -321,28 +321,28 @@ class LintPipeline: SyntaxVisitor { extension FormatPipeline { - func visit(_ node: Syntax) -> Syntax { + func rewrite(_ node: Syntax) -> Syntax { var node = node - node = DoNotUseSemicolons(context: context).visit(node) - node = FileScopedDeclarationPrivacy(context: context).visit(node) - node = FullyIndirectEnum(context: context).visit(node) - node = GroupNumericLiterals(context: context).visit(node) - node = NoAccessLevelOnExtensionDeclaration(context: context).visit(node) - node = NoAssignmentInExpressions(context: context).visit(node) - node = NoCasesWithOnlyFallthrough(context: context).visit(node) - node = NoEmptyTrailingClosureParentheses(context: context).visit(node) - node = NoLabelsInCasePatterns(context: context).visit(node) - node = NoParensAroundConditions(context: context).visit(node) - node = NoVoidReturnOnFunctionSignature(context: context).visit(node) - node = OneCasePerLine(context: context).visit(node) - node = OneVariableDeclarationPerLine(context: context).visit(node) - node = OrderedImports(context: context).visit(node) - node = ReturnVoidInsteadOfEmptyTuple(context: context).visit(node) - node = UseEarlyExits(context: context).visit(node) - node = UseShorthandTypeNames(context: context).visit(node) - node = UseSingleLinePropertyGetter(context: context).visit(node) - node = UseTripleSlashForDocumentationComments(context: context).visit(node) - node = UseWhereClausesInForLoops(context: context).visit(node) + node = DoNotUseSemicolons(context: context).rewrite(node) + node = FileScopedDeclarationPrivacy(context: context).rewrite(node) + node = FullyIndirectEnum(context: context).rewrite(node) + node = GroupNumericLiterals(context: context).rewrite(node) + node = NoAccessLevelOnExtensionDeclaration(context: context).rewrite(node) + node = NoAssignmentInExpressions(context: context).rewrite(node) + node = NoCasesWithOnlyFallthrough(context: context).rewrite(node) + node = NoEmptyTrailingClosureParentheses(context: context).rewrite(node) + node = NoLabelsInCasePatterns(context: context).rewrite(node) + node = NoParensAroundConditions(context: context).rewrite(node) + node = NoVoidReturnOnFunctionSignature(context: context).rewrite(node) + node = OneCasePerLine(context: context).rewrite(node) + node = OneVariableDeclarationPerLine(context: context).rewrite(node) + node = OrderedImports(context: context).rewrite(node) + node = ReturnVoidInsteadOfEmptyTuple(context: context).rewrite(node) + node = UseEarlyExits(context: context).rewrite(node) + node = UseShorthandTypeNames(context: context).rewrite(node) + node = UseSingleLinePropertyGetter(context: context).rewrite(node) + node = UseTripleSlashForDocumentationComments(context: context).rewrite(node) + node = UseWhereClausesInForLoops(context: context).rewrite(node) return node } } diff --git a/Sources/SwiftFormat/SwiftFormatter.swift b/Sources/SwiftFormat/SwiftFormatter.swift index a4a1654a..5902805e 100644 --- a/Sources/SwiftFormat/SwiftFormatter.swift +++ b/Sources/SwiftFormat/SwiftFormatter.swift @@ -151,7 +151,7 @@ public final class SwiftFormatter { configuration: configuration, operatorTable: operatorTable, findingConsumer: findingConsumer, fileURL: assumedURL, sourceFileSyntax: syntax, source: source, ruleNameCache: ruleNameCache) let pipeline = FormatPipeline(context: context) - let transformedSyntax = pipeline.visit(Syntax(syntax)) + let transformedSyntax = pipeline.rewrite(Syntax(syntax)) if debugOptions.contains(.disablePrettyPrint) { outputStream.write(transformedSyntax.description) diff --git a/Sources/SwiftFormatCore/Context.swift b/Sources/SwiftFormatCore/Context.swift index 870a3ebc..9dbd886c 100644 --- a/Sources/SwiftFormatCore/Context.swift +++ b/Sources/SwiftFormatCore/Context.swift @@ -14,6 +14,7 @@ import Foundation import SwiftFormatConfiguration import SwiftOperators import SwiftSyntax +import SwiftParser /// Context contains the bits that each formatter and linter will need access to. /// @@ -74,9 +75,8 @@ public final class Context { self.findingEmitter = FindingEmitter(consumer: findingConsumer) self.fileURL = fileURL self.importsXCTest = .notDetermined - self.sourceLocationConverter = - source.map { SourceLocationConverter(file: fileURL.relativePath, source: $0) } - ?? SourceLocationConverter(file: fileURL.relativePath, tree: sourceFileSyntax) + let tree = source.map { Parser.parse(source: $0) } ?? sourceFileSyntax + self.sourceLocationConverter = SourceLocationConverter(file: fileURL.relativePath, tree: tree) self.ruleMask = RuleMask( syntaxNode: Syntax(sourceFileSyntax), sourceLocationConverter: sourceLocationConverter diff --git a/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift b/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift index 16432baa..5aaeed3d 100644 --- a/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift +++ b/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift @@ -532,7 +532,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { // MARK: - Control flow statement nodes override func visit(_ node: LabeledStmtSyntax) -> SyntaxVisitorContinueKind { - after(node.labelColon, tokens: .space) + after(node.colon, tokens: .space) return .visitChildren } @@ -1156,9 +1156,9 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { if let signature = node.signature { after(node.leftBrace, tokens: .break(.open)) if node.statements.count > 0 { - after(signature.inTok, tokens: .break(.same, newlines: newlineBehavior)) + after(signature.inKeyword, tokens: .break(.same, newlines: newlineBehavior)) } else { - after(signature.inTok, tokens: .break(.same, size: 0, newlines: newlineBehavior)) + after(signature.inKeyword, tokens: .break(.same, size: 0, newlines: newlineBehavior)) } before(node.rightBrace, tokens: .break(.close)) } else { @@ -1207,7 +1207,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { // Due to visitation order, the matching .open break is added in ParameterClauseSyntax. // Since the output clause is optional but the in-token is required, placing the .close // before `inTok` ensures the close gets into the token stream. - before(node.inTok, tokens: .close) + before(node.inKeyword, tokens: .close) } else { // Group outside of the parens, so that the argument list together, preferring to break // between the argument list and the output. @@ -1226,7 +1226,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { before(node.output?.arrow, tokens: .break) after(node.lastToken(viewMode: .sourceAccurate), tokens: .close) - before(node.inTok, tokens: .break(.same)) + before(node.inKeyword, tokens: .break(.same)) return .visitChildren } @@ -1239,8 +1239,8 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { override func visit(_ node: ClosureCaptureItemSyntax) -> SyntaxVisitorContinueKind { before(node.firstToken(viewMode: .sourceAccurate), tokens: .open) after(node.specifier?.lastToken(viewMode: .sourceAccurate), tokens: .break) - before(node.assignToken, tokens: .break) - after(node.assignToken, tokens: .break) + before(node.equal, tokens: .break) + after(node.equal, tokens: .break) if let trailingComma = node.trailingComma { before(trailingComma, tokens: .close) after(trailingComma, tokens: .break(.same)) @@ -1274,8 +1274,8 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { arrangeFunctionCallArgumentList( arguments, - leftDelimiter: node.leftBracket, - rightDelimiter: node.rightBracket, + leftDelimiter: node.leftSquare, + rightDelimiter: node.rightSquare, forcesBreakBeforeRightDelimiter: breakBeforeRightBracket) return .visitChildren @@ -1506,7 +1506,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { appendFormatterIgnored(node: Syntax(node)) return .skipChildren } - after(node.eofToken, tokens: .break(.same, newlines: .soft)) + after(node.endOfFileToken, tokens: .break(.same, newlines: .soft)) return .visitChildren } @@ -1638,14 +1638,14 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { } override func visit(_ node: GenericParameterClauseSyntax) -> SyntaxVisitorContinueKind { - after(node.leftAngleBracket, tokens: .break(.open, size: 0), .open(argumentListConsistency())) - before(node.rightAngleBracket, tokens: .break(.close, size: 0), .close) + after(node.leftAngle, tokens: .break(.open, size: 0), .open(argumentListConsistency())) + before(node.rightAngle, tokens: .break(.close, size: 0), .close) return .visitChildren } override func visit(_ node: PrimaryAssociatedTypeClauseSyntax) -> SyntaxVisitorContinueKind { - after(node.leftAngleBracket, tokens: .break(.open, size: 0), .open(argumentListConsistency())) - before(node.rightAngleBracket, tokens: .break(.close, size: 0), .close) + after(node.leftAngle, tokens: .break(.open, size: 0), .open(argumentListConsistency())) + before(node.rightAngle, tokens: .break(.close, size: 0), .close) return .visitChildren } @@ -1681,8 +1681,8 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { } override func visit(_ node: GenericArgumentClauseSyntax) -> SyntaxVisitorContinueKind { - after(node.leftAngleBracket, tokens: .break(.open, size: 0), .open) - before(node.rightAngleBracket, tokens: .break(.close, size: 0), .close) + after(node.leftAngle, tokens: .break(.open, size: 0), .open) + before(node.rightAngle, tokens: .break(.close, size: 0), .close) return .visitChildren } @@ -1865,8 +1865,8 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { } override func visit(_ node: KeyPathSubscriptComponentSyntax) -> SyntaxVisitorContinueKind { - after(node.leftBracket, tokens: .break(.open, size: 0), .open) - before(node.rightBracket, tokens: .break(.close, size: 0), .close) + after(node.leftSquare, tokens: .break(.open, size: 0), .open) + before(node.rightSquare, tokens: .break(.close, size: 0), .close) return .visitChildren } @@ -1878,9 +1878,9 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { before(node.questionMark, tokens: .break(.open(kind: .continuation)), .open) after(node.questionMark, tokens: .space) before( - node.colonMark, + node.colon, tokens: .break(.close(mustBreak: false), size: 0), .break(.open(kind: .continuation)), .open) - after(node.colonMark, tokens: .space) + after(node.colon, tokens: .space) // When the ternary is wrapped in parens, absorb the closing paren into the ternary's group so // that it is glued to the last token of the ternary. @@ -2053,14 +2053,14 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { } override func visit(_ node: AsExprSyntax) -> SyntaxVisitorContinueKind { - before(node.asTok, tokens: .break(.continue), .open) + before(node.asKeyword, tokens: .break(.continue), .open) before(node.typeName.firstToken(viewMode: .sourceAccurate), tokens: .space) after(node.lastToken(viewMode: .sourceAccurate), tokens: .close) return .visitChildren } override func visit(_ node: IsExprSyntax) -> SyntaxVisitorContinueKind { - before(node.isTok, tokens: .break(.continue), .open) + before(node.isKeyword, tokens: .break(.continue), .open) before(node.typeName.firstToken(viewMode: .sourceAccurate), tokens: .space) after(node.lastToken(viewMode: .sourceAccurate), tokens: .close) return .visitChildren @@ -2081,8 +2081,8 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { } override func visit(_ node: ArrowExprSyntax) -> SyntaxVisitorContinueKind { - before(node.arrowToken, tokens: .break) - after(node.arrowToken, tokens: .space) + before(node.arrow, tokens: .break) + after(node.arrow, tokens: .space) return .visitChildren } @@ -2563,7 +2563,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { // `DerivativeRegistrationAttributeArguments` was added after the Swift 5.2 release was cut. #if HAS_DERIVATIVE_REGISTRATION_ATTRIBUTE - override func visit(_ node: DerivativeRegistrationAttributeArgumentsSyntax) + override func rewrite(_ node: DerivativeRegistrationAttributeArgumentsSyntax) -> SyntaxVisitorContinueKind { // This node encapsulates the entire list of arguments in a `@derivative(...)` or @@ -3411,7 +3411,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { return true } if let binOpExpr = operatorExpr.as(BinaryOperatorExprSyntax.self) { - if let binOp = operatorTable.infixOperator(named: binOpExpr.operatorToken.text), + if let binOp = operatorTable.infixOperator(named: binOpExpr.operator.text), let precedenceGroup = binOp.precedenceGroup, precedenceGroup == "AssignmentPrecedence" { return true @@ -3537,7 +3537,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { // We also want to reset after undoing the stacked indentation so that we have a visual // indication that the subexpression has ended. if let binOpExpr = operatorExpr?.as(BinaryOperatorExprSyntax.self) { - if let binOp = operatorTable.infixOperator(named: binOpExpr.operatorToken.text), + if let binOp = operatorTable.infixOperator(named: binOpExpr.operator.text), let precedenceGroup = binOp.precedenceGroup, precedenceGroup == "LogicalConjunctionPrecedence" || precedenceGroup == "LogicalDisjunctionPrecedence" @@ -3646,7 +3646,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { // The token kind (spaced or unspaced operator) represents how the *user* wrote it, and we want // to ignore that and apply our own rules. if let binaryOperator = operatorExpr.as(BinaryOperatorExprSyntax.self) { - let token = binaryOperator.operatorToken + let token = binaryOperator.operator if !config.spacesAroundRangeFormationOperators, let binOp = operatorTable.infixOperator(named: token.text), let precedenceGroup = binOp.precedenceGroup, precedenceGroup == "RangeFormationPrecedence" @@ -3742,7 +3742,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { // scoping tokens (e.g. `contextualBreakingStart`, `open`). if memberAccessExpr.base != nil && expr.parent?.isProtocol(CallingExprSyntaxProtocol.self) != true { - before(memberAccessExpr.dot, tokens: .break(.contextual, size: 0)) + before(memberAccessExpr.period, tokens: .break(.contextual, size: 0)) } var hasCompoundExpression = false if let base = memberAccessExpr.base { @@ -3786,12 +3786,12 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { if let calledMemberAccessExpr = calledExpression.as(MemberAccessExprSyntax.self) { if calledMemberAccessExpr.base != nil { if isNestedInPostfixIfConfig(node: Syntax(calledMemberAccessExpr)) { - before(calledMemberAccessExpr.dot, tokens: [.break(.same, size: 0)]) + before(calledMemberAccessExpr.period, tokens: [.break(.same, size: 0)]) } else { - before(calledMemberAccessExpr.dot, tokens: [.break(.contextual, size: 0)]) + before(calledMemberAccessExpr.period, tokens: [.break(.contextual, size: 0)]) } } - before(calledMemberAccessExpr.dot, tokens: beforeTokens) + before(calledMemberAccessExpr.period, tokens: beforeTokens) after(expr.lastToken(viewMode: .sourceAccurate), tokens: afterTokens) if isTopLevel { before(expr.firstToken(viewMode: .sourceAccurate), tokens: .contextualBreakingStart) @@ -3839,7 +3839,7 @@ private func isNestedInPostfixIfConfig(node: Syntax) -> Bool { extension Syntax { /// Creates a pretty-printable token stream for the provided Syntax node. func makeTokenStream(configuration: Configuration, operatorTable: OperatorTable) -> [Token] { - let commentsMoved = CommentMovingRewriter().visit(self) + let commentsMoved = CommentMovingRewriter().rewrite(self) return TokenStreamCreator(configuration: configuration, operatorTable: operatorTable) .makeStream(from: commentsMoved) } @@ -3884,13 +3884,13 @@ class CommentMovingRewriter: SyntaxRewriter { override func visit(_ node: InfixOperatorExprSyntax) -> ExprSyntax { if let binaryOperatorExpr = node.operatorOperand.as(BinaryOperatorExprSyntax.self), - let followingToken = binaryOperatorExpr.operatorToken.nextToken(viewMode: .all), + let followingToken = binaryOperatorExpr.operator.nextToken(viewMode: .all), followingToken.leadingTrivia.hasLineComment { // Rewrite the trivia so that the comment is in the operator token's leading trivia. let (remainingTrivia, extractedTrivia) = extractLineCommentTrivia(from: followingToken) - let combinedTrivia = binaryOperatorExpr.operatorToken.leadingTrivia + extractedTrivia - rewriteTokenTriviaMap[binaryOperatorExpr.operatorToken] = combinedTrivia + let combinedTrivia = binaryOperatorExpr.operator.leadingTrivia + extractedTrivia + rewriteTokenTriviaMap[binaryOperatorExpr.operator] = combinedTrivia rewriteTokenTriviaMap[followingToken] = remainingTrivia } return super.visit(node) diff --git a/Sources/SwiftFormatRules/AddModifierRewriter.swift b/Sources/SwiftFormatRules/AddModifierRewriter.swift index f58a4472..5ea4aa30 100644 --- a/Sources/SwiftFormatRules/AddModifierRewriter.swift +++ b/Sources/SwiftFormatRules/AddModifierRewriter.swift @@ -186,5 +186,5 @@ func addModifier( declaration: DeclSyntax, modifierKeyword: DeclModifierSyntax ) -> Syntax { - return AddModifierRewriter(modifierKeyword: modifierKeyword).visit(Syntax(declaration)) + return AddModifierRewriter(modifierKeyword: modifierKeyword).rewrite(Syntax(declaration)) } diff --git a/Sources/SwiftFormatRules/DoNotUseSemicolons.swift b/Sources/SwiftFormatRules/DoNotUseSemicolons.swift index 604ece25..59cea384 100644 --- a/Sources/SwiftFormatRules/DoNotUseSemicolons.swift +++ b/Sources/SwiftFormatRules/DoNotUseSemicolons.swift @@ -43,7 +43,7 @@ public final class DoNotUseSemicolons: SyntaxFormatRule { // Check for semicolons in statements inside of the item, because code blocks may be nested // inside of other code blocks. - guard let visitedItem = visit(Syntax(item)).as(ItemType.self) else { + guard let visitedItem = rewrite(Syntax(item)).as(ItemType.self) else { return node } diff --git a/Sources/SwiftFormatRules/NoAssignmentInExpressions.swift b/Sources/SwiftFormatRules/NoAssignmentInExpressions.swift index 7384c5f3..fa27da83 100644 --- a/Sources/SwiftFormatRules/NoAssignmentInExpressions.swift +++ b/Sources/SwiftFormatRules/NoAssignmentInExpressions.swift @@ -108,7 +108,7 @@ public final class NoAssignmentInExpressions: SyntaxFormatRule { guard let binaryOp = expr.operatorOperand.as(BinaryOperatorExprSyntax.self) else { return false } - return context.operatorTable.infixOperator(named: binaryOp.operatorToken.text)?.precedenceGroup + return context.operatorTable.infixOperator(named: binaryOp.operator.text)?.precedenceGroup == "AssignmentPrecedence" } diff --git a/Sources/SwiftFormatRules/NoEmptyTrailingClosureParentheses.swift b/Sources/SwiftFormatRules/NoEmptyTrailingClosureParentheses.swift index 6bc786e9..d8936562 100644 --- a/Sources/SwiftFormatRules/NoEmptyTrailingClosureParentheses.swift +++ b/Sources/SwiftFormatRules/NoEmptyTrailingClosureParentheses.swift @@ -37,7 +37,7 @@ public final class NoEmptyTrailingClosureParentheses: SyntaxFormatRule { // Need to visit `calledExpression` before creating a new node so that the location data (column // and line numbers) is available. - guard let rewrittenCalledExpr = ExprSyntax(visit(Syntax(node.calledExpression))) else { + guard let rewrittenCalledExpr = ExprSyntax(rewrite(Syntax(node.calledExpression))) else { return super.visit(node) } let formattedExp = replaceTrivia( diff --git a/Sources/SwiftFormatRules/ReplaceTrivia.swift b/Sources/SwiftFormatRules/ReplaceTrivia.swift index 4c3f5351..e389d9e7 100644 --- a/Sources/SwiftFormatRules/ReplaceTrivia.swift +++ b/Sources/SwiftFormatRules/ReplaceTrivia.swift @@ -59,5 +59,5 @@ func replaceTrivia( token: token, leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia - ).visit(Syntax(node)).as(SyntaxType.self)! + ).rewrite(Syntax(node)).as(SyntaxType.self)! } diff --git a/Sources/SwiftFormatRules/UseShorthandTypeNames.swift b/Sources/SwiftFormatRules/UseShorthandTypeNames.swift index aadbb63f..4ce6dea3 100644 --- a/Sources/SwiftFormatRules/UseShorthandTypeNames.swift +++ b/Sources/SwiftFormatRules/UseShorthandTypeNames.swift @@ -241,7 +241,7 @@ public final class UseShorthandTypeNames: SyntaxFormatRule { // otherwise the "?" applies to the return type instead of the function type. Attach the // leading trivia to the left-paren that we're adding in this case. let tupleTypeElement = TupleTypeElementSyntax( - inOut: nil, name: nil, secondName: nil, colon: nil, type: TypeSyntax(functionType), + inoutKeyword: nil, name: nil, secondName: nil, colon: nil, type: TypeSyntax(functionType), ellipsis: nil, initializer: nil, trailingComma: nil) let tupleTypeElementList = TupleTypeElementListSyntax([tupleTypeElement]) let tupleType = TupleTypeSyntax( @@ -384,7 +384,7 @@ public final class UseShorthandTypeNames: SyntaxFormatRule { } let result = MemberAccessExprSyntax( base: baseType, - dot: memberTypeIdentifier.period, + period: memberTypeIdentifier.period, name: memberTypeIdentifier.name, declNameArguments: nil) return ExprSyntax(result) @@ -475,7 +475,7 @@ public final class UseShorthandTypeNames: SyntaxFormatRule { rightParen: rightParen) let arrowExpr = ArrowExprSyntax( effectSpecifiers: effectSpecifiers, - arrowToken: arrow) + arrow: arrow) return SequenceExprSyntax( elements: ExprListSyntax([ diff --git a/Sources/generate-pipeline/PipelineGenerator.swift b/Sources/generate-pipeline/PipelineGenerator.swift index e0455f58..8a92036c 100644 --- a/Sources/generate-pipeline/PipelineGenerator.swift +++ b/Sources/generate-pipeline/PipelineGenerator.swift @@ -95,7 +95,7 @@ final class PipelineGenerator: FileGenerator { extension FormatPipeline { - func visit(_ node: Syntax) -> Syntax { + func rewrite(_ node: Syntax) -> Syntax { var node = node """ @@ -104,7 +104,7 @@ final class PipelineGenerator: FileGenerator { for ruleName in ruleCollector.allFormatters.map({ $0.typeName }).sorted() { handle.write( """ - node = \(ruleName)(context: context).visit(node) + node = \(ruleName)(context: context).rewrite(node) """) } diff --git a/Tests/SwiftFormatCoreTests/RuleMaskTests.swift b/Tests/SwiftFormatCoreTests/RuleMaskTests.swift index b4303b85..8ba56b17 100644 --- a/Tests/SwiftFormatCoreTests/RuleMaskTests.swift +++ b/Tests/SwiftFormatCoreTests/RuleMaskTests.swift @@ -11,8 +11,8 @@ final class RuleMaskTests: XCTestCase { private func createMask(sourceText: String) -> RuleMask { let fileURL = URL(fileURLWithPath: "/tmp/test.swift") - converter = SourceLocationConverter(file: fileURL.path, source: sourceText) let syntax = Parser.parse(source: sourceText) + converter = SourceLocationConverter(file: fileURL.path, tree: syntax) return RuleMask(syntaxNode: Syntax(syntax), sourceLocationConverter: converter) }