summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/compiler-core/slang-language-server-protocol.cpp34
-rw-r--r--source/compiler-core/slang-language-server-protocol.h14
-rw-r--r--source/slang/slang-language-server-semantic-tokens.cpp8
-rw-r--r--source/slang/slang-language-server.cpp97
-rw-r--r--source/slang/slang-language-server.h17
-rw-r--r--source/slang/slang-parser.cpp30
-rw-r--r--source/slang/slang-workspace-version.cpp4
7 files changed, 160 insertions, 44 deletions
diff --git a/source/compiler-core/slang-language-server-protocol.cpp b/source/compiler-core/slang-language-server-protocol.cpp
index 628baf08d..93ea0c9e3 100644
--- a/source/compiler-core/slang-language-server-protocol.cpp
+++ b/source/compiler-core/slang-language-server-protocol.cpp
@@ -257,6 +257,29 @@ static const StructRttiInfo _makeServerCapabilitiesRtti()
}
const StructRttiInfo ServerCapabilities::g_rttiInfo = _makeServerCapabilitiesRtti();
+static const StructRttiInfo _makeVSServerCapabilitiesRtti()
+{
+ VSServerCapabilities obj;
+ StructRttiBuilder builder(&obj, "LanguageServerProtocol::ServerCapabilities", nullptr);
+ builder.addField("positionEncoding", &obj.positionEncoding);
+ builder.addField("textDocumentSync", &obj.textDocumentSync);
+ builder.addField("workspace", &obj.workspace);
+ builder.addField("hoverProvider", &obj.hoverProvider);
+ builder.addField("inlayHintProvider", &obj.inlayHintProvider);
+ builder.addField("documentOnTypeFormattingProvider", &obj.documentOnTypeFormattingProvider);
+ builder.addField("documentFormattingProvider", &obj.documentFormattingProvider);
+ builder.addField("documentRangeFormattingProvider", &obj.documentRangeFormattingProvider);
+ builder.addField("definitionProvider", &obj.definitionProvider);
+ builder.addField("completionProvider", &obj.completionProvider);
+ builder.addField("semanticTokensProvider", &obj.semanticTokensProvider);
+ builder.addField("signatureHelpProvider", &obj.signatureHelpProvider);
+ builder.addField("documentSymbolProvider", &obj.documentSymbolProvider);
+ builder.addField("_vs_projectContextProvider", &obj._vs_projectContextProvider);
+ builder.ignoreUnknownFields();
+ return builder.make();
+}
+const StructRttiInfo VSServerCapabilities::g_rttiInfo = _makeVSServerCapabilitiesRtti();
+
static const StructRttiInfo _makeServerInfoRtti()
{
ServerInfo obj;
@@ -280,6 +303,17 @@ static const StructRttiInfo _makeInitializeResultRtti()
}
const StructRttiInfo InitializeResult::g_rttiInfo = _makeInitializeResultRtti();
+static const StructRttiInfo _makeVSInitializeResultRtti()
+{
+ VSInitializeResult obj;
+ StructRttiBuilder builder(&obj, "LanguageServerProtocol::VSInitializeResult", nullptr);
+ builder.addField("capabilities", &obj.capabilities);
+ builder.addField("serverInfo", &obj.serverInfo);
+ builder.ignoreUnknownFields();
+ return builder.make();
+}
+const StructRttiInfo VSInitializeResult::g_rttiInfo = _makeVSInitializeResultRtti();
+
const UnownedStringSlice InitializeParams::methodName =
UnownedStringSlice::fromLiteral("initialize");
diff --git a/source/compiler-core/slang-language-server-protocol.h b/source/compiler-core/slang-language-server-protocol.h
index 316c15c04..3dcc90be1 100644
--- a/source/compiler-core/slang-language-server-protocol.h
+++ b/source/compiler-core/slang-language-server-protocol.h
@@ -299,6 +299,12 @@ struct ServerCapabilities
static const StructRttiInfo g_rttiInfo;
};
+struct VSServerCapabilities : ServerCapabilities
+{
+ bool _vs_projectContextProvider = false;
+ static const StructRttiInfo g_rttiInfo;
+};
+
struct WorkspaceFolder
{
String uri;
@@ -327,6 +333,14 @@ struct InitializeResult
static const StructRttiInfo g_rttiInfo;
};
+struct VSInitializeResult
+{
+ VSServerCapabilities capabilities;
+ ServerInfo serverInfo;
+
+ static const StructRttiInfo g_rttiInfo;
+};
+
struct ShutdownParams
{
static const UnownedStringSlice methodName;
diff --git a/source/slang/slang-language-server-semantic-tokens.cpp b/source/slang/slang-language-server-semantic-tokens.cpp
index 837aad06c..ae10d62e8 100644
--- a/source/slang/slang-language-server-semantic-tokens.cpp
+++ b/source/slang/slang-language-server-semantic-tokens.cpp
@@ -40,6 +40,8 @@ SemanticToken _createSemanticToken(SourceManager* manager, SourceLoc loc, Name*
List<SemanticToken> getSemanticTokens(Linkage* linkage, Module* module, UnownedStringSlice fileName, DocumentVersion* doc)
{
auto manager = linkage->getSourceManager();
+
+ auto cbufferName = linkage->getNamePool()->getName(toSlice("ConstantBuffer"));
List<SemanticToken> result;
auto maybeInsertToken = [&](const SemanticToken& token)
@@ -73,6 +75,10 @@ List<SemanticToken> getSemanticTokens(Linkage* linkage, Module* module, UnownedS
if (target->hasModifier<BuiltinTypeModifier>())
return;
token.type = SemanticTokenType::Type;
+ if (name == cbufferName)
+ {
+ token.length = doc->getTokenLength(token.line, token.col);
+ }
}
else if (as<ConstructorDecl>(target))
{
@@ -156,7 +162,7 @@ List<SemanticToken> getSemanticTokens(Linkage* linkage, Module* module, UnownedS
}
else if (auto aggTypeDecl = as<AggTypeDeclBase>(node))
{
- if (aggTypeDecl->getName())
+ if (aggTypeDecl->getName() && aggTypeDecl->findModifier<ImplicitParameterGroupElementTypeModifier>() == nullptr)
{
SemanticToken token = _createSemanticToken(
manager, aggTypeDecl->getNameLoc(), aggTypeDecl->getName());
diff --git a/source/slang/slang-language-server.cpp b/source/slang/slang-language-server.cpp
index 84dd1b330..76e21c2ca 100644
--- a/source/slang/slang-language-server.cpp
+++ b/source/slang/slang-language-server.cpp
@@ -106,42 +106,58 @@ SlangResult LanguageServer::parseNextMessage()
{
InitializeParams args;
m_connection->toNativeArgsOrSendError(call.params, &args, call.id);
-
init(args);
+ auto fillCapability = [&](ServerCapabilities& caps)
+ {
+ caps.positionEncoding = "utf-16";
+ caps.textDocumentSync.openClose = true;
+ caps.textDocumentSync.change = (int)TextDocumentSyncKind::Incremental;
+ caps.workspace.workspaceFolders.supported = true;
+ caps.workspace.workspaceFolders.changeNotifications = false;
+ caps.hoverProvider = true;
+ caps.definitionProvider = true;
+ caps.documentSymbolProvider = true;
+ caps.inlayHintProvider.resolveProvider = false;
+ caps.documentFormattingProvider = true;
+ caps.documentOnTypeFormattingProvider.firstTriggerCharacter = "}";
+ caps.documentOnTypeFormattingProvider.moreTriggerCharacter.add(";");
+ caps.documentOnTypeFormattingProvider.moreTriggerCharacter.add(":");
+ caps.documentOnTypeFormattingProvider.moreTriggerCharacter.add("{");
+ caps.documentRangeFormattingProvider = true;
+ caps.completionProvider.triggerCharacters.add(".");
+ caps.completionProvider.triggerCharacters.add(":");
+ caps.completionProvider.triggerCharacters.add("[");
+ caps.completionProvider.triggerCharacters.add("\"");
+ caps.completionProvider.triggerCharacters.add("/");
+ caps.completionProvider.resolveProvider = true;
+ caps.completionProvider.workDoneToken = "";
+ caps.semanticTokensProvider.full = true;
+ caps.semanticTokensProvider.range = false;
+ caps.signatureHelpProvider.triggerCharacters.add("(");
+ caps.signatureHelpProvider.triggerCharacters.add(",");
+ caps.signatureHelpProvider.retriggerCharacters.add(",");
+ for (auto tokenType : kSemanticTokenTypes)
+ caps.semanticTokensProvider.legend.tokenTypes.add(tokenType);
+ };
+ ServerInfo serverInfo;
+ serverInfo.name = "SlangLanguageServer";
+ serverInfo.version = "1.8";
- InitializeResult result;
- result.serverInfo.name = "SlangLanguageServer";
- result.serverInfo.version = "1.3";
- result.capabilities.positionEncoding = "utf-16";
- result.capabilities.textDocumentSync.openClose = true;
- result.capabilities.textDocumentSync.change = (int)TextDocumentSyncKind::Incremental;
- result.capabilities.workspace.workspaceFolders.supported = true;
- result.capabilities.workspace.workspaceFolders.changeNotifications = false;
- result.capabilities.hoverProvider = true;
- result.capabilities.definitionProvider = true;
- result.capabilities.documentSymbolProvider = true;
- result.capabilities.inlayHintProvider.resolveProvider = false;
- result.capabilities.documentFormattingProvider = true;
- result.capabilities.documentOnTypeFormattingProvider.firstTriggerCharacter = "}";
- result.capabilities.documentOnTypeFormattingProvider.moreTriggerCharacter.add(";");
- result.capabilities.documentOnTypeFormattingProvider.moreTriggerCharacter.add(":");
- result.capabilities.documentOnTypeFormattingProvider.moreTriggerCharacter.add("{");
- result.capabilities.documentRangeFormattingProvider = true;
- result.capabilities.completionProvider.triggerCharacters.add(".");
- result.capabilities.completionProvider.triggerCharacters.add(":");
- result.capabilities.completionProvider.triggerCharacters.add("[");
- result.capabilities.completionProvider.triggerCharacters.add("\"");
- result.capabilities.completionProvider.triggerCharacters.add("/");
- result.capabilities.completionProvider.resolveProvider = true;
- result.capabilities.completionProvider.workDoneToken = "";
- result.capabilities.semanticTokensProvider.full = true;
- result.capabilities.semanticTokensProvider.range = false;
- result.capabilities.signatureHelpProvider.triggerCharacters.add("(");
- result.capabilities.signatureHelpProvider.triggerCharacters.add(",");
- result.capabilities.signatureHelpProvider.retriggerCharacters.add(",");
- for (auto tokenType : kSemanticTokenTypes)
- result.capabilities.semanticTokensProvider.legend.tokenTypes.add(tokenType);
- m_connection->sendResult(&result, call.id);
+ if (m_options.isVisualStudio)
+ {
+ VSInitializeResult vsResult;
+ vsResult.serverInfo = serverInfo;
+ fillCapability(vsResult.capabilities);
+ vsResult.capabilities._vs_projectContextProvider = true;
+ m_connection->sendResult(&vsResult, call.id);
+ }
+ else
+ {
+ InitializeResult result;
+ result.serverInfo = serverInfo;
+ fillCapability(result.capabilities);
+ m_connection->sendResult(&result, call.id);
+ }
return SLANG_OK;
}
else if (call.method == "initialized")
@@ -2301,9 +2317,18 @@ SlangResult LanguageServer::execute()
return SLANG_OK;
}
-SLANG_API SlangResult runLanguageServer()
+SLANG_API void LanguageServerStartupOptions::parse(int argc, const char* const* argv)
+{
+ for (int i = 1; i < argc; i++)
+ {
+ if (strcmp(argv[i], "-vs") == 0)
+ isVisualStudio = true;
+ }
+}
+
+SLANG_API SlangResult runLanguageServer(Slang::LanguageServerStartupOptions options)
{
- Slang::LanguageServer server;
+ Slang::LanguageServer server(options);
SLANG_RETURN_ON_FAIL(server.execute());
return SLANG_OK;
}
diff --git a/source/slang/slang-language-server.h b/source/slang/slang-language-server.h
index e244ad9f5..956ad9769 100644
--- a/source/slang/slang-language-server.h
+++ b/source/slang/slang-language-server.h
@@ -76,6 +76,14 @@ struct Command
Optional<LanguageServerProtocol::CancelParams> cancelArgs;
};
+struct LanguageServerStartupOptions
+{
+ // Are we working with Visual Studio client?
+ bool isVisualStudio = false;
+
+ SLANG_API void parse(int argc, const char* const* argv);
+};
+
class LanguageServer
{
private:
@@ -101,7 +109,12 @@ public:
bool m_quit = false;
List<LanguageServerProtocol::WorkspaceFolder> m_workspaceFolders;
RttiTypeFuncsMap m_typeMap;
-
+ LanguageServerStartupOptions m_options;
+
+ LanguageServer(LanguageServerStartupOptions options)
+ : m_options(options)
+ {}
+
SlangResult init(const LanguageServerProtocol::InitializeParams& args);
SlangResult execute();
void update();
@@ -182,5 +195,5 @@ inline bool _isIdentifierChar(char ch)
return ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch == '_';
}
-SLANG_API SlangResult runLanguageServer();
+SLANG_API SlangResult runLanguageServer(LanguageServerStartupOptions options);
} // namespace Slang
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index 909a8eb72..f0c9e175f 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -114,7 +114,7 @@ namespace Slang
DiagnosticSink* sink;
SourceLoc lastErrorLoc;
ParserOptions options;
-
+ Modifiers* pendingModifiers = nullptr;
int genericDepth = 0;
// Is the parser in a "recovering" state?
@@ -3095,7 +3095,7 @@ namespace Slang
}
static Decl* ParseHLSLBufferDecl(
- Parser* parser,
+ Parser* parser,
String bufferWrapperTypeName)
{
// An HLSL declaration of a constant buffer like this:
@@ -3119,7 +3119,19 @@ namespace Slang
// the second is a variable declaration that uses the buffer type.
StructDecl* bufferDataTypeDecl = parser->astBuilder->create<StructDecl>();
- addModifier(bufferDataTypeDecl, parser->astBuilder->create<PublicModifier>());
+ if (parser->pendingModifiers)
+ {
+ // Clone visibility modifier from cbuffer decl to the internal struct type decl.
+ // For example, if cbuffer is public, we want the element buffer type to also be
+ // public.
+ if (auto visModifier = parser->pendingModifiers->findModifier<VisibilityModifier>())
+ {
+ auto cloneVisModifier = (VisibilityModifier*)parser->astBuilder->createByNodeType(visModifier->astNodeType);
+ cloneVisModifier->keywordName = visModifier->keywordName;
+ cloneVisModifier->loc = visModifier->loc;
+ addModifier(bufferDataTypeDecl, cloneVisModifier);
+ }
+ }
VarDecl* bufferVarDecl = parser->astBuilder->create<VarDecl>();
@@ -4396,6 +4408,18 @@ namespace Slang
Modifiers modifiers )
{
DeclBase* decl = nullptr;
+
+ struct RestorePendingModifiersRAII
+ {
+ Modifiers* oldValue;
+ Parser* parser;
+ ~RestorePendingModifiersRAII()
+ {
+ parser->pendingModifiers = oldValue;
+ }
+ };
+ RestorePendingModifiersRAII restorePendingModifiersRAII{ parser->pendingModifiers, parser };
+ parser->pendingModifiers = &modifiers;
auto loc = parser->tokenReader.peekLoc();
diff --git a/source/slang/slang-workspace-version.cpp b/source/slang/slang-workspace-version.cpp
index 9a707aae7..1b17f3170 100644
--- a/source/slang/slang-workspace-version.cpp
+++ b/source/slang/slang-workspace-version.cpp
@@ -243,11 +243,11 @@ void WorkspaceVersion::parseDiagnostics(String compilerOutput)
pos = line.indexOf(' ');
diagnostic.code = StringUtil::parseIntAndAdvancePos(line, pos);
diagnostic.message = line.tail(colonIndex + 2);
- if (lineIndex + 1 < lines.getCount() && lines[lineIndex].startsWith("^+"))
+ if (lineIndex + 1 < lines.getCount() && lines[lineIndex+1].startsWith("^+"))
{
lineIndex++;
pos = 2;
- auto tokenLength = StringUtil::parseIntAndAdvancePos(line, pos);
+ auto tokenLength = StringUtil::parseIntAndAdvancePos(lines[lineIndex], pos);
diagnostic.range.end.character += tokenLength;
}