From 8d500d1a633717acdf78322f3e28f0619b34fb6e Mon Sep 17 00:00:00 2001 From: JP Simard Date: Mon, 19 Sep 2022 12:39:35 +0200 Subject: [PATCH] Rewrite `empty_collection_literal` with SwiftSyntax (#4220) --- .../EmptyCollectionLiteralRule.swift | 41 +++++++++++++++---- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/Source/SwiftLintFramework/Rules/Performance/EmptyCollectionLiteralRule.swift b/Source/SwiftLintFramework/Rules/Performance/EmptyCollectionLiteralRule.swift index a1bd3fca1d..22a2a3c454 100644 --- a/Source/SwiftLintFramework/Rules/Performance/EmptyCollectionLiteralRule.swift +++ b/Source/SwiftLintFramework/Rules/Performance/EmptyCollectionLiteralRule.swift @@ -1,6 +1,6 @@ -import SourceKittenFramework +import SwiftSyntax -public struct EmptyCollectionLiteralRule: ConfigurationProviderRule, OptInRule { +public struct EmptyCollectionLiteralRule: SwiftSyntaxRule, ConfigurationProviderRule, OptInRule { public var configuration = SeverityConfiguration(.warning) public init() {} @@ -28,13 +28,36 @@ public struct EmptyCollectionLiteralRule: ConfigurationProviderRule, OptInRule { ] ) - public func validate(file: SwiftLintFile) -> [StyleViolation] { - let pattern = "\\b\\s*(==|!=)\\s*\\[\\s*:?\\s*\\]" - let excludingKinds = SyntaxKind.commentAndStringKinds - return file.match(pattern: pattern, excludingSyntaxKinds: excludingKinds).map { - StyleViolation(ruleDescription: Self.description, - severity: configuration.severity, - location: Location(file: file, characterOffset: $0.location)) + public func makeVisitor(file: SwiftLintFile) -> ViolationsSyntaxVisitor? { + Visitor() + } +} + +private extension EmptyCollectionLiteralRule { + final class Visitor: SyntaxVisitor, ViolationsSyntaxVisitor { + private(set) var violationPositions: [AbsolutePosition] = [] + + override func visitPost(_ node: TokenSyntax) { + guard + node.tokenKind.isEqualityComparison, + let violationPosition = node.previousToken?.endPositionBeforeTrailingTrivia, + let expectedLeftSquareBracketToken = node.nextToken, + expectedLeftSquareBracketToken.tokenKind == .leftSquareBracket, + let expectedColonToken = expectedLeftSquareBracketToken.nextToken, + expectedColonToken.tokenKind == .colon || expectedColonToken.tokenKind == .rightSquareBracket + else { + return + } + + violationPositions.append(violationPosition) } } } + +private extension TokenKind { + var isEqualityComparison: Bool { + self == .spacedBinaryOperator("==") || + self == .spacedBinaryOperator("!=") || + self == .unspacedBinaryOperator("==") + } +}