diff --git a/.jazzy.yaml b/.jazzy.yaml index c096dabcc..5d062f35e 100644 --- a/.jazzy.yaml +++ b/.jazzy.yaml @@ -13,6 +13,8 @@ documentation: rule_docs/*.md hide_unlisted_documentation: true custom_categories_unlisted_prefix: '' exclude: + # TODO: Document extensions + - Source/SwiftLintFramework/Extensions/*.swift - Source/SwiftLintFramework/Rules/**/*.swift custom_categories: - name: Rules diff --git a/Source/SwiftLintFramework/Extensions/Array+SwiftLint.swift b/Source/SwiftLintFramework/Extensions/Array+SwiftLint.swift index 64ed8dae3..9cb038d9b 100644 --- a/Source/SwiftLintFramework/Extensions/Array+SwiftLint.swift +++ b/Source/SwiftLintFramework/Extensions/Array+SwiftLint.swift @@ -1,6 +1,6 @@ import Dispatch -extension Array where Element: Equatable { +public extension Array where Element: Equatable { /// The elements in this array, discarding duplicates after the first one. /// Order-preserving. var unique: [Element] { @@ -12,7 +12,7 @@ extension Array where Element: Equatable { } } -extension Array where Element: Hashable { +public extension Array where Element: Hashable { /// Produces an array containing the passed `obj` value. /// If `obj` is an array already, return it. /// If `obj` is a set, copy its elements to a new array. @@ -33,7 +33,7 @@ extension Array where Element: Hashable { } } -extension Array { +public extension Array { /// Produces an array containing the passed `obj` value. /// If `obj` is an array already, return it. /// If `obj` is a value of type `Element`, return a single-item array containing it. @@ -67,8 +67,7 @@ extension Array { /// /// - returns: The elements failing the `belongsInSecondPartition` test, followed by the elements passing the /// `belongsInSecondPartition` test. - @_spi(TestHelper) - public func partitioned(by belongsInSecondPartition: (Element) throws -> Bool) rethrows -> + func partitioned(by belongsInSecondPartition: (Element) throws -> Bool) rethrows -> (first: ArraySlice, second: ArraySlice) { var copy = self let pivot = try copy.partition(by: belongsInSecondPartition) @@ -80,8 +79,7 @@ extension Array { /// - parameter transform: The transformation to apply to each element. /// /// - returns: The result of applying `transform` on every element and flattening the results. - @_spi(TestHelper) - public func parallelFlatMap(transform: (Element) -> [T]) -> [T] { + func parallelFlatMap(transform: (Element) -> [T]) -> [T] { return parallelMap(transform: transform).flatMap { $0 } } @@ -110,10 +108,9 @@ extension Array { } } -extension Collection { +public extension Collection { /// Whether this collection has one or more element. - @_spi(TestHelper) - public var isNotEmpty: Bool { + var isNotEmpty: Bool { return !isEmpty } diff --git a/Source/SwiftLintFramework/Extensions/ByteCount+SwiftSyntax.swift b/Source/SwiftLintFramework/Extensions/ByteCount+SwiftSyntax.swift index 0b7d950d7..d027c5a2b 100644 --- a/Source/SwiftLintFramework/Extensions/ByteCount+SwiftSyntax.swift +++ b/Source/SwiftLintFramework/Extensions/ByteCount+SwiftSyntax.swift @@ -1,7 +1,7 @@ import SourceKittenFramework import SwiftSyntax -extension ByteCount { +public extension ByteCount { /// Converts a SwiftSyntax `AbsolutePosition` to a SourceKitten `ByteCount`. /// /// - parameter position: The SwiftSyntax position to convert. diff --git a/Source/SwiftLintFramework/Extensions/Dictionary+SwiftLint.swift b/Source/SwiftLintFramework/Extensions/Dictionary+SwiftLint.swift index e753e7335..dad6606e6 100644 --- a/Source/SwiftLintFramework/Extensions/Dictionary+SwiftLint.swift +++ b/Source/SwiftLintFramework/Extensions/Dictionary+SwiftLint.swift @@ -21,7 +21,7 @@ public struct SourceKittenDictionary { /// Creates a SourceKitten dictionary given a `Dictionary` input. /// /// - parameter value: The input dictionary/ - init(_ value: [String: SourceKitRepresentable]) { + public init(_ value: [String: SourceKitRepresentable]) { self.value = value let substructure = value["key.substructure"] as? [SourceKitRepresentable] ?? [] @@ -37,123 +37,123 @@ public struct SourceKittenDictionary { } /// Body length - var bodyLength: ByteCount? { + public var bodyLength: ByteCount? { return (value["key.bodylength"] as? Int64).map(ByteCount.init) } /// Body offset. - var bodyOffset: ByteCount? { + public var bodyOffset: ByteCount? { return (value["key.bodyoffset"] as? Int64).map(ByteCount.init) } /// Body byte range. - var bodyByteRange: ByteRange? { + public var bodyByteRange: ByteRange? { guard let offset = bodyOffset, let length = bodyLength else { return nil } return ByteRange(location: offset, length: length) } /// Kind. - var kind: String? { + public var kind: String? { return value["key.kind"] as? String } /// Length. - var length: ByteCount? { + public var length: ByteCount? { return (value["key.length"] as? Int64).map(ByteCount.init) } /// Name. - var name: String? { + public var name: String? { return value["key.name"] as? String } /// Name length. - var nameLength: ByteCount? { + public var nameLength: ByteCount? { return (value["key.namelength"] as? Int64).map(ByteCount.init) } /// Name offset. - var nameOffset: ByteCount? { + public var nameOffset: ByteCount? { return (value["key.nameoffset"] as? Int64).map(ByteCount.init) } /// Byte range of name. - var nameByteRange: ByteRange? { + public var nameByteRange: ByteRange? { guard let offset = nameOffset, let length = nameLength else { return nil } return ByteRange(location: offset, length: length) } /// Offset. - var offset: ByteCount? { + public var offset: ByteCount? { return (value["key.offset"] as? Int64).map(ByteCount.init) } /// Returns byte range starting from `offset` with `length` bytes - var byteRange: ByteRange? { + public var byteRange: ByteRange? { guard let offset, let length else { return nil } return ByteRange(location: offset, length: length) } /// Setter accessibility. - var setterAccessibility: String? { + public var setterAccessibility: String? { return value["key.setter_accessibility"] as? String } /// Type name. - var typeName: String? { + public var typeName: String? { return value["key.typename"] as? String } /// Documentation length. - var docLength: ByteCount? { + public var docLength: ByteCount? { return (value["key.doclength"] as? Int64).flatMap(ByteCount.init) } /// The attribute for this dictionary, as returned by SourceKit. - var attribute: String? { + public var attribute: String? { return value["key.attribute"] as? String } /// Module name in `@import` expressions. - var moduleName: String? { + public var moduleName: String? { return value["key.modulename"] as? String } /// The line number for this declaration. - var line: Int64? { + public var line: Int64? { return value["key.line"] as? Int64 } /// The column number for this declaration. - var column: Int64? { + public var column: Int64? { return value["key.column"] as? Int64 } /// The `SwiftDeclarationAttributeKind` values associated with this dictionary. - var enclosedSwiftAttributes: [SwiftDeclarationAttributeKind] { + public var enclosedSwiftAttributes: [SwiftDeclarationAttributeKind] { return swiftAttributes.compactMap { $0.attribute } .compactMap(SwiftDeclarationAttributeKind.init(rawValue:)) } /// The fully preserved SourceKitten dictionaries for all the attributes associated with this dictionary. - var swiftAttributes: [SourceKittenDictionary] { + public var swiftAttributes: [SourceKittenDictionary] { let array = value["key.attributes"] as? [SourceKitRepresentable] ?? [] return array.compactMap { $0 as? [String: SourceKitRepresentable] } .map(Self.init) } - var elements: [SourceKittenDictionary] { + public var elements: [SourceKittenDictionary] { let elements = value["key.elements"] as? [SourceKitRepresentable] ?? [] return elements.compactMap { $0 as? [String: SourceKitRepresentable] } .map(Self.init) } - var entities: [SourceKittenDictionary] { + public var entities: [SourceKittenDictionary] { let entities = value["key.entities"] as? [SourceKitRepresentable] ?? [] return entities.compactMap { $0 as? [String: SourceKitRepresentable] } .map(Self.init) } - var enclosedVarParameters: [SourceKittenDictionary] { + public var enclosedVarParameters: [SourceKittenDictionary] { return substructure.flatMap { subDict -> [SourceKittenDictionary] in if subDict.declarationKind == .varParameter { return [subDict] @@ -166,7 +166,7 @@ public struct SourceKittenDictionary { } } - var enclosedArguments: [SourceKittenDictionary] { + public var enclosedArguments: [SourceKittenDictionary] { return substructure.flatMap { subDict -> [SourceKittenDictionary] in guard subDict.expressionKind == .argument else { return [] @@ -176,7 +176,7 @@ public struct SourceKittenDictionary { } } - var inheritedTypes: [String] { + public var inheritedTypes: [String] { let array = value["key.inheritedtypes"] as? [SourceKitRepresentable] ?? [] return array.compactMap { ($0 as? [String: String]).flatMap { $0["key.name"] } } } @@ -189,7 +189,7 @@ extension SourceKittenDictionary { /// - parameter traverseBlock: block that will be called for each substructure in the dictionary. /// /// - returns: The list of substructure dictionaries with updated values from the traverse block. - func traverseDepthFirst(traverseBlock: (SourceKittenDictionary) -> [T]?) -> [T] { + public func traverseDepthFirst(traverseBlock: (SourceKittenDictionary) -> [T]?) -> [T] { var result: [T] = [] traverseDepthFirst(collectingValuesInto: &result, traverseBlock: traverseBlock) return result @@ -212,7 +212,7 @@ extension SourceKittenDictionary { /// - parameter traverseBlock: block that will be called for each entity in the dictionary. /// /// - returns: The list of entity dictionaries with updated values from the traverse block. - func traverseEntitiesDepthFirst(traverseBlock: (SourceKittenDictionary) -> T?) -> [T] { + public func traverseEntitiesDepthFirst(traverseBlock: (SourceKittenDictionary) -> T?) -> [T] { var result: [T] = [] traverseEntitiesDepthFirst(collectingValuesInto: &result, traverseBlock: traverseBlock) return result @@ -230,7 +230,7 @@ extension SourceKittenDictionary { } } -extension Dictionary where Key == Example { +public extension Dictionary where Key == Example { /// Returns a dictionary with SwiftLint violation markers (↓) removed from keys. /// /// - returns: A new `Dictionary`. diff --git a/Source/SwiftLintFramework/Extensions/NSRegularExpression+SwiftLint.swift b/Source/SwiftLintFramework/Extensions/NSRegularExpression+SwiftLint.swift index 4fb73efb8..14a833038 100644 --- a/Source/SwiftLintFramework/Extensions/NSRegularExpression+SwiftLint.swift +++ b/Source/SwiftLintFramework/Extensions/NSRegularExpression+SwiftLint.swift @@ -14,8 +14,8 @@ private struct RegexCacheKey: Hashable { } } -extension NSRegularExpression { - internal static func cached(pattern: String, options: Options? = nil) throws -> NSRegularExpression { +public extension NSRegularExpression { + static func cached(pattern: String, options: Options? = nil) throws -> NSRegularExpression { let options = options ?? [.anchorsMatchLines, .dotMatchesLineSeparators] let key = RegexCacheKey(pattern: pattern, options: options) regexCacheLock.lock() @@ -29,19 +29,19 @@ extension NSRegularExpression { return result } - internal func matches(in stringView: StringView, - options: NSRegularExpression.MatchingOptions = []) -> [NSTextCheckingResult] { + func matches(in stringView: StringView, + options: NSRegularExpression.MatchingOptions = []) -> [NSTextCheckingResult] { return matches(in: stringView.string, options: options, range: stringView.range) } - internal func matches(in stringView: StringView, - options: NSRegularExpression.MatchingOptions = [], - range: NSRange) -> [NSTextCheckingResult] { + func matches(in stringView: StringView, + options: NSRegularExpression.MatchingOptions = [], + range: NSRange) -> [NSTextCheckingResult] { return matches(in: stringView.string, options: options, range: range) } - internal func matches(in file: SwiftLintFile, - options: NSRegularExpression.MatchingOptions = []) -> [NSTextCheckingResult] { + func matches(in file: SwiftLintFile, + options: NSRegularExpression.MatchingOptions = []) -> [NSTextCheckingResult] { return matches(in: file.stringView.string, options: options, range: file.stringView.range) } } diff --git a/Source/SwiftLintFramework/Extensions/RandomAccessCollection+Swiftlint.swift b/Source/SwiftLintFramework/Extensions/RandomAccessCollection+Swiftlint.swift index 7e7126771..1678cb8f3 100644 --- a/Source/SwiftLintFramework/Extensions/RandomAccessCollection+Swiftlint.swift +++ b/Source/SwiftLintFramework/Extensions/RandomAccessCollection+Swiftlint.swift @@ -1,4 +1,4 @@ -extension RandomAccessCollection where Index == Int { +public extension RandomAccessCollection where Index == Int { /// Returns the first index in which an element of the collection satisfies the given predicate. /// The collection assumed to be sorted. If collection is not have sorted values the result is undefined. /// diff --git a/Source/SwiftLintFramework/Extensions/Request+SwiftLint.swift b/Source/SwiftLintFramework/Extensions/Request+SwiftLint.swift index 7f0e9e6ed..1ecf370f7 100644 --- a/Source/SwiftLintFramework/Extensions/Request+SwiftLint.swift +++ b/Source/SwiftLintFramework/Extensions/Request+SwiftLint.swift @@ -1,7 +1,7 @@ import Foundation import SourceKittenFramework -extension Request { +public extension Request { static let disableSourceKit = ProcessInfo.processInfo.environment["SWIFTLINT_DISABLE_SOURCEKIT"] != nil func sendIfNotDisabled() throws -> [String: SourceKitRepresentable] { diff --git a/Source/SwiftLintFramework/Extensions/SourceKittenDictionary+Swiftlint.swift b/Source/SwiftLintFramework/Extensions/SourceKittenDictionary+Swiftlint.swift index c430ad277..dff42f5f2 100644 --- a/Source/SwiftLintFramework/Extensions/SourceKittenDictionary+Swiftlint.swift +++ b/Source/SwiftLintFramework/Extensions/SourceKittenDictionary+Swiftlint.swift @@ -1,13 +1,13 @@ import SourceKittenFramework -extension SourceKittenDictionary { +public extension SourceKittenDictionary { /// Returns array of tuples containing "key.kind" and "byteRange" from Structure /// that contains the byte offset. Returns all kinds if no parameter specified. /// /// - parameter byteOffset: Int? /// /// - returns: The kinds and byte ranges. - internal func kinds(forByteOffset byteOffset: ByteCount? = nil) + func kinds(forByteOffset byteOffset: ByteCount? = nil) -> [(kind: String, byteRange: ByteRange)] { var results = [(kind: String, byteRange: ByteRange)]() @@ -27,7 +27,7 @@ extension SourceKittenDictionary { return results } - internal func structures(forByteOffset byteOffset: ByteCount) -> [SourceKittenDictionary] { + func structures(forByteOffset byteOffset: ByteCount) -> [SourceKittenDictionary] { var results = [SourceKittenDictionary]() func parse(_ dictionary: SourceKittenDictionary) { diff --git a/Source/SwiftLintFramework/Extensions/SourceRange+SwiftLint.swift b/Source/SwiftLintFramework/Extensions/SourceRange+SwiftLint.swift index 6e07af717..5c099e82d 100644 --- a/Source/SwiftLintFramework/Extensions/SourceRange+SwiftLint.swift +++ b/Source/SwiftLintFramework/Extensions/SourceRange+SwiftLint.swift @@ -1,6 +1,6 @@ import SwiftSyntax -extension SourceRange { +public extension SourceRange { /// Check if a position is contained within this range. /// /// - parameter position: The position to check. diff --git a/Source/SwiftLintFramework/Extensions/String+SwiftLint.swift b/Source/SwiftLintFramework/Extensions/String+SwiftLint.swift index 038798e01..be6ac71ab 100644 --- a/Source/SwiftLintFramework/Extensions/String+SwiftLint.swift +++ b/Source/SwiftLintFramework/Extensions/String+SwiftLint.swift @@ -1,8 +1,8 @@ import Foundation import SourceKittenFramework -extension String { - internal func hasTrailingWhitespace() -> Bool { +public extension String { + func hasTrailingWhitespace() -> Bool { if isEmpty { return false } @@ -14,22 +14,14 @@ extension String { return false } - internal func isUppercase() -> Bool { + func isUppercase() -> Bool { return self == uppercased() } - internal func isLowercase() -> Bool { + func isLowercase() -> Bool { return self == lowercased() } - internal func nameStrippingLeadingUnderscoreIfPrivate(_ dict: SourceKittenDictionary) -> String { - if let acl = dict.accessibility, - acl.isPrivate && first == "_" { - return String(self[index(after: startIndex)...]) - } - return self - } - private subscript (range: Range) -> String { let nsrange = NSRange(location: range.lowerBound, length: range.upperBound - range.lowerBound) @@ -39,21 +31,21 @@ extension String { queuedFatalError("invalid range") } - internal func substring(from: Int, length: Int? = nil) -> String { + func substring(from: Int, length: Int? = nil) -> String { if let length { return self[from.. Int? { + func lastIndex(of search: String) -> Int? { if let range = range(of: search, options: [.literal, .backwards]) { return distance(from: startIndex, to: range.lowerBound) } return nil } - internal func nsrangeToIndexRange(_ nsrange: NSRange) -> Range? { + func nsrangeToIndexRange(_ nsrange: NSRange) -> Range? { guard nsrange.location != NSNotFound else { return nil } @@ -70,18 +62,18 @@ extension String { return fromIndex.. String { + func absolutePathStandardized() -> String { return bridge().absolutePathRepresentation().bridge().standardizingPath } - internal var isFile: Bool { + var isFile: Bool { if self.isEmpty { return false } @@ -95,14 +87,14 @@ extension String { /// Count the number of occurrences of the given character in `self` /// - Parameter character: Character to count /// - Returns: Number of times `character` occurs in `self` - public func countOccurrences(of character: Character) -> Int { + func countOccurrences(of character: Character) -> Int { return self.reduce(0, { $1 == character ? $0 + 1 : $0 }) } /// If self is a path, this method can be used to get a path expression relative to a root directory - public func path(relativeTo rootDirectory: String) -> String { + func path(relativeTo rootDirectory: String) -> String { let normalizedRootDir = rootDirectory.bridge().standardizingPath let normalizedSelf = bridge().standardizingPath if normalizedRootDir.isEmpty { @@ -123,7 +115,7 @@ extension String { } } - internal func deletingPrefix(_ prefix: String) -> String { + func deletingPrefix(_ prefix: String) -> String { guard hasPrefix(prefix) else { return self } return String(dropFirst(prefix.count)) } diff --git a/Source/SwiftLintFramework/Extensions/StringView+SwiftLint.swift b/Source/SwiftLintFramework/Extensions/StringView+SwiftLint.swift index 46d6d5272..bf1ded721 100644 --- a/Source/SwiftLintFramework/Extensions/StringView+SwiftLint.swift +++ b/Source/SwiftLintFramework/Extensions/StringView+SwiftLint.swift @@ -1,6 +1,6 @@ import SourceKittenFramework -extension StringView { +public extension StringView { /// Converts a line and column position in a code snippet to a byte offset. /// - Parameters: /// - line: Line in code snippet diff --git a/Source/SwiftLintFramework/Extensions/StringView+SwiftSyntax.swift b/Source/SwiftLintFramework/Extensions/StringView+SwiftSyntax.swift index d869ec068..efee3d87d 100644 --- a/Source/SwiftLintFramework/Extensions/StringView+SwiftSyntax.swift +++ b/Source/SwiftLintFramework/Extensions/StringView+SwiftSyntax.swift @@ -2,7 +2,7 @@ import Foundation import SourceKittenFramework import SwiftSyntax -extension StringView { +public extension StringView { /// Converts two absolute positions from SwiftSyntax to a valid `NSRange` if possible. /// /// - parameter start: Starting position. diff --git a/Source/SwiftLintFramework/Extensions/SwiftDeclarationAttributeKind+Swiftlint.swift b/Source/SwiftLintFramework/Extensions/SwiftDeclarationAttributeKind+Swiftlint.swift index 3571092e4..ace97f9a2 100644 --- a/Source/SwiftLintFramework/Extensions/SwiftDeclarationAttributeKind+Swiftlint.swift +++ b/Source/SwiftLintFramework/Extensions/SwiftDeclarationAttributeKind+Swiftlint.swift @@ -1,6 +1,6 @@ import SourceKittenFramework -extension SwiftDeclarationAttributeKind { +public extension SwiftDeclarationAttributeKind { static var attributesRequiringFoundation: Set { return [ .objc, @@ -24,7 +24,7 @@ extension SwiftDeclarationAttributeKind { case `dynamic` case atPrefixed - init?(rawAttribute: String) { + public init?(rawAttribute: String) { let allModifierGroups: Set = [ .acl, .setterACL, .mutators, .override, .owned, .atPrefixed, .dynamic, .final, .typeMethods, .required, .convenience, .lazy @@ -40,7 +40,7 @@ extension SwiftDeclarationAttributeKind { } } - var swiftDeclarationAttributeKinds: Set { + public var swiftDeclarationAttributeKinds: Set { switch self { case .acl: return [ @@ -94,7 +94,7 @@ extension SwiftDeclarationAttributeKind { } } - var debugDescription: String { + public var debugDescription: String { return self.rawValue } } diff --git a/Source/SwiftLintFramework/Extensions/SwiftDeclarationKind+SwiftLint.swift b/Source/SwiftLintFramework/Extensions/SwiftDeclarationKind+SwiftLint.swift index 892368069..8bf1ae85c 100644 --- a/Source/SwiftLintFramework/Extensions/SwiftDeclarationKind+SwiftLint.swift +++ b/Source/SwiftLintFramework/Extensions/SwiftDeclarationKind+SwiftLint.swift @@ -1,7 +1,7 @@ import SourceKittenFramework -extension SwiftDeclarationKind { - internal static let variableKinds: Set = [ +public extension SwiftDeclarationKind { + static let variableKinds: Set = [ .varClass, .varGlobal, .varInstance, @@ -10,7 +10,7 @@ extension SwiftDeclarationKind { .varStatic ] - internal static let functionKinds: Set = [ + static let functionKinds: Set = [ .functionAccessorAddress, .functionAccessorDidset, .functionAccessorGetter, @@ -27,7 +27,7 @@ extension SwiftDeclarationKind { .functionSubscript ] - internal static let typeKinds: Set = [ + static let typeKinds: Set = [ .class, .struct, .typealias, @@ -35,7 +35,7 @@ extension SwiftDeclarationKind { .enum ] - internal static let extensionKinds: Set = [ + static let extensionKinds: Set = [ .extension, .extensionClass, .extensionEnum, diff --git a/Source/SwiftLintFramework/Extensions/SwiftLintFile+BodyLineCount.swift b/Source/SwiftLintFramework/Extensions/SwiftLintFile+BodyLineCount.swift index 9c90827bf..dc9af042a 100644 --- a/Source/SwiftLintFramework/Extensions/SwiftLintFile+BodyLineCount.swift +++ b/Source/SwiftLintFramework/Extensions/SwiftLintFile+BodyLineCount.swift @@ -1,6 +1,6 @@ import SwiftSyntax -extension SwiftLintFile { +public extension SwiftLintFile { /// This function determines if given a scope with a left/right brace, such as a function, closure, type, etc, how /// many lines the "body" spans when you ignore lines only containing comments and/or whitespace. /// diff --git a/Source/SwiftLintFramework/Extensions/SwiftLintFile+Cache.swift b/Source/SwiftLintFramework/Extensions/SwiftLintFile+Cache.swift index 4c7ef4818..256a19753 100644 --- a/Source/SwiftLintFramework/Extensions/SwiftLintFile+Cache.swift +++ b/Source/SwiftLintFramework/Extensions/SwiftLintFile+Cache.swift @@ -101,7 +101,7 @@ extension SwiftLintFile { return id } - internal var sourcekitdFailed: Bool { + public var sourcekitdFailed: Bool { get { return responseCache.get(self) == nil } @@ -123,7 +123,7 @@ extension SwiftLintFile { } } - internal var parserDiagnostics: [String]? { + public var parserDiagnostics: [String]? { if parserDiagnosticsDisabledForTests { return nil } @@ -133,9 +133,9 @@ extension SwiftLintFile { .map(\.message) } - internal var linesWithTokens: Set { linesWithTokensCache.get(self) } + public var linesWithTokens: Set { linesWithTokensCache.get(self) } - internal var structureDictionary: SourceKittenDictionary { + public var structureDictionary: SourceKittenDictionary { guard let structureDictionary = structureDictionaryCache.get(self) else { if let handler = assertHandler { handler() @@ -146,9 +146,9 @@ extension SwiftLintFile { return structureDictionary } - internal var syntaxClassifications: SyntaxClassifications { syntaxClassificationsCache.get(self) } + public var syntaxClassifications: SyntaxClassifications { syntaxClassificationsCache.get(self) } - internal var syntaxMap: SwiftLintSyntaxMap { + public var syntaxMap: SwiftLintSyntaxMap { guard let syntaxMap = syntaxMapCache.get(self) else { if let handler = assertHandler { handler() @@ -159,16 +159,17 @@ extension SwiftLintFile { return syntaxMap } - internal var syntaxTree: SourceFileSyntax { syntaxTreeCache.get(self) } + public var syntaxTree: SourceFileSyntax { syntaxTreeCache.get(self) } - internal var foldedSyntaxTree: SourceFileSyntax? { foldedSyntaxTreeCache.get(self) } + public var foldedSyntaxTree: SourceFileSyntax? { foldedSyntaxTreeCache.get(self) } - internal var locationConverter: SourceLocationConverter { locationConverterCache.get(self) } + public var locationConverter: SourceLocationConverter { locationConverterCache.get(self) } - internal var commands: [Command] { commandsCache.get(self).filter { $0.isValid } } - internal var invalidCommands: [Command] { commandsCache.get(self).filter { !$0.isValid } } + public var commands: [Command] { commandsCache.get(self).filter { $0.isValid } } - internal var syntaxTokensByLines: [[SwiftLintSyntaxToken]] { + public var invalidCommands: [Command] { commandsCache.get(self).filter { !$0.isValid } } + + public var syntaxTokensByLines: [[SwiftLintSyntaxToken]] { guard let syntaxTokensByLines = syntaxTokensByLinesCache.get(self) else { if let handler = assertHandler { handler() @@ -179,7 +180,7 @@ extension SwiftLintFile { return syntaxTokensByLines } - internal var syntaxKindsByLines: [[SourceKittenFramework.SyntaxKind]] { + public var syntaxKindsByLines: [[SourceKittenFramework.SyntaxKind]] { guard let syntaxKindsByLines = syntaxKindsByLinesCache.get(self) else { if let handler = assertHandler { handler() diff --git a/Source/SwiftLintFramework/Extensions/SwiftLintFile+Regex.swift b/Source/SwiftLintFramework/Extensions/SwiftLintFile+Regex.swift index b7747a55e..b99bd7e0d 100644 --- a/Source/SwiftLintFramework/Extensions/SwiftLintFile+Regex.swift +++ b/Source/SwiftLintFramework/Extensions/SwiftLintFile+Regex.swift @@ -1,8 +1,8 @@ import Foundation import SourceKittenFramework -internal func regex(_ pattern: String, - options: NSRegularExpression.Options? = nil) -> NSRegularExpression { +public func regex(_ pattern: String, + options: NSRegularExpression.Options? = nil) -> NSRegularExpression { // all patterns used for regular expressions in SwiftLint are string literals which have been // confirmed to work, so it's ok to force-try here. @@ -12,7 +12,7 @@ internal func regex(_ pattern: String, } extension SwiftLintFile { - internal func regions(restrictingRuleIdentifiers: Set? = nil) -> [Region] { + public func regions(restrictingRuleIdentifiers: Set? = nil) -> [Region] { var regions = [Region]() var disabledRules = Set() let commands: [Command] @@ -57,7 +57,7 @@ extension SwiftLintFile { return regions } - internal func commands(in range: NSRange? = nil) -> [Command] { + public func commands(in range: NSRange? = nil) -> [Command] { guard let range else { return commands .flatMap { $0.expand() } @@ -93,14 +93,14 @@ extension SwiftLintFile { return Location(file: path, line: nextLine, character: nextCharacter) } - internal func match(pattern: String, with syntaxKinds: [SyntaxKind], range: NSRange? = nil) -> [NSRange] { + public func match(pattern: String, with syntaxKinds: [SyntaxKind], range: NSRange? = nil) -> [NSRange] { return match(pattern: pattern, range: range) .filter { $0.1 == syntaxKinds } .map { $0.0 } } - internal func matchesAndTokens(matching pattern: String, - range: NSRange? = nil) -> [(NSTextCheckingResult, [SwiftLintSyntaxToken])] { + public func matchesAndTokens(matching pattern: String, + range: NSRange? = nil) -> [(NSTextCheckingResult, [SwiftLintSyntaxToken])] { let contents = stringView let range = range ?? contents.range let syntax = syntaxMap @@ -110,25 +110,25 @@ extension SwiftLintFile { } } - internal func matchesAndSyntaxKinds(matching pattern: String, - range: NSRange? = nil) -> [(NSTextCheckingResult, [SyntaxKind])] { + public func matchesAndSyntaxKinds(matching pattern: String, + range: NSRange? = nil) -> [(NSTextCheckingResult, [SyntaxKind])] { return matchesAndTokens(matching: pattern, range: range).map { textCheckingResult, tokens in (textCheckingResult, tokens.kinds) } } - internal func rangesAndTokens(matching pattern: String, - range: NSRange? = nil) -> [(NSRange, [SwiftLintSyntaxToken])] { + public func rangesAndTokens(matching pattern: String, + range: NSRange? = nil) -> [(NSRange, [SwiftLintSyntaxToken])] { return matchesAndTokens(matching: pattern, range: range).map { ($0.0.range, $0.1) } } - internal func match(pattern: String, range: NSRange? = nil, captureGroup: Int = 0) -> [(NSRange, [SyntaxKind])] { + public func match(pattern: String, range: NSRange? = nil, captureGroup: Int = 0) -> [(NSRange, [SyntaxKind])] { return matchesAndSyntaxKinds(matching: pattern, range: range).map { textCheckingResult, syntaxKinds in (textCheckingResult.range(at: captureGroup), syntaxKinds) } } - internal func swiftDeclarationKindsByLine() -> [[SwiftDeclarationKind]]? { + public func swiftDeclarationKindsByLine() -> [[SwiftDeclarationKind]]? { if sourcekitdFailed { return nil } @@ -151,7 +151,7 @@ extension SwiftLintFile { return results } - internal func syntaxTokensByLine() -> [[SwiftLintSyntaxToken]]? { + public func syntaxTokensByLine() -> [[SwiftLintSyntaxToken]]? { if sourcekitdFailed { return nil } @@ -180,7 +180,7 @@ extension SwiftLintFile { return results } - internal func syntaxKindsByLine() -> [[SyntaxKind]]? { + public func syntaxKindsByLine() -> [[SyntaxKind]]? { guard !sourcekitdFailed, let tokens = syntaxTokensByLine() else { return nil } @@ -199,22 +199,22 @@ extension SwiftLintFile { - returns: An array of [NSRange] objects consisting of regex matches inside file contents. */ - internal func match(pattern: String, - excludingSyntaxKinds syntaxKinds: Set, - range: NSRange? = nil, - captureGroup: Int = 0) -> [NSRange] { + public func match(pattern: String, + excludingSyntaxKinds syntaxKinds: Set, + range: NSRange? = nil, + captureGroup: Int = 0) -> [NSRange] { return match(pattern: pattern, range: range, captureGroup: captureGroup) .filter { syntaxKinds.isDisjoint(with: $0.1) } .map { $0.0 } } - internal typealias MatchMapping = (NSTextCheckingResult) -> NSRange + public typealias MatchMapping = (NSTextCheckingResult) -> NSRange - internal func match(pattern: String, - range: NSRange? = nil, - excludingSyntaxKinds: Set, - excludingPattern: String, - exclusionMapping: MatchMapping = { $0.range }) -> [NSRange] { + public func match(pattern: String, + range: NSRange? = nil, + excludingSyntaxKinds: Set, + excludingPattern: String, + exclusionMapping: MatchMapping = { $0.range }) -> [NSRange] { let matches = match(pattern: pattern, excludingSyntaxKinds: excludingSyntaxKinds) if matches.isEmpty { return [] @@ -225,7 +225,7 @@ extension SwiftLintFile { return matches.filter { !$0.intersects(exclusionRanges) } } - internal func append(_ string: String) { + public func append(_ string: String) { guard string.isNotEmpty else { return } @@ -245,7 +245,7 @@ extension SwiftLintFile { invalidateCache() } - internal func write(_ string: S) { + public func write(_ string: S) { guard string != contents else { return } @@ -267,7 +267,7 @@ extension SwiftLintFile { invalidateCache() } - internal func ruleEnabled(violatingRanges: [NSRange], for rule: Rule) -> [NSRange] { + public func ruleEnabled(violatingRanges: [NSRange], for rule: Rule) -> [NSRange] { let fileRegions = regions() if fileRegions.isEmpty { return violatingRanges } return violatingRanges.filter { range in @@ -278,11 +278,11 @@ extension SwiftLintFile { } } - internal func ruleEnabled(violatingRange: NSRange, for rule: Rule) -> NSRange? { + public func ruleEnabled(violatingRange: NSRange, for rule: Rule) -> NSRange? { return ruleEnabled(violatingRanges: [violatingRange], for: rule).first } - internal func isACL(token: SwiftLintSyntaxToken) -> Bool { + public func isACL(token: SwiftLintSyntaxToken) -> Bool { guard token.kind == .attributeBuiltin else { return false } @@ -291,7 +291,7 @@ extension SwiftLintFile { return aclString.flatMap(AccessControlLevel.init(description:)) != nil } - internal func contents(for token: SwiftLintSyntaxToken) -> String? { + public func contents(for token: SwiftLintSyntaxToken) -> String? { return stringView.substringWithByteRange(token.range) } } diff --git a/Source/SwiftLintFramework/Extensions/SwiftSyntax+SwiftLint.swift b/Source/SwiftLintFramework/Extensions/SwiftSyntax+SwiftLint.swift index a63ca77c3..fe591fc46 100644 --- a/Source/SwiftLintFramework/Extensions/SwiftSyntax+SwiftLint.swift +++ b/Source/SwiftLintFramework/Extensions/SwiftSyntax+SwiftLint.swift @@ -3,10 +3,10 @@ import SourceKittenFramework import SwiftSyntax // workaround for https://bugs.swift.org/browse/SR-10121 so we can use `Self` in a closure -protocol SwiftLintSyntaxVisitor: SyntaxVisitor {} +public protocol SwiftLintSyntaxVisitor: SyntaxVisitor {} extension SyntaxVisitor: SwiftLintSyntaxVisitor {} -extension SwiftLintSyntaxVisitor { +public extension SwiftLintSyntaxVisitor { func walk(tree: SyntaxType, handler: (Self) -> T) -> T { #if DEBUG // workaround for stack overflow when running in debug @@ -44,7 +44,7 @@ extension SwiftLintSyntaxVisitor { } } -extension SyntaxProtocol { +public extension SyntaxProtocol { func windowsOfThreeTokens() -> [(TokenSyntax, TokenSyntax, TokenSyntax)] { Array(tokens(viewMode: .sourceAccurate)) .windows(ofCount: 3) @@ -61,7 +61,7 @@ extension SyntaxProtocol { } } -extension AbsolutePosition { +public extension AbsolutePosition { func isContainedIn(regions: [SourceRange], locationConverter: SourceLocationConverter) -> Bool { regions.contains { region in region.contains(self, locationConverter: locationConverter) @@ -69,13 +69,13 @@ extension AbsolutePosition { } } -extension ByteSourceRange { +public extension ByteSourceRange { func toSourceKittenByteRange() -> ByteRange { ByteRange(location: ByteCount(offset), length: ByteCount(length)) } } -extension ClassDeclSyntax { +public extension ClassDeclSyntax { func isXCTestCase(_ testParentClasses: Set) -> Bool { guard let inheritanceList = inheritanceClause?.inheritedTypeCollection else { return false @@ -85,7 +85,7 @@ extension ClassDeclSyntax { } } -extension ExprSyntax { +public extension ExprSyntax { var asFunctionCall: FunctionCallExprSyntax? { if let functionCall = self.as(FunctionCallExprSyntax.self) { return functionCall @@ -99,19 +99,19 @@ extension ExprSyntax { } } -extension StringLiteralExprSyntax { +public extension StringLiteralExprSyntax { var isEmptyString: Bool { segments.onlyElement?.contentLength == .zero } } -extension TokenKind { +public extension TokenKind { var isEqualityComparison: Bool { self == .binaryOperator("==") || self == .binaryOperator("!=") } } -extension ModifierListSyntax? { +public extension ModifierListSyntax? { var containsLazy: Bool { contains(tokenKind: .keyword(.lazy)) } @@ -160,26 +160,26 @@ extension ModifierListSyntax? { } } -extension AttributeSyntax { +public extension AttributeSyntax { var attributeNameText: String { attributeName.as(SimpleTypeIdentifierSyntax.self)?.name.text ?? attributeName.description } } -extension AttributeListSyntax? { +public extension AttributeListSyntax? { func contains(attributeNamed attributeName: String) -> Bool { self?.contains { $0.as(AttributeSyntax.self)?.attributeNameText == attributeName } == true } } -extension TokenKind { +public extension TokenKind { var isUnavailableKeyword: Bool { self == .keyword(.unavailable) || self == .identifier("unavailable") } } -extension VariableDeclSyntax { +public extension VariableDeclSyntax { var isIBOutlet: Bool { attributes.contains(attributeNamed: "IBOutlet") } @@ -220,7 +220,7 @@ public extension EnumDeclSyntax { } } -extension FunctionDeclSyntax { +public extension FunctionDeclSyntax { var isIBAction: Bool { attributes.contains(attributeNamed: "IBAction") } @@ -251,7 +251,7 @@ extension FunctionDeclSyntax { } } -extension AccessorBlockSyntax { +public extension AccessorBlockSyntax { var getAccessor: AccessorDeclSyntax? { accessors.first { accessor in accessor.accessorKind.tokenKind == .keyword(.get) @@ -273,7 +273,7 @@ extension AccessorBlockSyntax { } } -extension TypeInheritanceClauseSyntax? { +public extension TypeInheritanceClauseSyntax? { func containsInheritedType(inheritedTypes: Set) -> Bool { self?.inheritedTypeCollection.contains { elem in guard let simpleType = elem.typeName.as(SimpleTypeIdentifierSyntax.self) else { @@ -285,7 +285,7 @@ extension TypeInheritanceClauseSyntax? { } } -extension Trivia { +public extension Trivia { func containsNewlines() -> Bool { contains { piece in if case .newlines = piece { @@ -312,7 +312,7 @@ extension Trivia { } } -extension TriviaPiece { +public extension TriviaPiece { var isHorizontalWhitespace: Bool { switch self { case .spaces, .tabs: @@ -323,7 +323,7 @@ extension TriviaPiece { } } -extension IntegerLiteralExprSyntax { +public extension IntegerLiteralExprSyntax { var isZero: Bool { guard case let .integerLiteral(number) = digits.tokenKind else { return false @@ -333,7 +333,7 @@ extension IntegerLiteralExprSyntax { } } -extension FloatLiteralExprSyntax { +public extension FloatLiteralExprSyntax { var isZero: Bool { guard case let .floatingLiteral(number) = floatingDigits.tokenKind else { return false diff --git a/Source/SwiftLintFramework/Extensions/SyntaxClassification+isComment.swift b/Source/SwiftLintFramework/Extensions/SyntaxClassification+isComment.swift index 26211d7fc..0507e0dd3 100644 --- a/Source/SwiftLintFramework/Extensions/SyntaxClassification+isComment.swift +++ b/Source/SwiftLintFramework/Extensions/SyntaxClassification+isComment.swift @@ -1,6 +1,6 @@ import IDEUtils -extension SyntaxClassification { +public extension SyntaxClassification { // True if it is any kind of comment. var isComment: Bool { switch self { diff --git a/Source/SwiftLintFramework/Extensions/SyntaxKind+SwiftLint.swift b/Source/SwiftLintFramework/Extensions/SyntaxKind+SwiftLint.swift index ab78c9a6d..55ae676ee 100644 --- a/Source/SwiftLintFramework/Extensions/SyntaxKind+SwiftLint.swift +++ b/Source/SwiftLintFramework/Extensions/SyntaxKind+SwiftLint.swift @@ -1,6 +1,6 @@ import SourceKittenFramework -extension SyntaxKind { +public extension SyntaxKind { init(shortName: Swift.String) throws { let prefix = "source.lang.swift.syntaxtype." guard let kind = SyntaxKind(rawValue: prefix + shortName.lowercased()) else { diff --git a/Source/SwiftLintFramework/Helpers/Stack.swift b/Source/SwiftLintFramework/Helpers/Stack.swift index f4d126f25..0f1d1a69b 100644 --- a/Source/SwiftLintFramework/Helpers/Stack.swift +++ b/Source/SwiftLintFramework/Helpers/Stack.swift @@ -1,31 +1,43 @@ /// A basic stack type implementing the LIFO principle - only the last inserted element can be accessed and removed. -struct Stack { +public struct Stack { private var elements = [Element]() - var isEmpty: Bool { + /// Creates an empty `Stack`. + public init() {} + + /// True if the stack has no elements. False otherwise. + public var isEmpty: Bool { elements.isEmpty } - var count: Int { + /// The number of elements in this stack. + public var count: Int { elements.count } - mutating func push(_ element: Element) { + /// Pushes (appends) an element onto the stack. + /// + /// - parameter element: The element to push onto the stack. + public mutating func push(_ element: Element) { elements.append(element) } + /// Removes and returns the last element of the stack. + /// + /// - returns: The last element of the stack if the stack is not empty; otherwise, nil. @discardableResult - mutating func pop() -> Element? { + public mutating func pop() -> Element? { elements.popLast() } - func peek() -> Element? { + /// Returns the last element of the stack if the stack is not empty; otherwise, nil. + public func peek() -> Element? { elements.last } } extension Stack: CustomDebugStringConvertible where Element == CustomDebugStringConvertible { - var debugDescription: String { + public var debugDescription: String { let intermediateElements = count > 1 ? elements[1 ..< count - 1] : [] return """ Stack with \(count) elements: diff --git a/Source/SwiftLintFramework/Models/AccessControlLevel.swift b/Source/SwiftLintFramework/Models/AccessControlLevel.swift index 91bea2865..5e23aca58 100644 --- a/Source/SwiftLintFramework/Models/AccessControlLevel.swift +++ b/Source/SwiftLintFramework/Models/AccessControlLevel.swift @@ -16,7 +16,7 @@ public enum AccessControlLevel: String, CustomStringConvertible { /// Initializes an access control level by its Swift source keyword value. /// /// - parameter value: The value used to describe this level in Swift source code. - internal init?(description value: String) { + public init?(description value: String) { switch value { case "private": self = .private case "fileprivate": self = .fileprivate @@ -45,7 +45,7 @@ public enum AccessControlLevel: String, CustomStringConvertible { } /// Returns true if is `private` or `fileprivate` - var isPrivate: Bool { + public var isPrivate: Bool { return self == .private || self == .fileprivate } } diff --git a/Source/SwiftLintFramework/Models/Command.swift b/Source/SwiftLintFramework/Models/Command.swift index e3c547537..d9efb2ac6 100644 --- a/Source/SwiftLintFramework/Models/Command.swift +++ b/Source/SwiftLintFramework/Models/Command.swift @@ -46,15 +46,15 @@ public struct Command: Equatable { } /// The action (verb) that SwiftLint should perform when interpreting this command. - internal let action: Action + public let action: Action /// The identifiers for the rules associated with this command. - internal let ruleIdentifiers: Set + public let ruleIdentifiers: Set /// The line in the source file where this command is defined. - internal let line: Int + public let line: Int /// The character offset within the line in the source file where this command is defined. - internal let character: Int? + public let character: Int? /// This command's modifier, if any. - internal let modifier: Modifier? + public let modifier: Modifier? /// The comment following this command's `-` delimiter, if any. internal let trailingComment: String? diff --git a/Source/SwiftLintFramework/Models/Example.swift b/Source/SwiftLintFramework/Models/Example.swift index 1bb9addc3..455bf8195 100644 --- a/Source/SwiftLintFramework/Models/Example.swift +++ b/Source/SwiftLintFramework/Models/Example.swift @@ -147,7 +147,7 @@ extension Example: Comparable { } } -extension Array where Element == Example { +public extension Array where Element == Example { /// Make these examples skip wrapping in comment tests. func skipWrappingInCommentTests() -> Self { map { $0.skipWrappingInCommentTest() } diff --git a/Source/SwiftLintFramework/Models/SwiftLintFile.swift b/Source/SwiftLintFramework/Models/SwiftLintFile.swift index d626da1e1..f70a31227 100644 --- a/Source/SwiftLintFramework/Models/SwiftLintFile.swift +++ b/Source/SwiftLintFramework/Models/SwiftLintFile.swift @@ -4,10 +4,10 @@ import SourceKittenFramework /// A unit of Swift source code, either on disk or in memory. public final class SwiftLintFile { /// The underlying SourceKitten file. - let file: File + public let file: File let id: UUID /// Whether or not this is a file generated for testing purposes. - private(set) var isTestFile = false + public private(set) var isTestFile = false /// A file is virtual if it is not backed by a filesystem path. private(set) var isVirtual = false diff --git a/Source/SwiftLintFramework/Models/SwiftLintSyntaxMap.swift b/Source/SwiftLintFramework/Models/SwiftLintSyntaxMap.swift index 31f2e89f3..13f122ea3 100644 --- a/Source/SwiftLintFramework/Models/SwiftLintSyntaxMap.swift +++ b/Source/SwiftLintFramework/Models/SwiftLintSyntaxMap.swift @@ -21,7 +21,7 @@ public struct SwiftLintSyntaxMap { /// - parameter byteRange: Byte-based NSRange. /// /// - returns: The array of syntax tokens intersecting with byte range. - internal func tokens(inByteRange byteRange: ByteRange) -> [SwiftLintSyntaxToken] { + public func tokens(inByteRange byteRange: ByteRange) -> [SwiftLintSyntaxToken] { func intersect(_ token: SwiftLintSyntaxToken) -> Bool { return token.range.intersects(byteRange) } @@ -48,7 +48,7 @@ public struct SwiftLintSyntaxMap { /// - parameter byteRange: Byte range. /// /// - returns: The syntax kinds in the specified byte range. - internal func kinds(inByteRange byteRange: ByteRange) -> [SyntaxKind] { + public func kinds(inByteRange byteRange: ByteRange) -> [SyntaxKind] { return tokens(inByteRange: byteRange).compactMap { $0.kind } } } diff --git a/Source/SwiftLintFramework/Models/SwiftLintSyntaxToken.swift b/Source/SwiftLintFramework/Models/SwiftLintSyntaxToken.swift index 3d48c4796..9266e39f9 100644 --- a/Source/SwiftLintFramework/Models/SwiftLintSyntaxToken.swift +++ b/Source/SwiftLintFramework/Models/SwiftLintSyntaxToken.swift @@ -32,7 +32,7 @@ public struct SwiftLintSyntaxToken { } } -extension Array where Element == SwiftLintSyntaxToken { +public extension Array where Element == SwiftLintSyntaxToken { /// The kinds for these tokens. var kinds: [SyntaxKind] { return compactMap { $0.kind } diff --git a/Source/SwiftLintFramework/Protocols/CacheDescriptionProvider.swift b/Source/SwiftLintFramework/Protocols/CacheDescriptionProvider.swift index 349b3e8bf..01c3b4585 100644 --- a/Source/SwiftLintFramework/Protocols/CacheDescriptionProvider.swift +++ b/Source/SwiftLintFramework/Protocols/CacheDescriptionProvider.swift @@ -1,5 +1,5 @@ /// Interface providing access to a cache description. -internal protocol CacheDescriptionProvider { +public protocol CacheDescriptionProvider { /// The cache description which will be used to determine if a previous /// cached value is still valid given the new cache value. var cacheDescription: String { get } diff --git a/Source/SwiftLintFramework/Protocols/Rule.swift b/Source/SwiftLintFramework/Protocols/Rule.swift index 17928de3f..b13db3941 100644 --- a/Source/SwiftLintFramework/Protocols/Rule.swift +++ b/Source/SwiftLintFramework/Protocols/Rule.swift @@ -63,27 +63,27 @@ public protocol Rule { func validate(file: SwiftLintFile, using storage: RuleStorage, compilerArguments: [String]) -> [StyleViolation] } -extension Rule { - public func validate(file: SwiftLintFile, using storage: RuleStorage, - compilerArguments: [String]) -> [StyleViolation] { +public extension Rule { + func validate(file: SwiftLintFile, using storage: RuleStorage, + compilerArguments: [String]) -> [StyleViolation] { return validate(file: file, compilerArguments: compilerArguments) } - public func validate(file: SwiftLintFile, compilerArguments: [String]) -> [StyleViolation] { + func validate(file: SwiftLintFile, compilerArguments: [String]) -> [StyleViolation] { return validate(file: file) } - public func isEqualTo(_ rule: Rule) -> Bool { + func isEqualTo(_ rule: Rule) -> Bool { return Self.description == type(of: rule).description } - public func collectInfo(for file: SwiftLintFile, into storage: RuleStorage, compilerArguments: [String]) { + func collectInfo(for file: SwiftLintFile, into storage: RuleStorage, compilerArguments: [String]) { // no-op: only CollectingRules mutate their storage } /// The cache description which will be used to determine if a previous /// cached value is still valid given the new cache value. - internal var cacheDescription: String { + var cacheDescription: String { return (self as? CacheDescriptionProvider)?.cacheDescription ?? configurationDescription } } @@ -130,7 +130,6 @@ public protocol CorrectableRule: Rule { func correct(file: SwiftLintFile, using storage: RuleStorage, compilerArguments: [String]) -> [Correction] } -@_spi(TestHelper) public extension CorrectableRule { func correct(file: SwiftLintFile, compilerArguments: [String]) -> [Correction] { return correct(file: file) @@ -142,7 +141,6 @@ public extension CorrectableRule { /// A correctable rule that can apply its corrections by replacing the content of ranges in the offending file with /// updated content. -@_spi(TestHelper) public protocol SubstitutionCorrectableRule: CorrectableRule { /// Returns the NSString-based `NSRange`s to be replaced in the specified file. /// @@ -160,7 +158,6 @@ public protocol SubstitutionCorrectableRule: CorrectableRule { func substitution(for violationRange: NSRange, in file: SwiftLintFile) -> (NSRange, String)? } -@_spi(TestHelper) public extension SubstitutionCorrectableRule { func correct(file: SwiftLintFile) -> [Correction] { let violatingRanges = file.ruleEnabled(violatingRanges: violationRanges(in: file), for: self) @@ -184,7 +181,6 @@ public extension SubstitutionCorrectableRule { } /// A `SubstitutionCorrectableRule` that is also an `ASTRule`. -@_spi(TestHelper) public protocol SubstitutionCorrectableASTRule: SubstitutionCorrectableRule, ASTRule { /// Returns the NSString-based `NSRange`s to be replaced in the specified file. /// @@ -220,7 +216,6 @@ public extension AnalyzerRule { } /// :nodoc: -@_spi(TestHelper) public extension AnalyzerRule where Self: CorrectableRule { func correct(file: SwiftLintFile) -> [Correction] { queuedFatalError("Must call `correct(file:compilerArguments:)` for AnalyzerRule") diff --git a/Source/SwiftLintFramework/Protocols/SwiftSyntaxCorrectableRule.swift b/Source/SwiftLintFramework/Protocols/SwiftSyntaxCorrectableRule.swift index 77006568d..1f9ef51e9 100644 --- a/Source/SwiftLintFramework/Protocols/SwiftSyntaxCorrectableRule.swift +++ b/Source/SwiftLintFramework/Protocols/SwiftSyntaxCorrectableRule.swift @@ -1,7 +1,6 @@ import SwiftSyntax /// A SwiftLint CorrectableRule that performs its corrections using a SwiftSyntax `SyntaxRewriter`. -@_spi(TestHelper) public protocol SwiftSyntaxCorrectableRule: SwiftSyntaxRule, CorrectableRule { /// Produce a `ViolationsSyntaxRewriter` for the given file. /// @@ -11,7 +10,6 @@ public protocol SwiftSyntaxCorrectableRule: SwiftSyntaxRule, CorrectableRule { func makeRewriter(file: SwiftLintFile) -> ViolationsSyntaxRewriter? } -@_spi(TestHelper) public extension SwiftSyntaxCorrectableRule { func correct(file: SwiftLintFile) -> [Correction] { guard let rewriter = makeRewriter(file: file), diff --git a/Source/SwiftLintFramework/Protocols/SwiftSyntaxRule.swift b/Source/SwiftLintFramework/Protocols/SwiftSyntaxRule.swift index 7a187aa91..23c32c0a4 100644 --- a/Source/SwiftLintFramework/Protocols/SwiftSyntaxRule.swift +++ b/Source/SwiftLintFramework/Protocols/SwiftSyntaxRule.swift @@ -112,7 +112,7 @@ public struct ReasonedRuleViolation: Comparable { /// Extension for arrays of `ReasonedRuleViolation`s that provides the automatic conversion of /// `AbsolutePosition`s into `ReasonedRuleViolation`s (without a specific reason). -extension Array where Element == ReasonedRuleViolation { +public extension Array where Element == ReasonedRuleViolation { /// Append a minimal violation for the specified position. /// /// - parameter position: The position for the violation to append. @@ -131,9 +131,9 @@ extension Array where Element == ReasonedRuleViolation { /// A SwiftSyntax `SyntaxVisitor` that produces absolute positions where violations should be reported. open class ViolationsSyntaxVisitor: SyntaxVisitor { /// Positions in a source file where violations should be reported. - internal var violations: [ReasonedRuleViolation] = [] + public var violations: [ReasonedRuleViolation] = [] /// List of declaration types that shall be skipped while traversing the AST. - internal var skippableDeclarations: [DeclSyntaxProtocol.Type] { [] } + open var skippableDeclarations: [DeclSyntaxProtocol.Type] { [] } override open func visit(_ node: ActorDeclSyntax) -> SyntaxVisitorContinueKind { skippableDeclarations.contains { $0 == ActorDeclSyntax.self } ? .skipChildren : .visitChildren @@ -172,7 +172,7 @@ open class ViolationsSyntaxVisitor: SyntaxVisitor { } } -extension Array where Element == DeclSyntaxProtocol.Type { +public extension Array where Element == DeclSyntaxProtocol.Type { /// All visitable declaration syntax types. static let all: Self = [ ActorDeclSyntax.self, diff --git a/Source/SwiftLintFramework/Rules/RuleConfigurations/RegexConfiguration.swift b/Source/SwiftLintFramework/Rules/RuleConfigurations/RegexConfiguration.swift index 1a6ec9713..087008c23 100644 --- a/Source/SwiftLintFramework/Rules/RuleConfigurations/RegexConfiguration.swift +++ b/Source/SwiftLintFramework/Rules/RuleConfigurations/RegexConfiguration.swift @@ -26,7 +26,7 @@ public struct RegexConfiguration: SeverityBasedRuleConfiguration, Hashable, Cach return "\(severity.rawValue): \(regex.pattern)" } - internal var cacheDescription: String { + public var cacheDescription: String { let jsonObject: [String] = [ identifier, name ?? "", diff --git a/Source/SwiftLintFramework/Rules/RuleConfigurations/SeverityLevelsConfiguration.swift b/Source/SwiftLintFramework/Rules/RuleConfigurations/SeverityLevelsConfiguration.swift index 54380a6d2..ce4d464a8 100644 --- a/Source/SwiftLintFramework/Rules/RuleConfigurations/SeverityLevelsConfiguration.swift +++ b/Source/SwiftLintFramework/Rules/RuleConfigurations/SeverityLevelsConfiguration.swift @@ -19,21 +19,21 @@ public struct SeverityLevelsConfiguration: RuleConfiguration, Equatable { } /// The threshold for a violation to be a warning. - var warning: Int + public var warning: Int /// The threshold for a violation to be an error. - var error: Int? + public var error: Int? /// Create a `SeverityLevelsConfiguration` based on the sepecified `warning` and `error` thresholds. /// /// - parameter warning: The threshold for a violation to be a warning. /// - parameter error: The threshold for a violation to be an error. - init(warning: Int, error: Int? = nil) { + public init(warning: Int, error: Int? = nil) { self.warning = warning self.error = error } /// The rule parameters that define the thresholds that should map to each severity. - var params: [RuleParameter] { + public var params: [RuleParameter] { if let error { return [RuleParameter(severity: .error, value: error), RuleParameter(severity: .warning, value: warning)] diff --git a/Source/SwiftLintFramework/Rules/Style/IdentifierNameRule.swift b/Source/SwiftLintFramework/Rules/Style/IdentifierNameRule.swift index 74d512641..a6ec2face 100644 --- a/Source/SwiftLintFramework/Rules/Style/IdentifierNameRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/IdentifierNameRule.swift @@ -142,4 +142,12 @@ private extension String { let operators = ["/", "=", "-", "+", "!", "*", "|", "^", "~", "?", ".", "%", "<", ">", "&"] return operators.contains(where: hasPrefix) } + + func nameStrippingLeadingUnderscoreIfPrivate(_ dict: SourceKittenDictionary) -> String { + if let acl = dict.accessibility, + acl.isPrivate && first == "_" { + return String(self[index(after: startIndex)...]) + } + return self + } }