summaryrefslogtreecommitdiff
path: root/source/slang/slang-language-server.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-10-27 14:27:52 -0700
committerGitHub <noreply@github.com>2024-10-27 14:27:52 -0700
commit1dd6ec26776081274604a94a96a1d87818830e82 (patch)
tree25b3a7d2df98cc152986b04725f61e69e1492b3a /source/slang/slang-language-server.cpp
parentfaa7d6ba4d73d8e3d89f083deea103afda456a21 (diff)
Export language server to wasm. (#5419)
Diffstat (limited to 'source/slang/slang-language-server.cpp')
-rw-r--r--source/slang/slang-language-server.cpp422
1 files changed, 262 insertions, 160 deletions
diff --git a/source/slang/slang-language-server.cpp b/source/slang/slang-language-server.cpp
index 94debde40..80d9c2ef8 100644
--- a/source/slang/slang-language-server.cpp
+++ b/source/slang/slang-language-server.cpp
@@ -30,6 +30,9 @@
#include "slang-mangle.h"
#include "../../tools/platform/performance-counter.h"
+#define SLANG_LS_RETURN_ON_SUCCESS(x) { auto _res = (x); if (_res.returnCode == SLANG_OK) return _res; }
+#define SLANG_LS_RETURN_ON_FAIL(x) { auto _res = (x); if (SLANG_FAILED(_res.returnCode)) return _res; }
+
namespace Slang
{
using namespace LanguageServerProtocol;
@@ -42,12 +45,8 @@ ArrayView<const char*> getCommitChars()
return makeArrayView(_commitCharsArray, SLANG_COUNT_OF(_commitCharsArray));
}
-SlangResult LanguageServer::init(const InitializeParams& args)
+SlangResult LanguageServerCore::init(const InitializeParams& args)
{
- SLANG_RETURN_ON_FAIL(m_connection->initWithStdStreams(JSONRPCConnection::CallStyle::Object));
-
- m_typeMap = JSONNativeUtil::getTypeFuncsMap();
-
m_workspaceFolders = args.workspaceFolders;
m_workspace = new Workspace();
List<URI> rootUris;
@@ -59,7 +58,16 @@ SlangResult LanguageServer::init(const InitializeParams& args)
return SLANG_OK;
}
-slang::IGlobalSession* LanguageServer::getOrCreateGlobalSession()
+SlangResult LanguageServer::init(const InitializeParams& args)
+{
+ SLANG_RETURN_ON_FAIL(m_connection->initWithStdStreams(JSONRPCConnection::CallStyle::Object));
+
+ m_typeMap = JSONNativeUtil::getTypeFuncsMap();
+
+ return m_core.init(args);
+}
+
+slang::IGlobalSession* LanguageServerCore::getOrCreateGlobalSession()
{
if (!m_session)
{
@@ -146,7 +154,7 @@ SlangResult LanguageServer::parseNextMessage()
serverInfo.name = "SlangLanguageServer";
serverInfo.version = "1.8";
- if (m_options.isVisualStudio)
+ if (m_core.m_options.isVisualStudio)
{
VSInitializeResult vsResult;
vsResult.serverInfo = serverInfo;
@@ -220,13 +228,18 @@ SlangResult LanguageServer::parseNextMessage()
}
}
-SlangResult LanguageServer::didOpenTextDocument(const DidOpenTextDocumentParams& args)
+SlangResult LanguageServerCore::didOpenTextDocument(const DidOpenTextDocumentParams& args)
{
String canonicalPath = uriToCanonicalPath(args.textDocument.uri);
m_workspace->openDoc(canonicalPath, args.textDocument.text);
return SLANG_OK;
}
+SlangResult LanguageServer::didOpenTextDocument(const DidOpenTextDocumentParams& args)
+{
+ return m_core.didOpenTextDocument(args);
+}
+
static bool isBoolType(Type* t)
{
auto basicType = as<BasicExpressionType>(t);
@@ -515,12 +528,24 @@ HumaneSourceLoc getModuleLoc(SourceManager* manager, ContainerDecl* moduleDecl)
SlangResult LanguageServer::hover(
const LanguageServerProtocol::HoverParams& args, const JSONValue& responseId)
{
+ auto result = m_core.hover(args);
+ if (SLANG_FAILED(result.returnCode) || result.isNull)
+ {
+ m_connection->sendResult(NullResponse::get(), responseId);
+ return SLANG_OK;
+ }
+ m_connection->sendResult(&result.result, responseId);
+ return SLANG_OK;
+}
+
+LanguageServerResult<LanguageServerProtocol::Hover> LanguageServerCore::hover(
+ const LanguageServerProtocol::HoverParams& args)
+{
String canonicalPath = uriToCanonicalPath(args.textDocument.uri);
RefPtr<DocumentVersion> doc;
if (!m_workspace->openedDocuments.tryGetValue(canonicalPath, doc))
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
Index line, col;
doc->zeroBasedUTF16LocToOneBasedUTF8Loc(args.position.line, args.position.character, line, col);
@@ -531,8 +556,7 @@ SlangResult LanguageServer::hover(
Module* parsedModule = version->getOrLoadModule(canonicalPath);
if (!parsedModule)
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return LanguageServerResult<LanguageServerProtocol::Hover>();
}
auto findResult = findASTNodesAt(
doc.Ptr(),
@@ -544,10 +568,8 @@ SlangResult LanguageServer::hover(
col);
if (findResult.getCount() == 0 || findResult[0].path.getCount() == 0)
{
- if (SLANG_SUCCEEDED(tryGetMacroHoverInfo(version, doc, line, col, responseId)))
- return SLANG_OK;
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ SLANG_LS_RETURN_ON_SUCCESS(tryGetMacroHoverInfo(version, doc, line, col));
+ return std::nullopt;
}
StringBuilder sb;
@@ -836,27 +858,37 @@ SlangResult LanguageServer::hover(
}
if (sb.getLength() == 0)
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
else
{
hover.contents.kind = "markdown";
hover.contents.value = sb.produceString();
- m_connection->sendResult(&hover, responseId);
- return SLANG_OK;
+ return hover;
}
}
SlangResult LanguageServer::gotoDefinition(
const LanguageServerProtocol::DefinitionParams& args, const JSONValue& responseId)
{
+ auto result = m_core.gotoDefinition(args);
+ if (SLANG_FAILED(result.returnCode) || result.isNull)
+ {
+ m_connection->sendResult(NullResponse::get(), responseId);
+ return SLANG_OK;
+ }
+ m_connection->sendResult(&result.result, responseId);
+ return SLANG_OK;
+}
+
+LanguageServerResult<List<LanguageServerProtocol::Location>> LanguageServerCore::gotoDefinition(
+ const LanguageServerProtocol::DefinitionParams& args)
+{
String canonicalPath = uriToCanonicalPath(args.textDocument.uri);
RefPtr<DocumentVersion> doc;
if (!m_workspace->openedDocuments.tryGetValue(canonicalPath, doc))
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
Index line, col;
doc->zeroBasedUTF16LocToOneBasedUTF8Loc(args.position.line, args.position.character, line, col);
@@ -867,8 +899,7 @@ SlangResult LanguageServer::gotoDefinition(
Module* parsedModule = version->getOrLoadModule(canonicalPath);
if (!parsedModule)
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
auto findResult = findASTNodesAt(
doc.Ptr(),
@@ -880,12 +911,9 @@ SlangResult LanguageServer::gotoDefinition(
col);
if (findResult.getCount() == 0 || findResult[0].path.getCount() == 0)
{
- if (SLANG_SUCCEEDED(tryGotoMacroDefinition(version, doc, line, col, responseId)))
- return SLANG_OK;
- if (SLANG_SUCCEEDED(tryGotoFileInclude(version, doc, line, responseId)))
- return SLANG_OK;
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ SLANG_LS_RETURN_ON_SUCCESS(tryGotoMacroDefinition(version, doc, line, col));
+ SLANG_LS_RETURN_ON_SUCCESS(tryGotoFileInclude(version, doc, line));
+ return std::nullopt;
}
struct LocationResult
{
@@ -948,8 +976,7 @@ SlangResult LanguageServer::gotoDefinition(
}
if (locations.getCount() == 0)
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
else
{
@@ -971,8 +998,7 @@ SlangResult LanguageServer::gotoDefinition(
results.add(result);
}
}
- m_connection->sendResult(&results, responseId);
- return SLANG_OK;
+ return results;
}
}
@@ -989,13 +1015,25 @@ template <typename Func> Deferred<Func> makeDeferred(const Func& f) { return Def
SlangResult LanguageServer::completion(
const LanguageServerProtocol::CompletionParams& args, const JSONValue& responseId)
{
+ auto result = m_core.completion(args);
+ if (SLANG_FAILED(result.returnCode) || result.isNull)
+ m_connection->sendResult(NullResponse::get(), responseId);
+ else if (result.result.items.getCount())
+ m_connection->sendResult(&result.result.items, responseId);
+ else
+ m_connection->sendResult(&result.result.textEditItems, responseId);
+ return SLANG_OK;
+}
+
+LanguageServerResult<CompletionResult> LanguageServerCore::completion(
+ const LanguageServerProtocol::CompletionParams& args)
+{
String canonicalPath = uriToCanonicalPath(args.textDocument.uri);
RefPtr<DocumentVersion> doc;
if (!m_workspace->openedDocuments.tryGetValue(canonicalPath, doc))
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
// Don't show completion at case label or after single '>' operator.
@@ -1014,8 +1052,7 @@ SlangResult LanguageServer::completion(
auto prevCharPos = args.position.character - 2;
if (prevCharPos >= 0 && prevCharPos < line.getLength() && line[prevCharPos] != requiredPrevChar)
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
}
}
@@ -1026,8 +1063,7 @@ SlangResult LanguageServer::completion(
auto cursorOffset = doc->getOffset(utf8Line, utf8Col);
if (cursorOffset == -1 || doc->getText().getLength() == 0)
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
// Ajust cursor position to the beginning of the current/last identifier.
@@ -1040,8 +1076,7 @@ SlangResult LanguageServer::completion(
// Never show suggestions when the user is typing a number.
if (cursorOffset + 1 >= 0 && cursorOffset + 1 < doc->getText().getLength() && CharUtil::isDigit(doc->getText()[cursorOffset + 1]))
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
// Always create a new workspace version for the completion request since we
@@ -1057,7 +1092,6 @@ SlangResult LanguageServer::completion(
context.cursorOffset = cursorOffset;
context.version = version;
context.doc = doc.Ptr();
- context.responseId = responseId;
context.canonicalPath = canonicalPath.getUnownedSlice();
context.line = utf8Line;
context.col = utf8Col;
@@ -1069,22 +1103,15 @@ SlangResult LanguageServer::completion(
context.commitCharacterBehavior = CommitCharacterBehavior::Disabled;
}
- if (SLANG_SUCCEEDED(context.tryCompleteInclude()))
- {
- return SLANG_OK;
- }
- if (SLANG_SUCCEEDED(context.tryCompleteImport()))
- {
- return SLANG_OK;
- }
+ SLANG_LS_RETURN_ON_SUCCESS(context.tryCompleteInclude());
+ SLANG_LS_RETURN_ON_SUCCESS(context.tryCompleteImport());
if (args.context.triggerKind ==
LanguageServerProtocol::kCompletionTriggerKindTriggerCharacter &&
(args.context.triggerCharacter == "\"" || args.context.triggerCharacter == "/"))
{
// Trigger characters '"' and '/' are for include only.
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
@@ -1099,49 +1126,48 @@ SlangResult LanguageServer::completion(
Module* parsedModule = version->getOrLoadModule(canonicalPath);
if (!parsedModule)
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
context.parsedModule = parsedModule;
- if (SLANG_SUCCEEDED(context.tryCompleteAttributes()))
- {
- return SLANG_OK;
- }
+ SLANG_LS_RETURN_ON_SUCCESS(context.tryCompleteAttributes());
// Don't generate completion suggestions after typing '['.
if (args.context.triggerKind ==
LanguageServerProtocol::kCompletionTriggerKindTriggerCharacter &&
args.context.triggerCharacter == "[")
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
- if (SLANG_SUCCEEDED(context.tryCompleteHLSLSemantic()))
- {
- return SLANG_OK;
- }
- if (SLANG_SUCCEEDED(context.tryCompleteMemberAndSymbol()))
+ SLANG_LS_RETURN_ON_SUCCESS(context.tryCompleteHLSLSemantic());
+ SLANG_LS_RETURN_ON_SUCCESS(context.tryCompleteMemberAndSymbol());
+ return std::nullopt;
+}
+
+SlangResult LanguageServer::completionResolve(
+ const LanguageServerProtocol::CompletionItem& args, const LanguageServerProtocol::TextEditCompletionItem& editItem, const JSONValue& responseId)
+{
+ auto result = m_core.completionResolve(args, editItem);
+ if (SLANG_FAILED(result.returnCode) || result.isNull)
{
+ m_connection->sendResult(NullResponse::get(), responseId);
return SLANG_OK;
}
- m_connection->sendResult(NullResponse::get(), responseId);
+ m_connection->sendResult(&result.result, responseId);
return SLANG_OK;
}
-SlangResult LanguageServer::completionResolve(
- const LanguageServerProtocol::CompletionItem& args, const LanguageServerProtocol::TextEditCompletionItem& editItem, const JSONValue& responseId)
+LanguageServerResult<LanguageServerProtocol::CompletionItem> LanguageServerCore::completionResolve(
+ const LanguageServerProtocol::CompletionItem& args, const LanguageServerProtocol::TextEditCompletionItem& editItem)
{
if (args.data.getLength() == 0)
{
if (editItem.textEdit.newText.getLength())
{
- m_connection->sendResult(&editItem, responseId);
- return SLANG_OK;
+ return std::nullopt;
}
- m_connection->sendResult(&args, responseId);
- return SLANG_OK;
+ return args;
}
LanguageServerProtocol::CompletionItem resolvedItem = args;
@@ -1149,8 +1175,7 @@ SlangResult LanguageServer::completionResolve(
auto version = m_workspace->getCurrentCompletionVersion();
if (!version || !version->linkage)
{
- m_connection->sendResult(&resolvedItem, responseId);
- return SLANG_OK;
+ return resolvedItem;
}
SLANG_AST_BUILDER_RAII(version->linkage->getASTBuilder());
auto& candidateItems = version->linkage->contentAssistInfo.completionSuggestions.candidateItems;
@@ -1163,20 +1188,31 @@ SlangResult LanguageServer::completionResolve(
resolvedItem.documentation.value = docSB.produceString();
resolvedItem.documentation.kind = "markdown";
}
- m_connection->sendResult(&resolvedItem, responseId);
- return SLANG_OK;
+ return resolvedItem;
}
SlangResult LanguageServer::semanticTokens(
const LanguageServerProtocol::SemanticTokensParams& args, const JSONValue& responseId)
{
+ auto result = m_core.semanticTokens(args);
+ if (SLANG_FAILED(result.returnCode) || result.isNull)
+ {
+ m_connection->sendResult(NullResponse::get(), responseId);
+ return SLANG_OK;
+ }
+ m_connection->sendResult(&result.result, responseId);
+ return SLANG_OK;
+}
+
+LanguageServerResult<LanguageServerProtocol::SemanticTokens> LanguageServerCore::semanticTokens(
+ const LanguageServerProtocol::SemanticTokensParams& args)
+{
String canonicalPath = uriToCanonicalPath(args.textDocument.uri);
RefPtr<DocumentVersion> doc;
if (!m_workspace->openedDocuments.tryGetValue(canonicalPath, doc))
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
auto version = m_workspace->getCurrentVersion();
@@ -1185,8 +1221,7 @@ SlangResult LanguageServer::semanticTokens(
Module* parsedModule = version->getOrLoadModule(canonicalPath);
if (!parsedModule)
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
auto tokens = getSemanticTokens(version->linkage, parsedModule, canonicalPath.getUnownedSlice(), doc.Ptr());
@@ -1204,11 +1239,10 @@ SlangResult LanguageServer::semanticTokens(
SemanticTokens response;
response.resultId = "";
response.data = getEncodedTokens(tokens);
- m_connection->sendResult(&response, responseId);
- return SLANG_OK;
+ return response;
}
-String LanguageServer::getExprDeclSignature(Expr* expr, String* outDocumentation, List<Slang::Range<Index>>* outParamRanges)
+String LanguageServerCore::getExprDeclSignature(Expr* expr, String* outDocumentation, List<Slang::Range<Index>>* outParamRanges)
{
if (auto declRefExpr = as<DeclRefExpr>(expr))
{
@@ -1285,7 +1319,7 @@ String LanguageServer::getExprDeclSignature(Expr* expr, String* outDocumentation
return printer.getString();
}
-String LanguageServer::getDeclRefSignature(DeclRef<Decl> declRef, String* outDocumentation, List<Slang::Range<Index>>* outParamRanges)
+String LanguageServerCore::getDeclRefSignature(DeclRef<Decl> declRef, String* outDocumentation, List<Slang::Range<Index>>* outParamRanges)
{
auto version = m_workspace->getCurrentVersion();
SLANG_AST_BUILDER_RAII(version->linkage->getASTBuilder());
@@ -1314,12 +1348,24 @@ String LanguageServer::getDeclRefSignature(DeclRef<Decl> declRef, String* outDoc
SlangResult LanguageServer::signatureHelp(
const LanguageServerProtocol::SignatureHelpParams& args, const JSONValue& responseId)
{
+ auto result = m_core.signatureHelp(args);
+ if (SLANG_FAILED(result.returnCode) || result.isNull)
+ {
+ m_connection->sendResult(NullResponse::get(), responseId);
+ return SLANG_OK;
+ }
+ m_connection->sendResult(&result.result, responseId);
+ return SLANG_OK;
+}
+
+LanguageServerResult<LanguageServerProtocol::SignatureHelp> LanguageServerCore::signatureHelp(
+ const LanguageServerProtocol::SignatureHelpParams& args)
+{
String canonicalPath = uriToCanonicalPath(args.textDocument.uri);
RefPtr<DocumentVersion> doc;
if (!m_workspace->openedDocuments.tryGetValue(canonicalPath, doc))
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
Index line, col;
doc->zeroBasedUTF16LocToOneBasedUTF8Loc(args.position.line, args.position.character, line, col);
@@ -1330,8 +1376,7 @@ SlangResult LanguageServer::signatureHelp(
Module* parsedModule = version->getOrLoadModule(canonicalPath);
if (!parsedModule)
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
auto findResult = findASTNodesAt(
@@ -1345,8 +1390,7 @@ SlangResult LanguageServer::signatureHelp(
if (findResult.getCount() == 0)
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
AppExprBase* appExpr = nullptr;
@@ -1373,14 +1417,12 @@ SlangResult LanguageServer::signatureHelp(
}
if (!appExpr)
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
if (appExpr->argumentDelimeterLocs.getCount() == 0)
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
auto funcExpr = appExpr->functionExpr;
@@ -1399,8 +1441,7 @@ SlangResult LanguageServer::signatureHelp(
}
if (!funcExpr)
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
SignatureHelp response;
@@ -1534,19 +1575,30 @@ SlangResult LanguageServer::signatureHelp(
}
}
- m_connection->sendResult(&response, responseId);
- return SLANG_OK;
+ return response;
}
SlangResult LanguageServer::documentSymbol(
const LanguageServerProtocol::DocumentSymbolParams& args, const JSONValue& responseId)
{
+ auto result = m_core.documentSymbol(args);
+ if (SLANG_FAILED(result.returnCode) || result.isNull)
+ {
+ m_connection->sendResult(NullResponse::get(), responseId);
+ return SLANG_OK;
+ }
+ m_connection->sendResult(&result.result, responseId);
+ return SLANG_OK;
+}
+
+LanguageServerResult<List<LanguageServerProtocol::DocumentSymbol>> LanguageServerCore::documentSymbol(
+ const LanguageServerProtocol::DocumentSymbolParams& args)
+{
String canonicalPath = uriToCanonicalPath(args.textDocument.uri);
RefPtr<DocumentVersion> doc;
if (!m_workspace->openedDocuments.tryGetValue(canonicalPath, doc))
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
auto version = m_workspace->getCurrentVersion();
SLANG_AST_BUILDER_RAII(version->linkage->getASTBuilder());
@@ -1554,22 +1606,31 @@ SlangResult LanguageServer::documentSymbol(
Module* parsedModule = version->getOrLoadModule(canonicalPath);
if (!parsedModule)
{
+ return std::nullopt;
+ }
+ List<DocumentSymbol> symbols = getDocumentSymbols(version->linkage, parsedModule, canonicalPath.getUnownedSlice(), doc.Ptr());
+ return symbols;
+}
+
+SlangResult LanguageServer::inlayHint(const LanguageServerProtocol::InlayHintParams& args, const JSONValue& responseId)
+{
+ auto result = m_core.inlayHint(args);
+ if (SLANG_FAILED(result.returnCode) || result.isNull)
+ {
m_connection->sendResult(NullResponse::get(), responseId);
return SLANG_OK;
}
- List<DocumentSymbol> symbols = getDocumentSymbols(version->linkage, parsedModule, canonicalPath.getUnownedSlice(), doc.Ptr());
- m_connection->sendResult(&symbols, responseId);
+ m_connection->sendResult(&result.result, responseId);
return SLANG_OK;
}
-SlangResult LanguageServer::inlayHint(const LanguageServerProtocol::InlayHintParams& args, const JSONValue& responseId)
+LanguageServerResult<List<LanguageServerProtocol::InlayHint>> LanguageServerCore::inlayHint(const LanguageServerProtocol::InlayHintParams& args)
{
String canonicalPath = uriToCanonicalPath(args.textDocument.uri);
RefPtr<DocumentVersion> doc;
if (!m_workspace->openedDocuments.tryGetValue(canonicalPath, doc))
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
auto version = m_workspace->getCurrentVersion();
SLANG_AST_BUILDER_RAII(version->linkage->getASTBuilder());
@@ -1577,8 +1638,7 @@ SlangResult LanguageServer::inlayHint(const LanguageServerProtocol::InlayHintPar
Module* parsedModule = version->getOrLoadModule(canonicalPath);
if (!parsedModule)
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
List<InlayHint> hints = getInlayHints(
version->linkage,
@@ -1587,8 +1647,7 @@ SlangResult LanguageServer::inlayHint(const LanguageServerProtocol::InlayHintPar
doc.Ptr(),
args.range,
m_inlayHintOptions);
- m_connection->sendResult(&hints, responseId);
- return SLANG_OK;
+ return hints;
}
List<LanguageServerProtocol::TextEdit> translateTextEdits(DocumentVersion* doc, List<Edit>& edits)
@@ -1615,12 +1674,24 @@ List<LanguageServerProtocol::TextEdit> translateTextEdits(DocumentVersion* doc,
SlangResult LanguageServer::formatting(const LanguageServerProtocol::DocumentFormattingParams& args, const JSONValue& responseId)
{
+ auto result = m_core.formatting(args);
+ if (SLANG_FAILED(result.returnCode) || result.isNull)
+ {
+ m_connection->sendResult(NullResponse::get(), responseId);
+ return SLANG_OK;
+ }
+ m_connection->sendResult(&result.result, responseId);
+ return SLANG_OK;
+}
+
+LanguageServerResult<List<LanguageServerProtocol::TextEdit>> LanguageServerCore::formatting(
+ const LanguageServerProtocol::DocumentFormattingParams& args)
+{
String canonicalPath = uriToCanonicalPath(args.textDocument.uri);
RefPtr<DocumentVersion> doc;
if (!m_workspace->openedDocuments.tryGetValue(canonicalPath, doc))
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
if (m_formatOptions.clangFormatLocation.getLength() == 0)
m_formatOptions.clangFormatLocation = findClangFormatTool();
@@ -1629,18 +1700,29 @@ SlangResult LanguageServer::formatting(const LanguageServerProtocol::DocumentFor
List<TextRange> exclusionRange = extractFormattingExclusionRanges(doc->getText().getUnownedSlice());
auto edits = formatSource(doc->getText().getUnownedSlice(), -1, -1, -1, exclusionRange, options);
auto textEdits = translateTextEdits(doc, edits);
- m_connection->sendResult(&textEdits, responseId);
- return SLANG_OK;
+ return textEdits;
}
SlangResult LanguageServer::rangeFormatting(const LanguageServerProtocol::DocumentRangeFormattingParams& args, const JSONValue& responseId)
{
+ auto result = m_core.rangeFormatting(args);
+ if (SLANG_FAILED(result.returnCode) || result.isNull)
+ {
+ m_connection->sendResult(NullResponse::get(), responseId);
+ return SLANG_OK;
+ }
+ m_connection->sendResult(&result.result, responseId);
+ return SLANG_OK;
+}
+
+LanguageServerResult<List<LanguageServerProtocol::TextEdit>> LanguageServerCore::rangeFormatting(
+ const LanguageServerProtocol::DocumentRangeFormattingParams& args)
+{
String canonicalPath = uriToCanonicalPath(args.textDocument.uri);
RefPtr<DocumentVersion> doc;
if (!m_workspace->openedDocuments.tryGetValue(canonicalPath, doc))
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
Index endLine, endCol;
doc->zeroBasedUTF16LocToOneBasedUTF8Loc(args.range.end.line, args.range.end.character, endLine, endCol);
@@ -1653,23 +1735,33 @@ SlangResult LanguageServer::rangeFormatting(const LanguageServerProtocol::Docume
List<TextRange> exclusionRange = extractFormattingExclusionRanges(doc->getText().getUnownedSlice());
auto edits = formatSource(doc->getText().getUnownedSlice(), args.range.start.line, args.range.end.line, endOffset, exclusionRange, options);
auto textEdits = translateTextEdits(doc, edits);
- m_connection->sendResult(&textEdits, responseId);
- return SLANG_OK;
+ return textEdits;
}
SlangResult LanguageServer::onTypeFormatting(const LanguageServerProtocol::DocumentOnTypeFormattingParams& args, const JSONValue& responseId)
{
+ auto result = m_core.onTypeFormatting(args);
+ if (SLANG_FAILED(result.returnCode) || result.isNull)
+ {
+ m_connection->sendResult(NullResponse::get(), responseId);
+ return SLANG_OK;
+ }
+ m_connection->sendResult(&result.result, responseId);
+ return SLANG_OK;
+}
+
+LanguageServerResult<List<LanguageServerProtocol::TextEdit>> LanguageServerCore::onTypeFormatting(
+ const LanguageServerProtocol::DocumentOnTypeFormattingParams& args)
+{
String canonicalPath = uriToCanonicalPath(args.textDocument.uri);
RefPtr<DocumentVersion> doc;
if (!m_workspace->openedDocuments.tryGetValue(canonicalPath, doc))
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
if (args.ch == ":" && !doc->getLine((Int)args.position.line + 1).trim().startsWith("case "))
{
- m_connection->sendResult(NullResponse::get(), responseId);
- return SLANG_OK;
+ return std::nullopt;
}
if (m_formatOptions.clangFormatLocation.getLength() == 0)
m_formatOptions.clangFormatLocation = findClangFormatTool();
@@ -1682,20 +1774,18 @@ SlangResult LanguageServer::onTypeFormatting(const LanguageServerProtocol::Docum
List<TextRange> exclusionRange = extractFormattingExclusionRanges(doc->getText().getUnownedSlice());
auto edits = formatSource(doc->getText().getUnownedSlice(), args.position.line, args.position.line, cursorOffset, exclusionRange, options);
auto textEdits = translateTextEdits(doc, edits);
- m_connection->sendResult(&textEdits, responseId);
- return SLANG_OK;
+ return textEdits;
}
void LanguageServer::publishDiagnostics()
{
-
if (std::chrono::system_clock::now() - m_lastDiagnosticUpdateTime < std::chrono::milliseconds(1000))
{
return;
}
m_lastDiagnosticUpdateTime = std::chrono::system_clock::now();
- auto version = m_workspace->getCurrentVersion();
+ auto version = m_core.m_workspace->getCurrentVersion();
SLANG_AST_BUILDER_RAII(version->linkage->getASTBuilder());
// Send updates to clear diagnostics for files that no longer have any messages.
@@ -1747,7 +1837,7 @@ void LanguageServer::updatePredefinedMacros(const JSONValue& macros)
List<String> predefinedMacros;
if (SLANG_SUCCEEDED(converter.convert(macros, &predefinedMacros)))
{
- if (m_workspace->updatePredefinedMacros(predefinedMacros))
+ if (m_core.m_workspace->updatePredefinedMacros(predefinedMacros))
{
sendRefreshRequests(m_connection);
}
@@ -1764,7 +1854,7 @@ void LanguageServer::updateSearchPaths(const JSONValue& value)
List<String> searchPaths;
if (SLANG_SUCCEEDED(converter.convert(value, &searchPaths)))
{
- if (m_workspace->updateSearchPaths(searchPaths))
+ if (m_core.m_workspace->updateSearchPaths(searchPaths))
{
sendRefreshRequests(m_connection);
}
@@ -1781,7 +1871,7 @@ void LanguageServer::updateSearchInWorkspace(const JSONValue& value)
bool searchPaths;
if (SLANG_SUCCEEDED(converter.convert(value, &searchPaths)))
{
- if (m_workspace->updateSearchInWorkspace(searchPaths))
+ if (m_core.m_workspace->updateSearchInWorkspace(searchPaths))
{
sendRefreshRequests(m_connection);
}
@@ -1800,15 +1890,15 @@ void LanguageServer::updateCommitCharacters(const JSONValue& jsonValue)
{
if (value == "on")
{
- m_commitCharacterBehavior = CommitCharacterBehavior::All;
+ m_core.m_commitCharacterBehavior = CommitCharacterBehavior::All;
}
else if (value == "off")
{
- m_commitCharacterBehavior = CommitCharacterBehavior::Disabled;
+ m_core.m_commitCharacterBehavior = CommitCharacterBehavior::Disabled;
}
else
{
- m_commitCharacterBehavior = CommitCharacterBehavior::MembersOnly;
+ m_core.m_commitCharacterBehavior = CommitCharacterBehavior::MembersOnly;
}
}
}
@@ -1819,17 +1909,17 @@ void LanguageServer::updateFormattingOptions(const JSONValue& clangFormatLoc, co
auto container = m_connection->getContainer();
JSONToNativeConverter converter(container, &m_typeMap, m_connection->getSink());
if (clangFormatLoc.isValid())
- converter.convert(clangFormatLoc, &m_formatOptions.clangFormatLocation);
+ converter.convert(clangFormatLoc, &m_core.m_formatOptions.clangFormatLocation);
if (clangFormatStyle.isValid())
- converter.convert(clangFormatStyle, &m_formatOptions.style);
+ converter.convert(clangFormatStyle, &m_core.m_formatOptions.style);
if (clangFormatFallbackStyle.isValid())
- converter.convert(clangFormatFallbackStyle, &m_formatOptions.fallbackStyle);
+ converter.convert(clangFormatFallbackStyle, &m_core.m_formatOptions.fallbackStyle);
if (allowLineBreakOnType.isValid())
- converter.convert(allowLineBreakOnType, &m_formatOptions.allowLineBreakInOnTypeFormatting);
+ converter.convert(allowLineBreakOnType, &m_core.m_formatOptions.allowLineBreakInOnTypeFormatting);
if (allowLineBreakInRange.isValid())
- converter.convert(allowLineBreakInRange, &m_formatOptions.allowLineBreakInRangeFormatting);
- if (m_formatOptions.style.getLength() == 0)
- m_formatOptions.style = Slang::FormatOptions().style;
+ converter.convert(allowLineBreakInRange, &m_core.m_formatOptions.allowLineBreakInRangeFormatting);
+ if (m_core.m_formatOptions.style.getLength() == 0)
+ m_core.m_formatOptions.style = Slang::FormatOptions().style;
}
void LanguageServer::updateInlayHintOptions(const JSONValue& deducedTypes, const JSONValue& parameterNames)
@@ -1840,13 +1930,13 @@ void LanguageServer::updateInlayHintOptions(const JSONValue& deducedTypes, const
bool showParameterNames = false;
converter.convert(deducedTypes, &showDeducedType);
converter.convert(parameterNames, &showParameterNames);
- if (showDeducedType != m_inlayHintOptions.showDeducedType || showParameterNames != m_inlayHintOptions.showParameterNames)
+ if (showDeducedType != m_core.m_inlayHintOptions.showDeducedType || showParameterNames != m_core.m_inlayHintOptions.showParameterNames)
{
m_connection->sendCall(
UnownedStringSlice("workspace/inlayHint/refresh"), JSONValue::makeInt(0));
}
- m_inlayHintOptions.showDeducedType = showDeducedType;
- m_inlayHintOptions.showParameterNames = showParameterNames;
+ m_core.m_inlayHintOptions.showDeducedType = showDeducedType;
+ m_core.m_inlayHintOptions.showParameterNames = showParameterNames;
}
void LanguageServer::updateTraceOptions(const JSONValue& value)
@@ -1921,7 +2011,7 @@ void LanguageServer::logMessage(int type, String message)
m_connection->sendCall(LanguageServerProtocol::LogMessageParams::methodName, &args);
}
-FormatOptions LanguageServer::getFormatOptions(Workspace* workspace, FormatOptions inOptions)
+FormatOptions LanguageServerCore::getFormatOptions(Workspace* workspace, FormatOptions inOptions)
{
FormatOptions result = inOptions;
if (workspace->rootDirectories.getCount())
@@ -1934,8 +2024,8 @@ FormatOptions LanguageServer::getFormatOptions(Workspace* workspace, FormatOptio
return result;
}
-SlangResult LanguageServer::tryGetMacroHoverInfo(
- WorkspaceVersion* version, DocumentVersion* doc, Index line, Index col, JSONValue responseId)
+LanguageServerResult<LanguageServerProtocol::Hover> LanguageServerCore::tryGetMacroHoverInfo(
+ WorkspaceVersion* version, DocumentVersion* doc, Index line, Index col)
{
Index startOffset = 0;
auto identifier = doc->peekIdentifier(line, col, startOffset);
@@ -1981,12 +2071,11 @@ SlangResult LanguageServer::tryGetMacroHoverInfo(
appendDefinitionLocation(sb, m_workspace, humaneLoc);
hover.contents.kind = "markdown";
hover.contents.value = sb.produceString();
- m_connection->sendResult(&hover, responseId);
- return SLANG_OK;
+ return hover;
}
-SlangResult LanguageServer::tryGotoMacroDefinition(
- WorkspaceVersion* version, DocumentVersion* doc, Index line, Index col, JSONValue responseId)
+LanguageServerResult<List<Location>> LanguageServerCore::tryGotoMacroDefinition(
+ WorkspaceVersion* version, DocumentVersion* doc, Index line, Index col)
{
Index startOffset = 0;
auto identifier = doc->peekIdentifier(line, col, startOffset);
@@ -1997,7 +2086,9 @@ SlangResult LanguageServer::tryGotoMacroDefinition(
return SLANG_FAIL;
auto humaneLoc =
version->linkage->getSourceManager()->getHumaneLoc(def->loc, SourceLocType::Actual);
- LanguageServerProtocol::Location result;
+ List<LanguageServerProtocol::Location> results;
+ results.setCount(1);
+ auto& result = results[0];
result.uri = URI::fromLocalFilePath(humaneLoc.pathInfo.foundPath.getUnownedSlice()).uri;
Index outLine, outCol;
doc->oneBasedUTF8LocToZeroBasedUTF16Loc(humaneLoc.line, humaneLoc.column, outLine, outCol);
@@ -2005,12 +2096,11 @@ SlangResult LanguageServer::tryGotoMacroDefinition(
result.range.start.character = (int)outCol;
result.range.end.line = (int)outLine;
result.range.end.character = (int)(outCol + identifier.getLength());
- m_connection->sendResult(&result, responseId);
- return SLANG_OK;
+ return results;
}
-SlangResult LanguageServer::tryGotoFileInclude(
- WorkspaceVersion* version, DocumentVersion* doc, Index line, JSONValue responseId)
+LanguageServerResult<List<Location>> LanguageServerCore::tryGotoFileInclude(
+ WorkspaceVersion* version, DocumentVersion* doc, Index line)
{
auto lineContent = doc->getLine(line).trim();
if (!lineContent.startsWith("#") || lineContent.indexOf(UnownedStringSlice("include")) == -1)
@@ -2021,14 +2111,15 @@ SlangResult LanguageServer::tryGotoFileInclude(
version->linkage->getSourceManager()->getHumaneLoc(include.loc, SourceLocType::Actual);
if (includeLoc.line == line && includeLoc.pathInfo.foundPath == doc->getPath())
{
- LanguageServerProtocol::Location result;
+ List<LanguageServerProtocol::Location> results;
+ results.setCount(1);
+ auto& result = results[0];
result.uri = URI::fromLocalFilePath(include.path.getUnownedSlice()).uri;
result.range.start.line = 0;
result.range.start.character = 0;
result.range.end.line = 0;
result.range.end.character = 0;
- m_connection->sendResult(&result, responseId);
- return SLANG_OK;
+ return results;
}
}
return SLANG_FAIL;
@@ -2267,17 +2358,28 @@ void LanguageServer::processCommands()
SlangResult LanguageServer::didCloseTextDocument(const DidCloseTextDocumentParams& args)
{
+ resetDiagnosticUpdateTime();
+ return m_core.didCloseTextDocument(args);
+}
+
+SlangResult LanguageServerCore::didCloseTextDocument(const DidCloseTextDocumentParams& args)
+{
String canonicalPath = uriToCanonicalPath(args.textDocument.uri);
m_workspace->closeDoc(canonicalPath);
- resetDiagnosticUpdateTime();
return SLANG_OK;
}
+
SlangResult LanguageServer::didChangeTextDocument(const DidChangeTextDocumentParams& args)
{
+ resetDiagnosticUpdateTime();
+ return m_core.didChangeTextDocument(args);
+}
+
+SlangResult LanguageServerCore::didChangeTextDocument(const DidChangeTextDocumentParams& args)
+{
String canonicalPath = uriToCanonicalPath(args.textDocument.uri);
for (auto change : args.contentChanges)
m_workspace->changeDoc(canonicalPath, change.range, change.text);
- resetDiagnosticUpdateTime();
return SLANG_OK;
}
@@ -2297,7 +2399,7 @@ SlangResult LanguageServer::didChangeConfiguration(
void LanguageServer::update()
{
- if (!m_workspace)
+ if (!m_core.m_workspace)
return;
publishDiagnostics();
}