@@ -94,11 +94,8 @@ internal extension Driver {
94
94
contents)
95
95
}
96
96
97
- mutating func performDependencyScan( ) throws -> InterModuleDependencyGraph {
98
- let scannerJob = try dependencyScanningJob ( )
99
- let forceResponseFiles = parsedOptions. hasArgument ( . driverForceResponseFiles)
100
- let dependencyGraph : InterModuleDependencyGraph
101
-
97
+ /// Returns false if the lib is available and ready to use
98
+ private func initSwiftScanLib( ) throws -> Bool {
102
99
// If `-nonlib-dependency-scanner` was specified or the libSwiftScan library cannot be found,
103
100
// attempt to fallback to using `swift-frontend -scan-dependencies` invocations for dependency
104
101
// scanning.
@@ -110,20 +107,58 @@ internal extension Driver {
110
107
fallbackToFrontend = true
111
108
diagnosticEngine. emit ( . warn_scanner_frontend_fallback( ) )
112
109
}
110
+ return fallbackToFrontend
111
+ }
112
+
113
+ private func sanitizeCommandForLibScanInvocation( _ command: inout [ String ] ) {
114
+ // Remove the tool executable to only leave the arguments
115
+ command. removeFirst ( )
116
+ // We generate full swiftc -frontend -scan-dependencies invocations in order to also be
117
+ // able to launch them as standalone jobs. Frontend's argument parser won't recognize
118
+ // -frontend when passed directly.
119
+ if command. first == " -frontend " {
120
+ command. removeFirst ( )
121
+ }
122
+ }
123
+
124
+ mutating func performImportPrescan( ) throws -> InterModuleDependencyImports {
125
+ let preScanJob = try importPreScanningJob ( )
126
+ let forceResponseFiles = parsedOptions. hasArgument ( . driverForceResponseFiles)
127
+ let imports : InterModuleDependencyImports
128
+
129
+ if !( try initSwiftScanLib ( ) ) {
130
+ let cwd = workingDirectory ?? fileSystem. currentWorkingDirectory!
131
+ var command = try itemizedJobCommand ( of: preScanJob,
132
+ forceResponseFiles: forceResponseFiles,
133
+ using: executor. resolver)
134
+ sanitizeCommandForLibScanInvocation ( & command)
135
+ imports =
136
+ try interModuleDependencyOracle. getImports ( workingDirectory: cwd,
137
+ commandLine: command)
138
+
139
+ } else {
140
+ // Fallback to legacy invocation of the dependency scanner with
141
+ // `swift-frontend -scan-dependencies -import-prescan`
142
+ imports =
143
+ try self . executor. execute ( job: preScanJob,
144
+ capturingJSONOutputAs: InterModuleDependencyImports . self,
145
+ forceResponseFiles: forceResponseFiles,
146
+ recordedInputModificationDates: recordedInputModificationDates)
147
+ }
148
+ return imports
149
+ }
150
+
151
+ mutating func performDependencyScan( ) throws -> InterModuleDependencyGraph {
152
+ let scannerJob = try dependencyScanningJob ( )
153
+ let forceResponseFiles = parsedOptions. hasArgument ( . driverForceResponseFiles)
154
+ let dependencyGraph : InterModuleDependencyGraph
113
155
114
- if ( !fallbackToFrontend ) {
156
+ if ! ( try initSwiftScanLib ( ) ) {
115
157
let cwd = workingDirectory ?? fileSystem. currentWorkingDirectory!
116
158
var command = try itemizedJobCommand ( of: scannerJob,
117
159
forceResponseFiles: forceResponseFiles,
118
160
using: executor. resolver)
119
- // Remove the tool executable to only leave the arguments
120
- command. removeFirst ( )
121
- // We generate full swiftc -frontend -scan-dependencies invocations in order to also be
122
- // able to launch them as standalone jobs. Frontend's argument parser won't recognize
123
- // -frontend when passed directly.
124
- if command. first == " -frontend " {
125
- command. removeFirst ( )
126
- }
161
+ sanitizeCommandForLibScanInvocation ( & command)
127
162
dependencyGraph =
128
163
try interModuleDependencyOracle. getDependencies ( workingDirectory: cwd,
129
164
commandLine: command)
@@ -143,33 +178,14 @@ internal extension Driver {
143
178
throws -> [ ModuleDependencyId : [ InterModuleDependencyGraph ] ] {
144
179
let batchScanningJob = try batchDependencyScanningJob ( for: moduleInfos)
145
180
let forceResponseFiles = parsedOptions. hasArgument ( . driverForceResponseFiles)
146
-
147
- // If `-nonlib-dependency-scanner` was specified or the libSwiftScan library cannot be found,
148
- // attempt to fallback to using `swift-frontend -scan-dependencies` invocations for dependency
149
- // scanning.
150
- var fallbackToFrontend = parsedOptions. hasArgument ( . driverScanDependenciesNonLib)
151
- let scanLibPath = try Self . getScanLibPath ( of: toolchain, hostTriple: hostTriple, env: env)
152
- if try interModuleDependencyOracle
153
- . verifyOrCreateScannerInstance ( fileSystem: fileSystem,
154
- swiftScanLibPath: scanLibPath) == false {
155
- fallbackToFrontend = true
156
- diagnosticEngine. emit ( . warn_scanner_frontend_fallback( ) )
157
- }
158
-
159
181
let moduleVersionedGraphMap : [ ModuleDependencyId : [ InterModuleDependencyGraph ] ]
160
- if ( !fallbackToFrontend) {
182
+
183
+ if !( try initSwiftScanLib ( ) ) {
161
184
let cwd = workingDirectory ?? fileSystem. currentWorkingDirectory!
162
185
var command = try itemizedJobCommand ( of: batchScanningJob,
163
186
forceResponseFiles: forceResponseFiles,
164
187
using: executor. resolver)
165
- // Remove the tool executable to only leave the arguments
166
- command. removeFirst ( )
167
- // We generate full swiftc -frontend -scan-dependencies invocations in order to also be
168
- // able to launch them as standalone jobs. Frontend's argument parser won't recognize
169
- // -frontend when passed directly.
170
- if command. first == " -frontend " {
171
- command. removeFirst ( )
172
- }
188
+ sanitizeCommandForLibScanInvocation ( & command)
173
189
moduleVersionedGraphMap =
174
190
try interModuleDependencyOracle. getBatchDependencies ( workingDirectory: cwd,
175
191
commandLine: command,
@@ -226,6 +242,34 @@ internal extension Driver {
226
242
return moduleVersionedGraphMap
227
243
}
228
244
245
+ /// Precompute the set of module names as imported by the current module
246
+ mutating func importPreScanningJob( ) throws -> Job {
247
+ // Aggregate the fast dependency scanner arguments
248
+ var inputs : [ TypedVirtualPath ] = [ ]
249
+ var commandLine : [ Job . ArgTemplate ] = swiftCompilerPrefixArgs. map { Job . ArgTemplate. flag ( $0) }
250
+ commandLine. appendFlag ( " -frontend " )
251
+ commandLine. appendFlag ( " -scan-dependencies " )
252
+ commandLine. appendFlag ( " -import-prescan " )
253
+ try addCommonFrontendOptions ( commandLine: & commandLine, inputs: & inputs,
254
+ bridgingHeaderHandling: . precompiled,
255
+ moduleDependencyGraphUse: . dependencyScan)
256
+ // FIXME: MSVC runtime flags
257
+
258
+ // Pass on the input files
259
+ commandLine. append ( contentsOf: inputFiles. map { . path( $0. file) } )
260
+
261
+ // Construct the scanning job.
262
+ return Job ( moduleName: moduleOutputInfo. name,
263
+ kind: . scanDependencies,
264
+ tool: VirtualPath . absolute ( try toolchain. getToolPath ( . swiftCompiler) ) ,
265
+ commandLine: commandLine,
266
+ displayInputs: inputs,
267
+ inputs: inputs,
268
+ primaryInputs: [ ] ,
269
+ outputs: [ TypedVirtualPath ( file: . standardOutput, type: . jsonDependencies) ] ,
270
+ supportsResponseFiles: true )
271
+ }
272
+
229
273
/// Precompute the dependencies for a given collection of modules using swift frontend's batch scanning mode
230
274
mutating func batchDependencyScanningJob( for moduleInfos: [ BatchScanModuleInfo ] ) throws -> Job {
231
275
var inputs : [ TypedVirtualPath ] = [ ]
0 commit comments