mirror of
https://github.com/realm/SwiftLint.git
synced 2026-05-07 20:12:49 +00:00
d10ccacb45
For example, if `CGFloat` is used in a file where only `UIKit` is imported but not `CoreGraphics`, this will be a violation even if the file previously compiled.
This is because Swift allows referencing some declarations that are only transitively imported.
Enabling the `require_explicit_imports` configuration option will require that the module of every declaration referenced in a source file be explicitly imported.
This will add significant noise to the imports list, but has a few advantages:
1. It will be easier to understand all the dependencies explicitly referenced in a source file.
2. Correcting the `unused_import` rule will no longer introduce compilation errors in files that compiled prior to the correction.
If missing imports are added to a file when correcting it, the `sorted_imports` rule will be automatically run on that file.
If you with to allow some imports to be implicitly importable transitively, you may specify the `allowed_transitive_imports` configuration:
```yaml
unused_import:
require_explicit_imports: true
allowed_transitive_imports:
- module: Foundation
allowed_transitive_imports:
- CoreFoundation
- Darwin
- ObjectiveC
```
101 lines
3.2 KiB
Swift
101 lines
3.2 KiB
Swift
import Foundation
|
|
import SourceKittenFramework
|
|
|
|
/// A unit of Swift source code, either on disk or in memory.
|
|
public final class SwiftLintFile {
|
|
private static var id = 0
|
|
private static var lock = NSLock()
|
|
|
|
private static func nextID () -> Int {
|
|
lock.lock()
|
|
defer { lock.unlock() }
|
|
id += 1
|
|
return id
|
|
}
|
|
|
|
let file: File
|
|
let id: Int
|
|
|
|
/// Creates a `SwiftLintFile` with a SourceKitten `File`.
|
|
///
|
|
/// - parameter file: A file from SourceKitten.
|
|
public init(file: File) {
|
|
self.file = file
|
|
self.id = SwiftLintFile.nextID()
|
|
}
|
|
|
|
/// Creates a `SwiftLintFile` by specifying its path on disk.
|
|
/// Fails if the file does not exist.
|
|
///
|
|
/// - parameter path: The path to a file on disk. Relative and absolute paths supported.
|
|
public convenience init?(path: String) {
|
|
guard let file = File(path: path) else { return nil }
|
|
self.init(file: file)
|
|
}
|
|
|
|
/// Creates a `SwiftLintFile` by specifying its path on disk. Unlike the `SwiftLintFile(path:)` initializer, this
|
|
/// one does not read its contents immediately, but rather traps at runtime when attempting to access its contents.
|
|
///
|
|
/// - parameter path: The path to a file on disk. Relative and absolute paths supported.
|
|
public convenience init(pathDeferringReading path: String) {
|
|
self.init(file: File(pathDeferringReading: path))
|
|
}
|
|
|
|
/// Creates a `SwiftLintFile` that is not backed by a file on disk by specifying its contents.
|
|
///
|
|
/// - parameter contents: The contents of the file.
|
|
public convenience init(contents: String) {
|
|
self.init(file: File(contents: contents))
|
|
}
|
|
|
|
/// The path on disk for this file.
|
|
public var path: String? {
|
|
return file.path
|
|
}
|
|
|
|
/// The file's contents.
|
|
public var contents: String {
|
|
return file.contents
|
|
}
|
|
|
|
/// A string view into the contents of this file optimized for string manipulation operations.
|
|
public var stringView: StringView {
|
|
return file.stringView
|
|
}
|
|
|
|
/// The parsed lines for this file's contents.
|
|
public var lines: [Line] {
|
|
return file.lines
|
|
}
|
|
|
|
/// Returns whether or not the file contains any attributes that require the Foundation module.
|
|
func containsAttributesRequiringFoundation() -> Bool {
|
|
guard contents.contains("@objc") else {
|
|
return false
|
|
}
|
|
|
|
func containsAttributesRequiringFoundation(dict: SourceKittenDictionary) -> Bool {
|
|
let attributesRequiringFoundation = SwiftDeclarationAttributeKind.attributesRequiringFoundation
|
|
if !attributesRequiringFoundation.isDisjoint(with: dict.enclosedSwiftAttributes) {
|
|
return true
|
|
} else {
|
|
return dict.substructure.contains(where: containsAttributesRequiringFoundation)
|
|
}
|
|
}
|
|
|
|
return containsAttributesRequiringFoundation(dict: structureDictionary)
|
|
}
|
|
}
|
|
|
|
// MARK: - Hashable Conformance
|
|
|
|
extension SwiftLintFile: Hashable {
|
|
public static func == (lhs: SwiftLintFile, rhs: SwiftLintFile) -> Bool {
|
|
return lhs.id == rhs.id
|
|
}
|
|
|
|
public func hash(into hasher: inout Hasher) {
|
|
hasher.combine(id)
|
|
}
|
|
}
|