summaryrefslogtreecommitdiff
path: root/source/slang/slang-workspace-version.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-06-22 19:58:34 -0700
committerGitHub <noreply@github.com>2022-06-22 19:58:34 -0700
commit07a380d72a13899a84cbdc35692be7a3d9246dcb (patch)
tree68e77f2e9682b3b7c3debd745604a494439e5b25 /source/slang/slang-workspace-version.cpp
parente5a75563a1ba2e378353af8b937b8b7bb0fe2c2b (diff)
More Language Server Improvements. (#2289)
Diffstat (limited to 'source/slang/slang-workspace-version.cpp')
-rw-r--r--source/slang/slang-workspace-version.cpp122
1 files changed, 55 insertions, 67 deletions
diff --git a/source/slang/slang-workspace-version.cpp b/source/slang/slang-workspace-version.cpp
index 781d8a3bc..0930ca0de 100644
--- a/source/slang/slang-workspace-version.cpp
+++ b/source/slang/slang-workspace-version.cpp
@@ -3,6 +3,8 @@
#include "../core/slang-file-system.h"
#include "../compiler-core/slang-lexer.h"
#include "slang-serialize-container.h"
+#include "slang-mangle.h"
+#include "slang-check-impl.h"
namespace Slang
{
@@ -30,10 +32,9 @@ DocumentVersion* Workspace::openDoc(String path, String text)
{
RefPtr<DocumentVersion> doc = new DocumentVersion();
doc->setText(text.getUnownedSlice());
- doc->setURI(URI::fromLocalFilePath(path.getUnownedSlice()));
+ doc->setPath(path);
openedDocuments[path] = doc;
workspaceSearchPaths.Add(Path::getParentDirectory(path));
- moduleCache.invalidate(path);
invalidate();
return doc.Ptr();
}
@@ -51,15 +52,18 @@ void Workspace::changeDoc(const String& path, LanguageServerProtocol::Range rang
auto originalText = doc->getText().getUnownedSlice();
StringBuilder newText;
newText << originalText.head(startOffset) << text << originalText.tail(endOffset);
- doc->setText(newText.ProduceString());
+ changeDoc(doc.Ptr(), newText.ProduceString());
}
- moduleCache.invalidate(path);
+}
+
+void Workspace::changeDoc(DocumentVersion* doc, const String& newText)
+{
+ doc->setText(newText);
invalidate();
}
void Workspace::closeDoc(const String& path)
{
- moduleCache.invalidate(path);
openedDocuments.Remove(path);
invalidate();
}
@@ -269,7 +273,6 @@ RefPtr<WorkspaceVersion> Workspace::createWorkspaceVersion()
slang::SessionDesc desc = {};
desc.fileSystem = this;
desc.targetCount = 1;
- desc.flags = slang::kSessionFlag_LanguageServer;
slang::TargetDesc targetDesc = {};
targetDesc.profile = slangGlobalSession->findProfile("sm_6_6");
desc.targets = &targetDesc;
@@ -308,13 +311,7 @@ RefPtr<WorkspaceVersion> Workspace::createWorkspaceVersion()
ComPtr<slang::ISession> session;
slangGlobalSession->createSession(desc, session.writeRef());
version->linkage = static_cast<Linkage*>(session.get());
- // TODO(yong): module cache does improves performance by 30%. However there are some issues
- // that prevents the deserialization to resolve the imported decls from the correct module.
- // This doesn't lead to crash, but may cause problems. We can enable this when the issues
- // are fixed.
-#if 0
- version->linkage->setModuleCache(&moduleCache);
-#endif
+ version->linkage->contentAssistInfo.checkingMode = ContentAssistCheckingMode::General;
return version;
}
@@ -337,7 +334,13 @@ WorkspaceVersion* Workspace::getCurrentVersion()
currentVersion = createWorkspaceVersion();
return currentVersion.Ptr();
}
-
+WorkspaceVersion* Workspace::createVersionForCompletion()
+{
+ currentCompletionVersion = createWorkspaceVersion();
+ currentCompletionVersion->linkage->contentAssistInfo.checkingMode =
+ ContentAssistCheckingMode::Completion;
+ return currentCompletionVersion.Ptr();
+}
void* Workspace::getInterface(const Guid& uuid)
{
if (uuid == ISlangUnknown::getTypeGuid() || uuid == ISlangFileSystem::getTypeGuid())
@@ -416,6 +419,21 @@ static bool _isIdentifierChar(char ch)
return ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9' || ch == '_';
}
+UnownedStringSlice DocumentVersion::peekIdentifier(Index& offset)
+{
+ Index start = offset;
+ Index end = offset;
+ while (start >= 0 && _isIdentifierChar(text[start]))
+ start--;
+ while (end < text.getLength() && _isIdentifierChar(text[end]))
+ end++;
+ offset = start + 1;
+ if (end > offset)
+ return text.getUnownedSlice().subString(start + 1, end - start - 1);
+ return UnownedStringSlice("");
+}
+
+
int DocumentVersion::getTokenLength(Index line, Index col)
{
auto offset = getOffset(line, col);
@@ -454,8 +472,19 @@ Module* WorkspaceVersion::getOrLoadModule(String path)
return nullptr;
ComPtr<ISlangBlob> diagnosticBlob;
RefPtr<StringBlob> sourceBlob = new StringBlob((*doc)->getText());
+ auto moduleName = getMangledNameFromNameString(path.getUnownedSlice());
+ linkage->contentAssistInfo.primaryModuleName = linkage->getNamePool()->getName(moduleName);
+ linkage->contentAssistInfo.primaryModulePath = path;
+ // Note:
+ // The module at `path` may have already been loaded into the linkage previously
+ // due to an `import`. However that module won't get fully checked in when the checker
+ // is in language server mode to speed things up.
+ // Therefore, we always call `loadModuleFromSource` to load a fresh module instead of
+ // trying to reuse the existing one through `findOrImportModule`, this will result in
+ // redundant parsing and storage, but it saves us from the hassle of handling
+ // incremental/lazy checking on a previously loaded module.
auto parsedModule = linkage->loadModuleFromSource(
- Path::getFileNameWithoutExt(path).getBuffer(),
+ moduleName.getBuffer(),
path.getBuffer(),
sourceBlob.Ptr(),
diagnosticBlob.writeRef());
@@ -474,63 +503,22 @@ Module* WorkspaceVersion::getOrLoadModule(String path)
return static_cast<Module*>(parsedModule);
}
-RefPtr<Module> SerializedModuleCache::tryLoadModule(
- Linkage* linkage, String filePath)
+MacroDefinitionContentAssistInfo* WorkspaceVersion::tryGetMacroDefinition(UnownedStringSlice name)
{
- Path::getCanonical(filePath, filePath);
- if (List<uint8_t>* rawData = serializedModules.TryGetValue(filePath))
+ if (macroDefinitions.Count() == 0)
{
- RefPtr<MemoryStreamBase> memStream =
- new MemoryStreamBase(FileAccess::Read, rawData->getBuffer(), rawData->getCount());
- RiffContainer riffContainer;
- RiffUtil::read(memStream.Ptr(), riffContainer);
- SerialContainerData outData;
- SerialContainerUtil::ReadOptions options;
- options.linkage = linkage;
- options.namePool = linkage->getNamePool();
- options.session = linkage->getSessionImpl();
- options.sharedASTBuilder = linkage->getASTBuilder()->getSharedASTBuilder();
- options.astBuilder = linkage->getASTBuilder();
- DiagnosticSink sink(linkage->getSourceManager(), Lexer::sourceLocationLexer);
- options.sink = &sink;
- options.sourceManager = linkage->getSourceManager();
- SLANG_RETURN_NULL_ON_FAIL(SerialContainerUtil::read(&riffContainer, options, outData));
- if (outData.modules.getCount() == 1)
+ // build dictionary.
+ for (auto& def : linkage->contentAssistInfo.preprocessorInfo.macroDefinitions)
{
- RefPtr<Module> module = new Module(linkage, linkage->getASTBuilder());
- auto moduleDecl = as<ModuleDecl>(outData.modules[0].astRootNode);
- if (moduleDecl)
- {
- moduleDecl->module = module.Ptr();
- module->setModuleDecl(moduleDecl);
- return module;
- }
+ macroDefinitions[def.name] = &def;
}
}
- return nullptr;
-}
-
-void SerializedModuleCache::storeModule(
- Linkage* linkage, String filePath, RefPtr<Module> module)
-{
- Path::getCanonical(filePath, filePath);
- RiffContainer container;
- SerialContainerUtil::WriteOptions options;
- options.sourceManager = linkage->getSourceManager();
- options.compressionType = SerialCompressionType::None;
- options.optionFlags = SerialOptionFlag::SourceLocation | SerialOptionFlag::ASTModule;
- SerialContainerData data;
- SerialContainerData::Module moduleData;
- moduleData.astBuilder = linkage->getASTBuilder();
- moduleData.astRootNode = module->getModuleDecl();
- moduleData.irModule = nullptr;
- data.modules.add(moduleData);
- SerialContainerUtil::write(data, options, &container);
- RefPtr<OwnedMemoryStream> memStream = new OwnedMemoryStream(FileAccess::Write);
- RiffUtil::write(&container, memStream);
- List<uint8_t> rawData;
- memStream->swapContents(rawData);
- serializedModules[filePath] = _Move(rawData);
+ MacroDefinitionContentAssistInfo* result = nullptr;
+ auto namePtr = linkage->getNamePool()->tryGetName(name);
+ if (!namePtr)
+ return nullptr;
+ macroDefinitions.TryGetValue(namePtr, result);
+ return result;
}
} // namespace Slang