Move storage for VFS into editor document

The invocation options are not an appropriate place to put this state,
since it can change between requests. This moves it to the editor
document, allowing us to change the specific VFS instance without
causing a rebuild (unless the contents/timestamps for a dependency
change).
This commit is contained in:
Ben Langmuir
2019-06-25 14:27:56 -07:00
committed by Marc Rasi
parent 78a7d95f07
commit 205371c886
9 changed files with 205 additions and 132 deletions

View File

@@ -601,6 +601,7 @@ class SwiftDocumentSemanticInfo :
std::weak_ptr<SwiftASTManager> ASTMgr;
std::shared_ptr<NotificationCenter> NotificationCtr;
ThreadSafeRefCntPtr<SwiftInvocation> InvokRef;
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fileSystem;
std::string CompilerArgsError;
uint64_t ASTGeneration = 0;
@@ -613,15 +614,21 @@ class SwiftDocumentSemanticInfo :
mutable llvm::sys::Mutex Mtx;
public:
SwiftDocumentSemanticInfo(StringRef Filename,
std::weak_ptr<SwiftASTManager> ASTMgr,
std::shared_ptr<NotificationCenter> NotificationCtr)
: Filename(Filename), ASTMgr(ASTMgr), NotificationCtr(NotificationCtr) {}
SwiftDocumentSemanticInfo(
StringRef Filename, std::weak_ptr<SwiftASTManager> ASTMgr,
std::shared_ptr<NotificationCenter> NotificationCtr,
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fileSystem)
: Filename(Filename), ASTMgr(ASTMgr), NotificationCtr(NotificationCtr),
fileSystem(fileSystem) {}
SwiftInvocationRef getInvocation() const {
return InvokRef;
}
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> getFileSystem() const {
return fileSystem;
}
uint64_t getASTGeneration() const;
void
@@ -1039,7 +1046,8 @@ void SwiftDocumentSemanticInfo::processLatestSnapshotAsync(
// SwiftDocumentSemanticInfo pointer so use that for the token.
const void *OncePerASTToken = SemaInfoRef.get();
if (auto ASTMgr = this->ASTMgr.lock()) {
ASTMgr->processASTAsync(Invok, std::move(Consumer), OncePerASTToken);
ASTMgr->processASTAsync(Invok, std::move(Consumer), OncePerASTToken,
fileSystem);
}
}
@@ -1077,8 +1085,11 @@ struct SwiftEditorDocument::Implementation {
: ASTMgr(LangSupport.getASTManager()),
NotificationCtr(LangSupport.getNotificationCenter()),
FilePath(FilePath), FormatOptions(options) {
SemanticInfo =
new SwiftDocumentSemanticInfo(FilePath, ASTMgr, NotificationCtr);
// This instance of semantic info is used if a document is opened with
// `key.syntactic_only: 1`, but subsequently a semantic request such as
// cursor_info is made.
SemanticInfo = new SwiftDocumentSemanticInfo(
FilePath, ASTMgr, NotificationCtr, llvm::vfs::getRealFileSystem());
}
};
@@ -1723,8 +1734,8 @@ ImmutableTextSnapshotRef SwiftEditorDocument::initializeText(
// Try to create a compiler invocation object if needing semantic info
// or it's syntactic-only but with passed-in compiler arguments.
if (ProvideSemanticInfo || !Args.empty()) {
Impl.SemanticInfo = new SwiftDocumentSemanticInfo(Impl.FilePath, Impl.ASTMgr,
Impl.NotificationCtr);
Impl.SemanticInfo = new SwiftDocumentSemanticInfo(
Impl.FilePath, Impl.ASTMgr, Impl.NotificationCtr, FileSystem);
Impl.SemanticInfo->setCompilerArgs(Args, FileSystem);
}
return Impl.EditableBuffer->getSnapshot();
@@ -1953,6 +1964,13 @@ bool SwiftEditorDocument::hasUpToDateAST() const {
return Impl.SyntaxInfo->hasUpToDateAST();
}
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
SwiftEditorDocument::getFileSystem() const {
llvm::sys::ScopedLock L(Impl.AccessMtx);
return Impl.SemanticInfo ? Impl.SemanticInfo->getFileSystem()
: llvm::vfs::getRealFileSystem();
}
void SwiftEditorDocument::formatText(unsigned Line, unsigned Length,
EditorConsumer &Consumer) {
auto SyntaxInfo = Impl.getSyntaxInfo();
@@ -2127,7 +2145,9 @@ void SwiftLangSupport::editorOpen(
ArrayRef<const char *> Args, Optional<VFSOptions> vfsOptions) {
std::string error;
auto fileSystem = getFileSystem(vfsOptions, error);
// Do not provide primaryFile so that opening an existing document will
// reinitialize the filesystem instead of keeping the old one.
auto fileSystem = getFileSystem(vfsOptions, /*primaryFile=*/None, error);
if (!fileSystem)
return Consumer.handleRequestError(error.c_str());