@@ -92,7 +92,7 @@ class Frontend {
92
92
if paths. isEmpty {
93
93
processStandardInput ( )
94
94
} else {
95
- processPaths ( paths)
95
+ processPaths ( paths, parallel : lintFormatOptions . parallel )
96
96
}
97
97
}
98
98
@@ -124,30 +124,47 @@ class Frontend {
124
124
}
125
125
126
126
/// Processes source content from a list of files and/or directories provided as paths.
127
- private func processPaths( _ paths: [ String ] ) {
127
+ private func processPaths( _ paths: [ String ] , parallel : Bool ) {
128
128
precondition (
129
129
!paths. isEmpty,
130
130
" processPaths(_:) should only be called when paths is non-empty. " )
131
131
132
- for path in FileIterator ( paths: paths) {
133
- guard let sourceFile = FileHandle ( forReadingAtPath: path) else {
134
- diagnosticEngine. diagnose ( Diagnostic . Message ( . error, " Unable to open \( path) " ) )
135
- continue
132
+ let lock = NSLock ( )
133
+ if parallel {
134
+ let allFilePaths = Array ( FileIterator ( paths: paths) )
135
+ DispatchQueue . concurrentPerform ( iterations: allFilePaths. count) { index in
136
+ let path = allFilePaths [ index]
137
+ openAndProcess ( path, lock: lock)
136
138
}
137
-
138
- guard let configuration = configuration (
139
- atPath: lintFormatOptions. configurationPath, orInferredFromSwiftFileAtPath: path)
140
- else {
141
- // Already diagnosed in the called method.
142
- continue
139
+ } else {
140
+ for path in FileIterator ( paths: paths) {
141
+ openAndProcess ( path, lock: nil )
143
142
}
143
+ }
144
+ }
144
145
145
- let fileToProcess = FileToProcess (
146
- fileHandle: sourceFile, path: path, configuration: configuration)
147
- processFile ( fileToProcess)
146
+ /// Read and process the given path, optionally synchronizing diagnostic output with the given lock.
147
+ private func openAndProcess( _ path: String , lock: NSLock ? ) -> Void {
148
+ guard let sourceFile = FileHandle ( forReadingAtPath: path) else {
149
+ lock? . lock ( )
150
+ defer { lock? . unlock ( ) }
151
+ diagnosticEngine. diagnose ( Diagnostic . Message ( . error, " Unable to open \( path) " ) )
152
+ return
148
153
}
154
+
155
+ guard let configuration = configuration (
156
+ atPath: lintFormatOptions. configurationPath, orInferredFromSwiftFileAtPath: path)
157
+ else {
158
+ // Already diagnosed in the called method.
159
+ return
160
+ }
161
+
162
+ let fileToProcess = FileToProcess (
163
+ fileHandle: sourceFile, path: path, configuration: configuration)
164
+ processFile ( fileToProcess)
149
165
}
150
166
167
+
151
168
/// Returns the configuration that applies to the given `.swift` source file, when an explicit
152
169
/// configuration path is also perhaps provided.
153
170
///
0 commit comments