mirror of
https://github.com/realm/SwiftLint.git
synced 2026-06-06 20:18:40 +00:00
5a30991fa4
This cuts down on the boilerplate involved in writing SwiftSyntax-based rules. May not be significant right now since most rules are still built with SourceKit, but as we migrate more rules moving forward, this should make it easier for rule authors to write rules that behave performantly and correctly.
65 lines
2.6 KiB
Swift
65 lines
2.6 KiB
Swift
import SourceKittenFramework
|
|
|
|
/// A rule that leverages the Swift source's pre-typechecked Abstract Syntax Tree to recurse into the source's
|
|
/// structure, validating the rule recursively in nested source bodies.
|
|
public protocol ASTRule: Rule {
|
|
/// The kind of token being recursed over.
|
|
associatedtype KindType: RawRepresentable
|
|
|
|
/// Executes the rule on a file and a subset of its AST structure, returning any violations to the rule's
|
|
/// expectations.
|
|
///
|
|
/// - parameter file: The file for which to execute the rule.
|
|
/// - parameter kind: The kind of token being recursed over.
|
|
/// - parameter dictionary: The dictionary for an AST subset to validate.
|
|
///
|
|
/// - returns: All style violations to the rule's expectations.
|
|
func validate(file: SwiftLintFile, kind: KindType, dictionary: SourceKittenDictionary) -> [StyleViolation]
|
|
|
|
/// Get the `kind` from the specified dictionary.
|
|
///
|
|
/// - parameter dictionary: The `SourceKittenDictionary` representing the source structure from which to extract the
|
|
/// `kind`.
|
|
///
|
|
/// - returns: The `kind` from the specified dictionary, if one was found.
|
|
func kind(from dictionary: SourceKittenDictionary) -> KindType?
|
|
}
|
|
|
|
public extension ASTRule {
|
|
func validate(file: SwiftLintFile) -> [StyleViolation] {
|
|
return validate(file: file, dictionary: file.structureDictionary)
|
|
}
|
|
|
|
/// Executes the rule on a file and a subset of its AST structure, returning any violations to the rule's
|
|
/// expectations.
|
|
///
|
|
/// - parameter file: The file for which to execute the rule.
|
|
/// - parameter dictionary: The dictionary for an AST subset to validate.
|
|
///
|
|
/// - returns: All style violations to the rule's expectations.
|
|
func validate(file: SwiftLintFile, dictionary: SourceKittenDictionary) -> [StyleViolation] {
|
|
return dictionary.traverseDepthFirst { subDict in
|
|
guard let kind = self.kind(from: subDict) else { return nil }
|
|
return validate(file: file, kind: kind, dictionary: subDict)
|
|
}
|
|
}
|
|
}
|
|
|
|
public extension ASTRule where KindType == SwiftDeclarationKind {
|
|
func kind(from dictionary: SourceKittenDictionary) -> KindType? {
|
|
return dictionary.declarationKind
|
|
}
|
|
}
|
|
|
|
public extension ASTRule where KindType == SwiftExpressionKind {
|
|
func kind(from dictionary: SourceKittenDictionary) -> KindType? {
|
|
return dictionary.expressionKind
|
|
}
|
|
}
|
|
|
|
public extension ASTRule where KindType == StatementKind {
|
|
func kind(from dictionary: SourceKittenDictionary) -> KindType? {
|
|
return dictionary.statementKind
|
|
}
|
|
}
|