forked from realm/SwiftLint
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds closure_body_length opt-in rule
because closure bodies should not span too many lines. Implements realm#52.
- Loading branch information
1 parent
a71e792
commit aaf92cf
Showing
7 changed files
with
207 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
Source/SwiftLintFramework/Rules/ClosureBodyLengthRule.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// | ||
// ClosureBodyLengthRule.swift | ||
// SwiftLint | ||
// | ||
// Created by Ornithologist Coder on 8/3/17. | ||
// Copyright © 2017 Realm. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import SourceKittenFramework | ||
|
||
public struct ClosureBodyLengthRule: ASTRule, OptInRule, ConfigurationProviderRule { | ||
public var configuration = SeverityLevelsConfiguration(warning: 20, error: 100) | ||
|
||
public init() {} | ||
|
||
public static let description = RuleDescription( | ||
identifier: "closure_body_length", | ||
name: "Closure Body Length", | ||
description: "Closure bodies should not span too many lines.", | ||
kind: .metrics, | ||
nonTriggeringExamples: [ | ||
"foo.bar { $0 }", | ||
"foo.bar { value in\n" + repeatElement("\tprint(\"toto\")\n", count: 19).joined() + "\treturn value\n}", | ||
"foo.bar { value in\n\n" + repeatElement("\tprint(\"toto\")\n", count: 19).joined() + "\n\treturn value\n}" | ||
], | ||
triggeringExamples: [ | ||
"foo.bar {↓ value in\n" + repeatElement("\tprint(\"toto\")\n", count: 20).joined() + "\treturn value\n}", | ||
"foo.bar {↓ value in\n\n" + repeatElement("\tprint(\"toto\")\n", count: 20).joined() + "\n\treturn value\n}" | ||
] | ||
) | ||
|
||
public func validate(file: File, | ||
kind: SwiftExpressionKind, | ||
dictionary: [String: SourceKitRepresentable]) -> [StyleViolation] { | ||
guard | ||
kind == .call, | ||
let bodyOffset = dictionary.bodyOffset, | ||
let bodyLength = dictionary.bodyLength, | ||
case let contents = file.contents.bridge(), | ||
contents.substringWithByteRange(start: bodyOffset - 1, length: 1) == "{", | ||
let startLine = contents.lineAndCharacter(forByteOffset: bodyOffset)?.line, | ||
let endLine = contents.lineAndCharacter(forByteOffset: bodyOffset + bodyLength)?.line | ||
else { | ||
return [] | ||
} | ||
|
||
return configuration.params.flatMap { parameter in | ||
let (exceeds, lineCount) = file.exceedsLineCountExcludingCommentsAndWhitespace(startLine, | ||
endLine, | ||
parameter.value) | ||
guard exceeds else { return nil } | ||
|
||
return StyleViolation(ruleDescription: type(of: self).description, | ||
severity: parameter.severity, | ||
location: Location(file: file, byteOffset: bodyOffset), | ||
reason: "Closure body should span \(configuration.warning) lines or less " + | ||
"excluding comments and whitespace: currently spans \(lineCount) " + "lines") | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters