56 lines
2.2 KiB
Swift
56 lines
2.2 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, returnng 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 dicttionary for an AST subset to validate.
|
|
func validate(file: SwiftLintFile, kind: KindType, dictionary: SourceKittenDictionary) -> [StyleViolation]
|
|
|
|
/// Get the `kind` from the specified dictionary.
|
|
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, returnng any violations to the rule's
|
|
/// expectations.
|
|
///
|
|
/// - parameter file: The file for which to execute the rule.
|
|
/// - parameter dictionary: The dicttionary for an AST subset to validate.
|
|
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
|
|
}
|
|
}
|