// // FunctionBodyLengthRule.swift // SwiftLint // // Created by JP Simard on 2015-05-16. // Copyright (c) 2015 Realm. All rights reserved. // import SourceKittenFramework import SwiftXPC public struct FunctionBodyLengthRule: ASTRule, ParameterizedRule, ConfigurableRule { public init() { self.init(parameters: [ RuleParameter(severity: .Warning, value: 40), RuleParameter(severity: .Error, value: 100) ]) } public init(parameters: [RuleParameter]) { self.parameters = parameters } public let parameters: [RuleParameter] public static let description = RuleDescription( identifier: "function_body_length", name: "Function Body Length", description: "Functions bodies should not span too many lines." ) public func validateFile(file: File, kind: SwiftDeclarationKind, dictionary: XPCDictionary) -> [StyleViolation] { let functionKinds: [SwiftDeclarationKind] = [ .FunctionAccessorAddress, .FunctionAccessorDidset, .FunctionAccessorGetter, .FunctionAccessorMutableaddress, .FunctionAccessorSetter, .FunctionAccessorWillset, .FunctionConstructor, .FunctionDestructor, .FunctionFree, .FunctionMethodClass, .FunctionMethodInstance, .FunctionMethodStatic, .FunctionOperator, .FunctionSubscript ] if !functionKinds.contains(kind) { return [] } if let offset = (dictionary["key.offset"] as? Int64).flatMap({ Int($0) }), let bodyOffset = (dictionary["key.bodyoffset"] as? Int64).flatMap({ Int($0) }), let bodyLength = (dictionary["key.bodylength"] as? Int64).flatMap({ Int($0) }) { let location = Location(file: file, byteOffset: offset) let startLine = file.contents.lineAndCharacterForByteOffset(bodyOffset) let endLine = file.contents.lineAndCharacterForByteOffset(bodyOffset + bodyLength) for parameter in parameters.reverse() { if let startLine = startLine?.line, let endLine = endLine?.line where endLine - startLine > parameter.value { return [StyleViolation(ruleDescription: self.dynamicType.description, severity: parameter.severity, location: location, reason: "Function body should span \(parameters.first!.value) lines " + "or less: currently spans \(endLine - startLine) lines")] } } } return [] } }