@@ -88,6 +88,8 @@ struct InvocationOptions {
88
88
}
89
89
90
90
void applyTo (CompilerInvocation &CompInvok) const ;
91
+ void applyToSubstitutingInputs (CompilerInvocation &CompInvok,
92
+ FrontendInputs &&Inputs) const ;
91
93
void profile (llvm::FoldingSetNodeID &ID) const ;
92
94
void raw (std::vector<std::string> &Args, std::string &PrimaryFile) const ;
93
95
@@ -132,6 +134,11 @@ void SwiftInvocation::raw(std::vector<std::string> &Args,
132
134
void InvocationOptions::applyTo (CompilerInvocation &CompInvok) const {
133
135
CompInvok = this ->Invok ;
134
136
}
137
+ void InvocationOptions::applyToSubstitutingInputs (
138
+ CompilerInvocation &CompInvok, FrontendInputs &&inputs) const {
139
+ CompInvok = this ->Invok ;
140
+ CompInvok.getFrontendOptions ().Inputs = inputs;
141
+ }
135
142
136
143
void InvocationOptions::raw (std::vector<std::string> &Args,
137
144
std::string &PrimaryFile) const {
@@ -231,15 +238,20 @@ typedef uint64_t BufferStamp;
231
238
232
239
struct FileContent {
233
240
ImmutableTextSnapshotRef Snapshot;
241
+ std::string Filename;
234
242
std::unique_ptr<llvm::MemoryBuffer> Buffer;
243
+ bool IsPrimary;
235
244
BufferStamp Stamp;
236
245
237
- FileContent (ImmutableTextSnapshotRef Snapshot,
238
- std::unique_ptr<llvm::MemoryBuffer> Buffer,
246
+ FileContent (ImmutableTextSnapshotRef Snapshot, std::string Filename,
247
+ std::unique_ptr<llvm::MemoryBuffer> Buffer, bool IsPrimary,
239
248
BufferStamp Stamp)
240
- : Snapshot(std::move(Snapshot)),
241
- Buffer (std::move(Buffer)),
242
- Stamp(Stamp) {}
249
+ : Snapshot(std::move(Snapshot)), Filename(Filename),
250
+ Buffer (std::move(Buffer)), IsPrimary(IsPrimary), Stamp(Stamp) {}
251
+
252
+ explicit operator InputFile () const {
253
+ return InputFile (Filename, IsPrimary, Buffer.get ());
254
+ }
243
255
};
244
256
245
257
class ASTProducer : public ThreadSafeRefCountedBase <ASTProducer> {
@@ -284,6 +296,11 @@ class ASTProducer : public ThreadSafeRefCountedBase<ASTProducer> {
284
296
ASTUnitRef createASTUnit (SwiftASTManager::Implementation &MgrImpl,
285
297
ArrayRef<ImmutableTextSnapshotRef> Snapshots,
286
298
std::string &Error);
299
+
300
+ void findSnapshotAndOpenFiles (SwiftASTManager::Implementation &MgrImpl,
301
+ ArrayRef<ImmutableTextSnapshotRef> Snapshots,
302
+ SmallVectorImpl<FileContent> &Contents,
303
+ std::string &Error) const ;
287
304
};
288
305
289
306
typedef IntrusiveRefCntPtr<ASTProducer> ASTProducerRef;
@@ -330,7 +347,8 @@ struct SwiftASTManager::Implementation {
330
347
" sourcekit.swift.ASTBuilding" };
331
348
332
349
ASTProducerRef getASTProducer (SwiftInvocationRef InvokRef);
333
- FileContent getFileContent (StringRef FilePath, std::string &Error);
350
+ FileContent getFileContent (StringRef FilePath, bool IsPrimary,
351
+ std::string &Error);
334
352
BufferStamp getBufferStamp (StringRef FilePath);
335
353
std::unique_ptr<llvm::MemoryBuffer> getMemoryBuffer (StringRef Filename,
336
354
std::string &Error);
@@ -391,6 +409,14 @@ static void sanitizeCompilerArgs(ArrayRef<const char *> Args,
391
409
}
392
410
}
393
411
412
+ static FrontendInputs
413
+ convertFileContentsToInputs (const SmallVectorImpl<FileContent> &contents) {
414
+ FrontendInputs inputs;
415
+ for (const FileContent &content : contents)
416
+ inputs.addInput (InputFile (content));
417
+ return inputs;
418
+ }
419
+
394
420
static FrontendInputs
395
421
resolveSymbolicLinksInInputs (FrontendInputs &inputs,
396
422
StringRef UnresolvedPrimaryFile,
@@ -547,23 +573,25 @@ SwiftASTManager::Implementation::getASTProducer(SwiftInvocationRef InvokRef) {
547
573
}
548
574
549
575
static FileContent getFileContentFromSnap (ImmutableTextSnapshotRef Snap,
550
- StringRef FilePath) {
576
+ bool IsPrimary, StringRef FilePath) {
551
577
auto Buf = llvm::MemoryBuffer::getMemBufferCopy (
552
578
Snap->getBuffer ()->getText (), FilePath);
553
- return FileContent (Snap, std::move (Buf), Snap->getStamp ());
579
+ return FileContent (Snap, FilePath, std::move (Buf), IsPrimary,
580
+ Snap->getStamp ());
554
581
}
555
582
556
- FileContent
557
- SwiftASTManager::Implementation::getFileContent (StringRef UnresolvedPath,
558
- std::string &Error) {
583
+ FileContent SwiftASTManager::Implementation::getFileContent (
584
+ StringRef UnresolvedPath, bool IsPrimary, std::string &Error) {
559
585
std::string FilePath = SwiftLangSupport::resolvePathSymlinks (UnresolvedPath);
560
586
if (auto EditorDoc = EditorDocs.findByPath (FilePath))
561
- return getFileContentFromSnap (EditorDoc->getLatestSnapshot (), FilePath);
587
+ return getFileContentFromSnap (EditorDoc->getLatestSnapshot (), IsPrimary,
588
+ FilePath);
562
589
563
590
// FIXME: Is there a way to get timestamp and buffer for a file atomically ?
564
591
auto Stamp = getBufferStamp (FilePath);
565
592
auto Buffer = getMemoryBuffer (FilePath, Error);
566
- return FileContent (nullptr , std::move (Buffer), Stamp);
593
+ return FileContent (nullptr , UnresolvedPath, std::move (Buffer), IsPrimary,
594
+ Stamp);
567
595
}
568
596
569
597
BufferStamp SwiftASTManager::Implementation::getBufferStamp (StringRef FilePath){
@@ -766,44 +794,17 @@ ASTUnitRef ASTProducer::createASTUnit(SwiftASTManager::Implementation &MgrImpl,
766
794
Stamps.clear ();
767
795
DependencyStamps.clear ();
768
796
769
- const InvocationOptions &Opts = InvokRef->Impl .Opts ;
770
-
771
797
SmallVector<FileContent, 8 > Contents;
772
- for (const auto &input :
773
- Opts.Invok .getFrontendOptions ().Inputs .getAllFiles ()) {
774
- StringRef File = input.file ();
775
- if (File.empty ())
776
- continue ;
777
- bool FoundSnapshot = false ;
778
- for (auto &Snap : Snapshots) {
779
- if (Snap->getFilename () == File) {
780
- FoundSnapshot = true ;
781
- Contents.push_back (getFileContentFromSnap (Snap, File));
782
- break ;
783
- }
784
- }
785
- if (FoundSnapshot)
786
- break ;
787
-
788
- auto Content = MgrImpl.getFileContent (File, Error);
789
- if (!Content.Buffer ) {
790
- LOG_WARN_FUNC (" failed getting file contents for " << File << " : " << Error);
791
- // File may not exist, continue and recover as if it was empty.
792
- Content.Buffer = llvm::MemoryBuffer::getNewMemBuffer (0 , File);
793
- }
794
- Contents.push_back (std::move (Content));
795
- }
796
- assert (Contents.size () ==
797
- Opts.Invok .getFrontendOptions ().Inputs .inputCount ());
798
+ findSnapshotAndOpenFiles (MgrImpl, Snapshots, Contents, Error);
798
799
799
800
for (auto &Content : Contents)
800
801
Stamps.push_back (Content.Stamp );
801
802
802
803
trace::SwiftInvocation TraceInfo;
803
804
804
805
if (trace::enabled ()) {
805
- TraceInfo.Args .PrimaryFile = Opts.PrimaryFile ;
806
- TraceInfo.Args .Args = Opts.Args ;
806
+ TraceInfo.Args .PrimaryFile = InvokRef-> Impl . Opts .PrimaryFile ;
807
+ TraceInfo.Args .Args = InvokRef-> Impl . Opts .Args ;
807
808
}
808
809
809
810
ASTUnitRef ASTRef = new ASTUnit (++ASTUnitGeneration, MgrImpl.Stats );
@@ -814,7 +815,6 @@ ASTUnitRef ASTProducer::createASTUnit(SwiftASTManager::Implementation &MgrImpl,
814
815
if (trace::enabled ()) {
815
816
TraceInfo.addFile (Content.Buffer ->getBufferIdentifier (),
816
817
Content.Buffer ->getBuffer ());
817
-
818
818
}
819
819
}
820
820
auto &CompIns = ASTRef->Impl .CompInst ;
@@ -824,12 +824,10 @@ ASTUnitRef ASTProducer::createASTUnit(SwiftASTManager::Implementation &MgrImpl,
824
824
CompIns.addDiagnosticConsumer (&Consumer);
825
825
826
826
CompilerInvocation Invocation;
827
- Opts.applyTo (Invocation);
827
+ InvokRef->Impl .Opts .applyToSubstitutingInputs (
828
+ Invocation, convertFileContentsToInputs (Contents));
829
+
828
830
Invocation.getLangOptions ().KeepSyntaxInfoInSourceFile = true ;
829
- for (auto i : indices (Contents)) {
830
- Invocation.getFrontendOptions ().Inputs .setBuffer (Contents[i].Buffer .get (),
831
- i);
832
- }
833
831
834
832
if (CompIns.setup (Invocation)) {
835
833
// FIXME: Report the diagnostic.
@@ -891,3 +889,36 @@ ASTUnitRef ASTProducer::createASTUnit(SwiftASTManager::Implementation &MgrImpl,
891
889
892
890
return ASTRef;
893
891
}
892
+
893
+ void ASTProducer::findSnapshotAndOpenFiles (
894
+ SwiftASTManager::Implementation &MgrImpl,
895
+ ArrayRef<ImmutableTextSnapshotRef> Snapshots,
896
+ SmallVectorImpl<FileContent> &Contents, std::string &Error) const {
897
+ const InvocationOptions &Opts = InvokRef->Impl .Opts ;
898
+ for (const auto &input :
899
+ Opts.Invok .getFrontendOptions ().Inputs .getAllFiles ()) {
900
+ StringRef File = input.file ();
901
+ bool IsPrimary = input.isPrimary ();
902
+ bool FoundSnapshot = false ;
903
+ for (auto &Snap : Snapshots) {
904
+ if (Snap->getFilename () == File) {
905
+ FoundSnapshot = true ;
906
+ Contents.push_back (getFileContentFromSnap (Snap, IsPrimary, File));
907
+ break ;
908
+ }
909
+ }
910
+ if (FoundSnapshot)
911
+ continue ;
912
+
913
+ auto Content = MgrImpl.getFileContent (File, IsPrimary, Error);
914
+ if (!Content.Buffer ) {
915
+ LOG_WARN_FUNC (" failed getting file contents for " << File << " : "
916
+ << Error);
917
+ // File may not exist, continue and recover as if it was empty.
918
+ Content.Buffer = llvm::MemoryBuffer::getNewMemBuffer (0 , File);
919
+ }
920
+ Contents.push_back (std::move (Content));
921
+ }
922
+ assert (Contents.size () ==
923
+ Opts.Invok .getFrontendOptions ().Inputs .inputCount ());
924
+ }
0 commit comments