diff options
| author | Yong He <yonghe@outlook.com> | 2022-06-07 14:10:49 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-07 14:10:49 -0700 |
| commit | 0c64995ea28febcc7d38e1519da8d93391ce2e7d (patch) | |
| tree | 8696ab86b29caf80c3ebbd205c700e24b8c20bf3 /source/slang/slang-workspace-version.h | |
| parent | 8c4a15c522861d2f30eacc9cd2b03ad793018639 (diff) | |
Major language server features. (#2264)
* Major language server features.
* Include slangd in binary release.
* Fix compiler issues.
* Fix compiler error.
* Completion resolve.
* Various improvements.
* Update diagnostic test expected output.
* Bug fix for source locations.
* Adjust diagnostic update frequency.
* Update github actions to store artifacts.
* Fix infinite parser loop.
* Fix parser recovery.
* Fix parser recovery.
* Update test.
* Fix test.
* Disable IR gen for language server.
* Allow commit characters in auto completion.
* Fix lookup for invoke exprs.
* More parser robustness fixes.
* update solution file
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-workspace-version.h')
| -rw-r--r-- | source/slang/slang-workspace-version.h | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/source/slang/slang-workspace-version.h b/source/slang/slang-workspace-version.h new file mode 100644 index 000000000..3dcd3d9ce --- /dev/null +++ b/source/slang/slang-workspace-version.h @@ -0,0 +1,135 @@ +#pragma once + +#include "../../slang-com-helper.h" +#include "../../slang-com-ptr.h" +#include "../../slang.h" +#include "../core/slang-basic.h" +#include "../core/slang-com-object.h" +#include "slang-language-server-protocol.h" +#include "slang-compiler.h" +#include "slang-doc-ast.h" + +namespace Slang +{ + struct URI + { + String uri; + bool operator==(const URI& other) const + { + return uri == other.uri; + } + bool operator!=(const URI& other) const { return uri != other.uri; } + + HashCode getHashCode() const { return uri.getHashCode(); } + + bool isLocalFile() { return uri.startsWith("file://"); }; + String getPath() const; + StringSlice getProtocol() const { return uri.subString(0, uri.indexOf("://")); } + + static URI fromLocalFilePath(UnownedStringSlice path); + static URI fromString(UnownedStringSlice uriString); + static bool isSafeURIChar(char ch); + }; + + class Workspace; + + class DocumentVersion : public RefObject + { + private: + URI uri; + String text; + List<Int> lineBreaks; + public: + void setURI(URI newURI) + { + uri = newURI; + } + URI getURI() { return uri; } + const String& getText() { return text; } + void setText(const String& newText); + Index getOffset(Index lineIndex, Index colIndex) + { + if(lineIndex < 0) return -1; + if (lineIndex - 1 >= lineBreaks.getCount()) + return -1; + if (lineBreaks.getCount() == 0) + return -1; + + Index lineStart = lineIndex >= 2 ? lineBreaks[lineIndex - 2] : 0; + return lineStart + colIndex - 1; + } + void offsetToLineCol(Index offset, Index& line, Index& col) + { + auto firstGreater = std::upper_bound(lineBreaks.begin(), lineBreaks.end(), offset); + line = Index(firstGreater - lineBreaks.begin() + 1); + if (firstGreater == lineBreaks.begin()) + { + col = offset + 1; + } + else + { + col = Index(offset - *(firstGreater - 1)); + } + } + UnownedStringSlice getLine(Index lineIndex) + { + if (lineIndex < 0) + return UnownedStringSlice(); + if (lineIndex - 1 >= lineBreaks.getCount()) + return UnownedStringSlice(); + if (lineBreaks.getCount() == 0) + return UnownedStringSlice(); + + Int lineStart = lineIndex >= 2 ? lineBreaks[lineIndex - 2] : 0; + Int lineEnd = lineBreaks[lineIndex - 1]; + return text.getUnownedSlice().subString(lineStart, lineEnd); + } + }; + + struct DocumentDiagnostics + { + OrderedHashSet<LanguageServerProtocol::Diagnostic> messages; + String originalOutput; + }; + + class WorkspaceVersion : public RefObject + { + private: + Dictionary<String, Module*> modules; + Dictionary<ModuleDecl*, RefPtr<ASTMarkup>> markupASTs; + public: + Workspace* workspace; + RefPtr<Linkage> linkage; + Dictionary<String, DocumentDiagnostics> diagnostics; + List<Decl*> currentCompletionItems; + ASTMarkup* getOrCreateMarkupAST(ModuleDecl* module); + + Module* getOrLoadModule(String path); + }; + + class Workspace + : public ISlangFileSystem + , public ComObject + { + private: + RefPtr<WorkspaceVersion> currentVersion; + RefPtr<WorkspaceVersion> createWorkspaceVersion(); + public: + List<String> rootDirectories; + OrderedHashSet<String> searchPaths; + + slang::IGlobalSession* slangGlobalSession; + Dictionary<String, RefPtr<DocumentVersion>> openedDocuments; + DocumentVersion* openDoc(String path, String text); + void init(List<URI> rootDirURI, slang::IGlobalSession* globalSession); + void invalidate(); + WorkspaceVersion* getCurrentVersion(); + + public: + // Inherited via ISlangFileSystem + SLANG_COM_OBJECT_IUNKNOWN_ALL + void* getInterface(const Guid& uuid); + virtual SLANG_NO_THROW SlangResult SLANG_MCALL + loadFile(const char* path, ISlangBlob** outBlob) override; + }; +} // namespace LanguageServerProtocol |
