11import Foundation
22
33/// Performs multiple checks at once considering certain optimizations depending on the amount of them
4- public final class SourceFileBatchChecker {
4+ public actor SourceFileBatchChecker {
55
66 public typealias ReportStream = AsyncThrowingStream < ErrorMessage , Error >
7-
7+ public typealias UnusedKeysStream = AsyncThrowingStream < UnusedKeyMessage , Error >
8+ typealias ReportMessages = ( errors: [ ErrorMessage ] , unused: [ UnusedKeyMessage ] , used: [ LocalizeEntry ] )
9+
810 @available ( macOS 12 , * )
911 /// Async stream of obtained check reports
1012 public var reports : ReportStream {
1113 get throws {
1214 try run ( )
1315 }
1416 }
15-
16- @available ( macOS, deprecated: 12 , obsoleted: 13 , message: " Use much faster reports stream " )
17- public func getReports( ) throws -> [ ErrorMessage ] {
18- try syncRun ( )
17+
18+ public var unusedKeys : [ UnusedKeyMessage ] {
19+ get async throws {
20+ try await runForUnusedKeys ( )
21+ }
1922 }
2023
2124 @available ( macOS 12 , * )
@@ -60,20 +63,21 @@ public final class SourceFileBatchChecker {
6063 @discardableResult
6164 func run( ) throws -> ReportStream {
6265 let localizeBundle = try LocalizeBundle ( directoryPath: localizeBundleUrl. path)
66+ let chunks = chunks
6367 return ReportStream { continuation in
6468 Task {
65- await withThrowingTaskGroup ( of: [ ErrorMessage ] . self) { group in
69+ await withThrowingTaskGroup ( of: ReportMessages . self) { group in
6670 for filesChunk in chunks {
6771 group. addTask {
68- try self . processBatch (
72+ try await self . processBatch (
6973 ofSourceFiles: Array ( filesChunk) ,
7074 in: localizeBundle
7175 )
7276 }
7377 }
7478
7579 do {
76- for try await reportsChunk in group {
80+ for try await ( reportsChunk, _ , _ ) in group {
7781 reportsChunk. forEach {
7882 continuation. yield ( $0)
7983 }
@@ -86,9 +90,40 @@ public final class SourceFileBatchChecker {
8690 }
8791 }
8892 }
89-
93+
94+ @available ( macOS 12 , * )
95+ @discardableResult
96+ func runForUnusedKeys( ) async throws -> [ UnusedKeyMessage ] {
97+ let localizeBundle = try LocalizeBundle ( directoryPath: localizeBundleUrl. path)
98+ return try await Task {
99+ try await withThrowingTaskGroup ( of: ReportMessages . self) { group in
100+ for filesChunk in chunks {
101+ group. addTask {
102+ try await self . processBatch (
103+ ofSourceFiles: Array ( filesChunk) ,
104+ in: localizeBundle
105+ )
106+ }
107+ }
108+
109+ var usedKeys : Set < String > = [ ]
110+ var unusedKeys : Set < String > = [ ]
111+ for try await (_, unusedKeysChunk, usedKeysChunk) in group {
112+ unusedKeysChunk. forEach {
113+ unusedKeys. insert ( $0. key)
114+ }
115+ usedKeysChunk. forEach {
116+ usedKeys. insert ( $0. key)
117+ }
118+ }
119+ let trulyUnusedKeys = unusedKeys. subtracting ( usedKeys)
120+ return Array ( trulyUnusedKeys. map ( UnusedKeyMessage . init ( key: ) ) )
121+ }
122+ } . value
123+ }
124+
90125 @discardableResult
91- func syncRun( ) throws -> [ ErrorMessage ] {
126+ func syncRun( ) throws -> ReportMessages {
92127 let localizeBundle = LocalizeBundle ( fileUrl: localizeBundleUrl)
93128 let reports = try self . processBatch (
94129 ofSourceFiles: sourceFiles,
@@ -98,7 +133,7 @@ public final class SourceFileBatchChecker {
98133 return reports
99134 }
100135
101- private func processBatch( ofSourceFiles files: [ String ] , in localizeBundle: LocalizeBundle ) throws -> [ ErrorMessage ] {
136+ private func processBatch( ofSourceFiles files: [ String ] , in localizeBundle: LocalizeBundle ) throws -> ReportMessages {
102137 let fileUrls = files. compactMap ( URL . init ( fileURLWithPath: ) )
103138 let sourceCheckers = try fileUrls. map {
104139 try SourceFileChecker ( fileUrl: $0, localizeBundle: localizeBundle)
@@ -107,7 +142,11 @@ public final class SourceFileBatchChecker {
107142 try sourceChecker. start ( )
108143 }
109144
110- return sourceCheckers. flatMap ( \. errors)
145+ return (
146+ sourceCheckers. flatMap ( \. errors) ,
147+ sourceCheckers. flatMap ( \. unusedKeys) . map ( UnusedKeyMessage . init ( key: ) ) ,
148+ sourceCheckers. flatMap ( \. usedKeys)
149+ )
111150 }
112151
113152}
0 commit comments