@@ -146,8 +146,8 @@ public actor SwiftPMBuildSystem {
146
146
}
147
147
}
148
148
149
- var fileToTarget : [ AbsolutePath : SwiftBuildTarget ] = [ : ]
150
- var sourceDirToTarget : [ AbsolutePath : SwiftBuildTarget ] = [ : ]
149
+ var fileToTarget : [ DocumentURI : SwiftBuildTarget ] = [ : ]
150
+ var sourceDirToTarget : [ DocumentURI : SwiftBuildTarget ] = [ : ]
151
151
152
152
/// Maps configured targets ids to their SwiftPM build target as well as an index in their topological sorting.
153
153
///
@@ -286,15 +286,18 @@ public actor SwiftPMBuildSystem {
286
286
/// - reloadPackageStatusCallback: Will be informed when `reloadPackage` starts and ends executing.
287
287
/// - Returns: nil if `workspacePath` is not part of a package or there is an error.
288
288
public init ? (
289
- url : URL ,
289
+ uri : DocumentURI ,
290
290
toolchainRegistry: ToolchainRegistry ,
291
291
buildSetup: BuildSetup ,
292
292
isForIndexBuild: Bool ,
293
293
reloadPackageStatusCallback: @escaping ( ReloadPackageStatus ) async -> Void
294
294
) async {
295
+ guard let fileURL = uri. fileURL else {
296
+ return nil
297
+ }
295
298
do {
296
299
try await self . init (
297
- workspacePath: try TSCAbsolutePath ( validating: url . path) ,
300
+ workspacePath: try TSCAbsolutePath ( validating: fileURL . path) ,
298
301
toolchainRegistry: toolchainRegistry,
299
302
fileSystem: localFileSystem,
300
303
buildSetup: buildSetup,
@@ -304,7 +307,7 @@ public actor SwiftPMBuildSystem {
304
307
} catch Error . noManifest {
305
308
return nil
306
309
} catch {
307
- logger. error ( " failed to create SwiftPMWorkspace at \( url . path ) : \( error. forLogging) " )
310
+ logger. error ( " failed to create SwiftPMWorkspace at \( uri . forLogging ) : \( error. forLogging) " )
308
311
return nil
309
312
}
310
313
}
@@ -351,13 +354,13 @@ extension SwiftPMBuildSystem {
351
354
}
352
355
)
353
356
354
- self . fileToTarget = [ AbsolutePath : SwiftBuildTarget] (
357
+ self . fileToTarget = [ DocumentURI : SwiftBuildTarget] (
355
358
modulesGraph. allTargets. flatMap { target in
356
359
return target. sources. paths. compactMap {
357
360
guard let buildTarget = buildDescription. getBuildTarget ( for: target, in: modulesGraph) else {
358
361
return nil
359
362
}
360
- return ( key: $0 , value: buildTarget)
363
+ return ( key: DocumentURI ( $0 . asURL ) , value: buildTarget)
361
364
}
362
365
} ,
363
366
uniquingKeysWith: { td, _ in
@@ -366,12 +369,12 @@ extension SwiftPMBuildSystem {
366
369
}
367
370
)
368
371
369
- self . sourceDirToTarget = [ AbsolutePath : SwiftBuildTarget] (
370
- modulesGraph. allTargets. compactMap { ( target) -> ( AbsolutePath , SwiftBuildTarget ) ? in
372
+ self . sourceDirToTarget = [ DocumentURI : SwiftBuildTarget] (
373
+ modulesGraph. allTargets. compactMap { ( target) -> ( DocumentURI , SwiftBuildTarget ) ? in
371
374
guard let buildTarget = buildDescription. getBuildTarget ( for: target, in: modulesGraph) else {
372
375
return nil
373
376
}
374
- return ( key: target. sources. root, value: buildTarget)
377
+ return ( key: DocumentURI ( target. sources. root. asURL ) , value: buildTarget)
375
378
} ,
376
379
uniquingKeysWith: { td, _ in
377
380
// FIXME: is there a preferred target?
@@ -390,6 +393,13 @@ extension SwiftPMBuildSystem {
390
393
}
391
394
}
392
395
396
+ fileprivate struct NonFileURIError : Error , CustomStringConvertible {
397
+ let uri : DocumentURI
398
+ var description : String {
399
+ " Trying to get build settings for non-file URI: \( uri) "
400
+ }
401
+ }
402
+
393
403
extension SwiftPMBuildSystem : SKCore . BuildSystem {
394
404
public nonisolated var supportsPreparation : Bool { true }
395
405
@@ -410,8 +420,11 @@ extension SwiftPMBuildSystem: SKCore.BuildSystem {
410
420
411
421
/// Return the compiler arguments for the given source file within a target, making any necessary adjustments to
412
422
/// account for differences in the SwiftPM versions being linked into SwiftPM and being installed in the toolchain.
413
- private func compilerArguments( for file: URL , in buildTarget: any SwiftBuildTarget ) async throws -> [ String ] {
414
- let compileArguments = try buildTarget. compileArguments ( for: file)
423
+ private func compilerArguments( for file: DocumentURI , in buildTarget: any SwiftBuildTarget ) async throws -> [ String ] {
424
+ guard let fileURL = file. fileURL else {
425
+ throw NonFileURIError ( uri: file)
426
+ }
427
+ let compileArguments = try buildTarget. compileArguments ( for: fileURL)
415
428
416
429
#if compiler(>=6.1)
417
430
#warning("When we drop support for Swift 5.10 we no longer need to adjust compiler arguments for the Modules move")
@@ -449,9 +462,10 @@ extension SwiftPMBuildSystem: SKCore.BuildSystem {
449
462
return nil
450
463
}
451
464
452
- if !buildTarget. sources. contains ( url ) ,
465
+ if !buildTarget. sources. lazy . map ( DocumentURI . init ) . contains ( uri ) ,
453
466
let substituteFile = buildTarget. sources. sorted ( by: { $0. path < $1. path } ) . first
454
467
{
468
+ logger. info ( " Getting compiler arguments for \( url) using substitute file \( substituteFile) " )
455
469
// If `url` is not part of the target's source, it's most likely a header file. Fake compiler arguments for it
456
470
// from a substitute file within the target.
457
471
// Even if the file is not a header, this should give reasonable results: Say, there was a new `.cpp` file in a
@@ -460,13 +474,13 @@ extension SwiftPMBuildSystem: SKCore.BuildSystem {
460
474
// getting its compiler arguments and then patching up the compiler arguments by replacing the substitute file
461
475
// with the `.cpp` file.
462
476
return FileBuildSettings (
463
- compilerArguments: try await compilerArguments ( for: substituteFile, in: buildTarget) ,
477
+ compilerArguments: try await compilerArguments ( for: DocumentURI ( substituteFile) , in: buildTarget) ,
464
478
workingDirectory: workspacePath. pathString
465
479
) . patching ( newFile: try resolveSymlinks ( path) . pathString, originalFile: substituteFile. absoluteString)
466
480
}
467
481
468
482
return FileBuildSettings (
469
- compilerArguments: try await compilerArguments ( for: url , in: buildTarget) ,
483
+ compilerArguments: try await compilerArguments ( for: uri , in: buildTarget) ,
470
484
workingDirectory: workspacePath. pathString
471
485
)
472
486
}
@@ -483,7 +497,7 @@ extension SwiftPMBuildSystem: SKCore.BuildSystem {
483
497
return [ ]
484
498
}
485
499
486
- if let target = try ? buildTarget ( for: path ) {
500
+ if let target = buildTarget ( for: uri ) {
487
501
return [ ConfiguredTarget ( target) ]
488
502
}
489
503
@@ -655,13 +669,15 @@ extension SwiftPMBuildSystem: SKCore.BuildSystem {
655
669
}
656
670
657
671
/// Returns the resolved target description for the given file, if one is known.
658
- private func buildTarget( for file: AbsolutePath ) throws -> SwiftBuildTarget ? {
672
+ private func buildTarget( for file: DocumentURI ) -> SwiftBuildTarget ? {
659
673
if let td = fileToTarget [ file] {
660
674
return td
661
675
}
662
676
663
- let realpath = try resolveSymlinks ( file)
664
- if realpath != file, let td = fileToTarget [ realpath] {
677
+ if let fileURL = file. fileURL,
678
+ let realpath = try ? resolveSymlinks ( AbsolutePath ( validating: fileURL. path) ) ,
679
+ let td = fileToTarget [ DocumentURI ( realpath. asURL) ]
680
+ {
665
681
fileToTarget [ file] = td
666
682
return td
667
683
}
@@ -704,11 +720,7 @@ extension SwiftPMBuildSystem: SKCore.BuildSystem {
704
720
// If a Swift file within a target is updated, reload all the other files within the target since they might be
705
721
// referring to a function in the updated file.
706
722
for event in events {
707
- guard let url = event. uri. fileURL,
708
- url. pathExtension == " swift " ,
709
- let absolutePath = try ? AbsolutePath ( validating: url. path) ,
710
- let target = fileToTarget [ absolutePath]
711
- else {
723
+ guard event. uri. fileURL? . pathExtension == " swift " , let target = fileToTarget [ event. uri] else {
712
724
continue
713
725
}
714
726
filesWithUpdatedDependencies. formUnion ( target. sources. map { DocumentURI ( $0) } )
@@ -724,7 +736,7 @@ extension SwiftPMBuildSystem: SKCore.BuildSystem {
724
736
// If we have background indexing enabled, this is not necessary because we call `fileDependenciesUpdated` when
725
737
// preparation of a target finishes.
726
738
if !isForIndexBuild, events. contains ( where: { $0. uri. fileURL? . pathExtension == " swiftmodule " } ) {
727
- filesWithUpdatedDependencies. formUnion ( self . fileToTarget. keys. map { DocumentURI ( $0 . asURL ) } )
739
+ filesWithUpdatedDependencies. formUnion ( self . fileToTarget. keys)
728
740
}
729
741
await self . fileDependenciesUpdatedDebouncer. scheduleCall ( filesWithUpdatedDependencies)
730
742
}
@@ -737,11 +749,11 @@ extension SwiftPMBuildSystem: SKCore.BuildSystem {
737
749
}
738
750
739
751
public func sourceFiles( ) -> [ SourceFileInfo ] {
740
- return fileToTarget. compactMap { ( path , target) -> SourceFileInfo ? in
752
+ return fileToTarget. compactMap { ( uri , target) -> SourceFileInfo ? in
741
753
// We should only set mayContainTests to `true` for files from test targets
742
754
// (https://github.com/apple/sourcekit-lsp/issues/1174).
743
755
return SourceFileInfo (
744
- uri: DocumentURI ( path . asURL ) ,
756
+ uri: uri ,
745
757
isPartOfRootProject: target. isPartOfRootPackage,
746
758
mayContainTests: true
747
759
)
@@ -782,7 +794,7 @@ extension SwiftPMBuildSystem {
782
794
func impl( _ path: AbsolutePath ) throws -> ConfiguredTarget ? {
783
795
var dir = path. parentDirectory
784
796
while !dir. isRoot {
785
- if let buildTarget = sourceDirToTarget [ dir] {
797
+ if let buildTarget = sourceDirToTarget [ DocumentURI ( dir. asURL ) ] {
786
798
return ConfiguredTarget ( buildTarget)
787
799
}
788
800
dir = dir. parentDirectory
0 commit comments