fix XCTestRule

This commit is contained in:
Roy Cao 2019-12-21 15:19:22 +08:00
parent 88b9011d45
commit bf4f13abcd
7 changed files with 54 additions and 42 deletions

View File

@ -8,7 +8,7 @@ struct AttributesRule: SourceCollectRule {
case ibaction = "IBAction"
}
func skip(_ node: Syntax) -> Bool {
func skip(_ node: Syntax, location: SourceLocation) -> Bool {
if let funcDecl = node as? FunctionDeclSyntax {
return skip(funcDecl)
}

View File

@ -12,7 +12,7 @@ struct CommentRule: SourceCollectRule {
static let all = "pecker:ignore all"
}
func skip(_ node: Syntax) -> Bool {
func skip(_ node: Syntax, location: SourceLocation) -> Bool {
guard let node = node as? ModifierSyntax else { return true }
let comments = node.leadingTrivia?.compactMap({ $0.comment }) ?? []
if comments.contains(where: { $0.contains(Comment.signal) }) || comments.contains(where: { $0.contains(Comment.all) }) {
@ -25,26 +25,26 @@ struct CommentRule: SourceCollectRule {
}
}
if let classDel: StructDeclSyntax = node.searchParent() {
if containAllSkip(classDel) {
if let structDel: StructDeclSyntax = node.searchParent() {
if containAllSkip(structDel) {
return true
}
}
if let classDel: EnumDeclSyntax = node.searchParent() {
if containAllSkip(classDel) {
if let enumDel: EnumDeclSyntax = node.searchParent() {
if containAllSkip(enumDel) {
return true
}
}
if let classDel: ProtocolDeclSyntax = node.searchParent() {
if containAllSkip(classDel) {
if let protocolDel: ProtocolDeclSyntax = node.searchParent() {
if containAllSkip(protocolDel) {
return true
}
}
if let classDel: ExtensionDeclSyntax = node.searchParent() {
if containAllSkip(classDel) {
if let extensionDel: ExtensionDeclSyntax = node.searchParent() {
if containAllSkip(extensionDel) {
return true
}
}

View File

@ -6,7 +6,7 @@ public protocol Rule {}
public protocol SourceCollectRule: Rule {
func skip(_ node: Syntax) -> Bool
func skip(_ node: Syntax, location: SourceLocation) -> Bool
}
public protocol AnalyzeRule: Rule {

View File

@ -4,7 +4,7 @@ import SwiftSyntax
/// Skip public syntax
struct SkipPublicRule: SourceCollectRule {
func skip(_ node: Syntax) -> Bool {
func skip(_ node: Syntax, location: SourceLocation) -> Bool {
if let modifierSyntax = node as? ModifierSyntax {
return modifierSyntax.isPublic()
}

View File

@ -7,7 +7,7 @@ struct SuperClassRule: SourceCollectRule {
var blacklist: Set<String> = ["NotificationService",
"PreviewProvider"]
func skip(_ node: Syntax) -> Bool {
func skip(_ node: Syntax, location: SourceLocation) -> Bool {
if let node = node as? InheritableSyntax {
if blacklist.contains(where: node.isInherited(from:)) {
return true

View File

@ -4,32 +4,44 @@ import SwiftSyntax
/// The rules for UITest and UnitTests
struct XCTestRule: SourceCollectRule {
func skip(_ node: Syntax) -> Bool {
func skip(_ node: Syntax, location: SourceLocation) -> Bool {
if let clsDecl = node as? ClassDeclSyntax {
return skip(clsDecl)
return skip(clsDecl, location: location)
}
if let funcDecl = node as? FunctionDeclSyntax {
return skip(funcDecl)
return skip(funcDecl, location: location)
}
return false
}
/// If a class is Inherited from XCTestCase, skip it
/// - Parameter node: ClassDeclSyntax
func skip(_ node: ClassDeclSyntax) -> Bool {
return isInheritedFromXCTestCase(node)
func skip(_ node: ClassDeclSyntax, location: SourceLocation) -> Bool {
return isInheritedFromXCTestCase(node) || fuzzyRule(location: location)
}
/// If a UITest funciton hasPrefix "test" and has parameters, skip it
/// - Parameter node: FunctionDeclSyntax
func skip(_ node: FunctionDeclSyntax) -> Bool {
func skip(_ node: FunctionDeclSyntax, location: SourceLocation) -> Bool {
if let classDecl: ClassDeclSyntax = node.searchParent(), isInheritedFromXCTestCase(classDecl) {
if node.identifier.text.hasPrefix("test") && node.signature.input.parameterList.count == 0 {
return true
}
}
// Fuzzy recognition
if fuzzyRule(location: location) {
if node.identifier.text.hasPrefix("test") && node.signature.input.parameterList.count == 0 {
return true
}
}
return false
}
private func fuzzyRule(location: SourceLocation) -> Bool {
let array = location.description.components(separatedBy: "/")
return array.contains(where: { $0.hasSuffix("Tests") })
}
}
private func isInheritedFromXCTestCase(_ node: ClassDeclSyntax) -> Bool {

View File

@ -14,74 +14,74 @@ class SwiftSourceCollectPipeline: SyntaxVisitor {
}
func visit(_ node: ClassDeclSyntax) -> SyntaxVisitorContinueKind {
if skip(syntax: node) {
if let position = findLocaiton(syntax: node.identifier) {
if skip(syntax: node, location: position) {
return .visitChildren
}
if let position = findLocaiton(syntax: node.identifier) {
collect(SourceDetail(name: node.identifier.text, sourceKind: .class, location: position))
}
return .visitChildren
}
func visit(_ node: StructDeclSyntax) -> SyntaxVisitorContinueKind {
if skip(syntax: node) {
if let position = findLocaiton(syntax: node.identifier) {
if skip(syntax: node, location: position) {
return .visitChildren
}
if let position = findLocaiton(syntax: node.identifier) {
collect(SourceDetail(name: node.identifier.text, sourceKind: .struct, location: position))
}
return .visitChildren
}
func visit(_ node: FunctionDeclSyntax) -> SyntaxVisitorContinueKind {
if skip(syntax: node) {
return .visitChildren
}
let ps = node.signature.input.parameterList.compactMap {
$0.firstName?.text
}
let function = Function(name: node.identifier.text, parameters: ps)
if let position = findLocaiton(syntax: node.identifier) {
if skip(syntax: node, location: position) {
return .visitChildren
}
collect(SourceDetail(name: function.description, sourceKind: .function, location: position))
}
return .visitChildren
}
func visit(_ node: EnumDeclSyntax) -> SyntaxVisitorContinueKind {
if skip(syntax: node) {
if let position = findLocaiton(syntax: node.identifier) {
if skip(syntax: node, location: position) {
return .visitChildren
}
if let position = findLocaiton(syntax: node.identifier) {
collect(SourceDetail(name: node.identifier.text, sourceKind: .enum, location: position))
}
return .visitChildren
}
func visit(_ node: ProtocolDeclSyntax) -> SyntaxVisitorContinueKind {
if skip(syntax: node) {
if let position = findLocaiton(syntax: node.identifier) {
if skip(syntax: node, location: position) {
return .visitChildren
}
if let position = findLocaiton(syntax: node.identifier) {
collect(SourceDetail(name: node.identifier.text, sourceKind: .protocol, location: position))
}
return .visitChildren
}
func visit(_ node: TypealiasDeclSyntax) -> SyntaxVisitorContinueKind {
if skip(syntax: node) {
if let position = findLocaiton(syntax: node.identifier) {
if skip(syntax: node, location: position) {
return .visitChildren
}
if let position = findLocaiton(syntax: node.identifier) {
collect(SourceDetail(name: node.identifier.text, sourceKind: .typealias, location: position))
}
return .visitChildren
}
func visit(_ node: OperatorDeclSyntax) -> SyntaxVisitorContinueKind {
if skip(syntax: node) {
if let position = findLocaiton(syntax: node.identifier) {
if skip(syntax: node, location: position) {
return .visitChildren
}
if let position = findLocaiton(syntax: node.identifier) {
collect(SourceDetail(name: node.identifier.text, sourceKind: .operator, location: position))
}
return .visitChildren
@ -100,13 +100,13 @@ class SwiftSourceCollectPipeline: SyntaxVisitor {
extension SwiftSourceCollectPipeline {
func skip(syntax: IdentifierSyntax) -> Bool {
func skip(syntax: IdentifierSyntax, location: SourceLocation) -> Bool {
// Skip the symbol in blacklist
if context.configuration.blacklistSymbols.contains(syntax.identifier.text) {
return true
}
// Rules check
if rules.contains(where: { $0.skip(syntax) }) {
if rules.contains(where: { $0.skip(syntax, location: location) }) {
return true
}
return false