@@ -77,11 +77,15 @@ struct InvocationOptions {
77
77
const std::string PrimaryFile;
78
78
const CompilerInvocation Invok;
79
79
80
+ // / If defined, all filesystem operations resulting from this invocation
81
+ // / should use this filesystem instead of the real filesystem.
82
+ const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem;
83
+
80
84
InvocationOptions (ArrayRef<const char *> CArgs, StringRef PrimaryFile,
81
- CompilerInvocation Invok)
82
- : Args(_convertArgs(CArgs)),
83
- PrimaryFile (PrimaryFile),
84
- Invok(std::move(Invok)) {
85
+ CompilerInvocation Invok,
86
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem)
87
+ : Args(_convertArgs(CArgs)), PrimaryFile(PrimaryFile),
88
+ Invok (std::move(Invok)), FileSystem(FileSystem ) {
85
89
// Assert invocation with a primary file. We want to avoid full typechecking
86
90
// for all files.
87
91
assert (!this ->PrimaryFile .empty ());
@@ -163,6 +167,7 @@ void InvocationOptions::profile(llvm::FoldingSetNodeID &ID) const {
163
167
for (auto &Arg : Args)
164
168
ID.AddString (Arg);
165
169
ID.AddString (PrimaryFile);
170
+ ID.AddPointer (FileSystem.get ());
166
171
}
167
172
168
173
// ===----------------------------------------------------------------------===//
@@ -373,11 +378,15 @@ struct SwiftASTManager::Implementation {
373
378
" sourcekit.swift.ASTBuilding" };
374
379
375
380
ASTProducerRef getASTProducer (SwiftInvocationRef InvokRef);
376
- FileContent getFileContent (StringRef FilePath, bool IsPrimary,
377
- std::string &Error);
378
- BufferStamp getBufferStamp (StringRef FilePath);
379
- std::unique_ptr<llvm::MemoryBuffer> getMemoryBuffer (StringRef Filename,
380
- std::string &Error);
381
+ FileContent
382
+ getFileContent (StringRef FilePath, bool IsPrimary, std::string &Error,
383
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem);
384
+ BufferStamp
385
+ getBufferStamp (StringRef FilePath,
386
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem);
387
+ std::unique_ptr<llvm::MemoryBuffer> getMemoryBuffer (
388
+ StringRef Filename, std::string &Error,
389
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem = nullptr );
381
390
};
382
391
383
392
SwiftASTManager::SwiftASTManager (
@@ -541,17 +550,17 @@ bool SwiftASTManager::initCompilerInvocationNoInputs(
541
550
return false ;
542
551
}
543
552
544
- SwiftInvocationRef
545
- SwiftASTManager::getInvocation (ArrayRef<const char *> OrigArgs,
546
- StringRef PrimaryFile,
547
- std::string &Error) {
553
+ SwiftInvocationRef SwiftASTManager::getInvocation (
554
+ ArrayRef<const char *> OrigArgs, StringRef PrimaryFile, std::string &Error,
555
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem) {
548
556
549
557
DiagnosticEngine Diags (Impl.SourceMgr );
550
558
EditorDiagConsumer CollectDiagConsumer;
551
559
Diags.addConsumer (CollectDiagConsumer);
552
560
553
561
CompilerInvocation CompInvok;
554
- if (initCompilerInvocation (CompInvok, OrigArgs, Diags, PrimaryFile, Error)) {
562
+ if (initCompilerInvocation (CompInvok, OrigArgs, Diags, PrimaryFile, Error,
563
+ FileSystem)) {
555
564
// We create a traced operation here to represent the failure to parse
556
565
// arguments since we cannot reach `createAST` where that would normally
557
566
// happen.
@@ -568,7 +577,7 @@ SwiftASTManager::getInvocation(ArrayRef<const char *> OrigArgs,
568
577
return nullptr ;
569
578
}
570
579
571
- InvocationOptions Opts (OrigArgs, PrimaryFile, CompInvok);
580
+ InvocationOptions Opts (OrigArgs, PrimaryFile, CompInvok, FileSystem );
572
581
return new SwiftInvocation (
573
582
*new SwiftInvocation::Implementation (std::move (Opts)));
574
583
}
@@ -634,38 +643,45 @@ static FileContent getFileContentFromSnap(ImmutableTextSnapshotRef Snap,
634
643
}
635
644
636
645
FileContent SwiftASTManager::Implementation::getFileContent (
637
- StringRef UnresolvedPath, bool IsPrimary, std::string &Error) {
646
+ StringRef UnresolvedPath, bool IsPrimary, std::string &Error,
647
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem) {
638
648
std::string FilePath = SwiftLangSupport::resolvePathSymlinks (UnresolvedPath);
639
649
if (auto EditorDoc = EditorDocs->findByPath (FilePath))
640
650
return getFileContentFromSnap (EditorDoc->getLatestSnapshot (), IsPrimary,
641
651
FilePath);
642
652
643
653
// FIXME: Is there a way to get timestamp and buffer for a file atomically ?
644
- auto Stamp = getBufferStamp (FilePath);
645
- auto Buffer = getMemoryBuffer (FilePath, Error);
654
+ auto Stamp = getBufferStamp (FilePath, FileSystem );
655
+ auto Buffer = getMemoryBuffer (FilePath, Error, FileSystem );
646
656
return FileContent (nullptr , UnresolvedPath, std::move (Buffer), IsPrimary,
647
657
Stamp);
648
658
}
649
659
650
- BufferStamp SwiftASTManager::Implementation::getBufferStamp (StringRef FilePath){
660
+ BufferStamp SwiftASTManager::Implementation::getBufferStamp (
661
+ StringRef FilePath,
662
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem) {
651
663
if (auto EditorDoc = EditorDocs->findByPath (FilePath))
652
664
return EditorDoc->getLatestSnapshot ()->getStamp ();
653
665
654
- llvm::sys::fs::file_status Status;
655
- if (std::error_code Ret = llvm::sys::fs::status (FilePath, Status)) {
666
+ auto StatusOrErr = FileSystem
667
+ ? FileSystem->status (FilePath)
668
+ : llvm::vfs::getRealFileSystem ()->status (FilePath);
669
+ if (std::error_code Err = StatusOrErr.getError ()) {
656
670
// Failure to read the file.
657
- LOG_WARN_FUNC (" failed to stat file: " << FilePath
658
- << " ( " << Ret. message () << ' )' );
671
+ LOG_WARN_FUNC (" failed to stat file: " << FilePath << " ( " << Err. message ()
672
+ << ' )' );
659
673
return -1 ;
660
674
}
661
- return Status .getLastModificationTime ().time_since_epoch ().count ();
675
+ return StatusOrErr. get () .getLastModificationTime ().time_since_epoch ().count ();
662
676
}
663
677
664
678
std::unique_ptr<llvm::MemoryBuffer>
665
- SwiftASTManager::Implementation::getMemoryBuffer (StringRef Filename,
666
- std::string &Error) {
679
+ SwiftASTManager::Implementation::getMemoryBuffer (
680
+ StringRef Filename, std::string &Error,
681
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem) {
667
682
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
668
- llvm::MemoryBuffer::getFile (Filename);
683
+ FileSystem ? FileSystem->getBufferForFile (Filename)
684
+ : llvm::vfs::getRealFileSystem ()->getBufferForFile (Filename);
669
685
if (FileBufOrErr)
670
686
return std::move (FileBufOrErr.get ());
671
687
@@ -780,15 +796,17 @@ bool ASTProducer::shouldRebuild(SwiftASTManager::Implementation &MgrImpl,
780
796
}
781
797
}
782
798
if (!FoundSnapshot)
783
- InputStamps.push_back (MgrImpl.getBufferStamp (File));
799
+ InputStamps.push_back (
800
+ MgrImpl.getBufferStamp (File, Invok.Opts .FileSystem ));
784
801
}
785
802
assert (InputStamps.size () ==
786
803
Invok.Opts .Invok .getFrontendOptions ().InputsAndOutputs .inputCount ());
787
804
if (Stamps != InputStamps)
788
805
return true ;
789
806
790
807
for (auto &Dependency : DependencyStamps) {
791
- if (Dependency.second != MgrImpl.getBufferStamp (Dependency.first ))
808
+ if (Dependency.second !=
809
+ MgrImpl.getBufferStamp (Dependency.first , Invok.Opts .FileSystem ))
792
810
return true ;
793
811
}
794
812
@@ -895,7 +913,7 @@ ASTUnitRef ASTProducer::createASTUnit(SwiftASTManager::Implementation &MgrImpl,
895
913
896
914
Invocation.getLangOptions ().CollectParsedToken = true ;
897
915
898
- if (CompIns.setup (Invocation)) {
916
+ if (CompIns.setup (Invocation, InvokRef-> Impl . Opts . FileSystem )) {
899
917
// FIXME: Report the diagnostic.
900
918
LOG_WARN_FUNC (" Compilation setup failed!!!" );
901
919
Error = " compilation setup failed" ;
@@ -917,8 +935,9 @@ ASTUnitRef ASTProducer::createASTUnit(SwiftASTManager::Implementation &MgrImpl,
917
935
// FIXME: There exists a small window where the module file may have been
918
936
// modified after compilation finished and before we get its stamp.
919
937
for (auto &Filename : Filenames) {
920
- DependencyStamps.push_back (std::make_pair (Filename,
921
- MgrImpl.getBufferStamp (Filename)));
938
+ DependencyStamps.push_back (std::make_pair (
939
+ Filename,
940
+ MgrImpl.getBufferStamp (Filename, InvokRef->Impl .Opts .FileSystem )));
922
941
}
923
942
924
943
// Since we only typecheck the primary file (plus referenced constructs
@@ -970,7 +989,8 @@ void ASTProducer::findSnapshotAndOpenFiles(
970
989
if (FoundSnapshot)
971
990
continue ;
972
991
973
- auto Content = MgrImpl.getFileContent (File, IsPrimary, Error);
992
+ auto Content =
993
+ MgrImpl.getFileContent (File, IsPrimary, Error, Opts.FileSystem );
974
994
if (!Content.Buffer ) {
975
995
LOG_WARN_FUNC (" failed getting file contents for " << File << " : "
976
996
<< Error);
0 commit comments