-
-
Notifications
You must be signed in to change notification settings - Fork 195
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add experimental unused import analysis.
- Loading branch information
Showing
27 changed files
with
217 additions
and
36 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,4 @@ targets: | |
- PeripheryTests | ||
- SPMTests | ||
- AccessibilityTests | ||
enable_unused_import_analysis: true |
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 |
---|---|---|
|
@@ -8,3 +8,4 @@ targets: | |
- XcodeTests | ||
- SPMTests | ||
- AccessibilityTests | ||
enable_unused_import_analysis: true |
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 |
---|---|---|
|
@@ -6,7 +6,7 @@ | |
|
||
##### Enhancements | ||
|
||
- None. | ||
- Add experimental unused import analysis. | ||
|
||
##### Bug Fixes | ||
|
||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
import Foundation | ||
import ArgumentParser | ||
import PeripheryKit | ||
import Shared | ||
|
||
Logger.configureBuffering() | ||
|
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
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
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
82 changes: 82 additions & 0 deletions
82
Sources/PeripheryKit/SourceGraph/Mutators/UnusedImportMarker.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,82 @@ | ||
import Foundation | ||
import Shared | ||
|
||
/// Marks unused import statements (experimental). | ||
/// | ||
/// A module import is unused when the source file contains no references to it, and no other | ||
/// imported modules either export it, or extend declarations declared by it. | ||
/// | ||
/// Testing TODO: | ||
/// * Exports, including nested exports | ||
/// * Public declaration extended by another module | ||
final class UnusedImportMarker: SourceGraphMutator { | ||
private let graph: SourceGraph | ||
private let configuration: Configuration | ||
|
||
required init(graph: SourceGraph, configuration: Configuration) { | ||
self.graph = graph | ||
self.configuration = configuration | ||
} | ||
|
||
func mutate() throws { | ||
guard configuration.enableUnusedImportsAnalysis else { return } | ||
|
||
var referencedModulesByFile = [SourceFile: Set<String>]() | ||
|
||
// Build a mapping of source files and the modules they reference. | ||
for ref in graph.allReferences { | ||
guard let decl = graph.explicitDeclaration(withUsr: ref.usr) else { continue } | ||
// Record directly referenced modules and also identify any modules that extended | ||
// the declaration. These extensions may provide members/conformances that aren't | ||
// referenced directly but which are still required. | ||
let referencedModules = decl.location.file.modules.union(modulesExtending(decl)) | ||
referencedModulesByFile[ref.location.file, default: []].formUnion(referencedModules) | ||
} | ||
|
||
// For each source file, determine whether its imports are unused. | ||
for (file, referencedModules) in referencedModulesByFile { | ||
let unreferencedImports = file.importStatements | ||
.filter { | ||
// Only consider modules that have been indexed as we need to see which modules | ||
// they export. | ||
graph.indexedModules.contains($0.module) && | ||
!referencedModules.contains($0.module) | ||
} | ||
|
||
for unreferencedImport in unreferencedImports { | ||
// In the simple case, a module is unused if it's not referenced. However, it's | ||
// possible the module exports other referenced modules. | ||
guard !referencedModules.contains(where: { | ||
graph.isModule($0, exportedBy: unreferencedImport.module) | ||
}) else { continue } | ||
|
||
graph.markUnusedModuleImport(unreferencedImport) | ||
} | ||
} | ||
} | ||
|
||
// MARK: - Private | ||
|
||
private var extendedDeclCache: [Declaration: Set<String>] = [:] | ||
|
||
/// Identifies any modules that extend the given declaration. | ||
private func modulesExtending(_ decl: Declaration) -> Set<String> { | ||
guard decl.kind.isExtendableKind else { return [] } | ||
|
||
if let modules = extendedDeclCache[decl] { | ||
return modules | ||
} | ||
|
||
let modules: Set<String> = graph.references(to: decl) | ||
.flatMapSet { | ||
guard let parent = $0.parent, | ||
parent.kind == decl.kind.extensionKind, | ||
parent.name == decl.name | ||
else { return [] } | ||
|
||
return parent.location.file.modules | ||
} | ||
extendedDeclCache[decl] = modules | ||
return modules | ||
} | ||
} |
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
Oops, something went wrong.