diff options
Diffstat (limited to 'source/slang/slang-language-server.cpp')
| -rw-r--r-- | source/slang/slang-language-server.cpp | 144 |
1 files changed, 115 insertions, 29 deletions
diff --git a/source/slang/slang-language-server.cpp b/source/slang/slang-language-server.cpp index 0818aea07..7dc2f6dcc 100644 --- a/source/slang/slang-language-server.cpp +++ b/source/slang/slang-language-server.cpp @@ -67,7 +67,7 @@ slang::IGlobalSession* LanguageServer::getOrCreateGlobalSession() return m_session; } -void LanguageServer::resetDiagnosticUpdateTime() { time(&m_lastDiagnosticUpdateTime); } +void LanguageServer::resetDiagnosticUpdateTime() { m_lastDiagnosticUpdateTime = std::chrono::system_clock::now(); } String uriToCanonicalPath(const String& uri) { @@ -159,7 +159,7 @@ SlangResult LanguageServer::parseNextMessage() if (response.result.getKind() == JSONValue::Kind::Array) { auto arr = m_connection->getContainer()->getArray(response.result); - if (arr.getCount() == 8) + if (arr.getCount() == 9) { updatePredefinedMacros(arr[0]); updateSearchPaths(arr[1]); @@ -167,6 +167,7 @@ SlangResult LanguageServer::parseNextMessage() updateCommitCharacters(arr[3]); updateFormattingOptions(arr[4], arr[5]); updateInlayHintOptions(arr[6], arr[7]); + updateTraceOptions(arr[8]); } } break; @@ -222,43 +223,90 @@ String getDeclSignatureString(DeclRef<Decl> declRef, ASTBuilder* astBuilder) static String _formatDocumentation(String doc) { + bool hasDoxygen = false; // TODO: may want to use DocMarkdownWriter in the future to format the text. // For now just insert line breaks before `\param` and `\returns` markups. List<UnownedStringSlice> lines; StringUtil::split(doc.getUnownedSlice(), '\n', lines); StringBuilder result; - + StringBuilder returnDocSB; + StringBuilder parameterDocSB; + StringBuilder* currentSection = &result; + bool isFirstParam = true; for (Index i = 0; i < lines.getCount(); i++) { auto trimedLine = lines[i].trimStart(); - if (i > 0) - { - if ((trimedLine.startsWith("\\") || trimedLine.startsWith("@")) && lines[i - 1].trim().getLength() != 0) - { - result << " \n"; - } - else - { - result << "\n"; - } - } if (trimedLine.startsWith("\\") || trimedLine.startsWith("@")) { + hasDoxygen = true; trimedLine = trimedLine.tail(1); if (trimedLine.startsWith("returns ")) { - trimedLine = trimedLine.subString(8, trimedLine.getLength()); - result << "**returns** "; + trimedLine = trimedLine.tail(8); + currentSection = &returnDocSB; + (*currentSection) << trimedLine << " \n"; } else if (trimedLine.startsWith("return ")) { - trimedLine = trimedLine.subString(7, trimedLine.getLength()); - result << "**Returns** "; + trimedLine = trimedLine.tail(7); + currentSection = &returnDocSB; + (*currentSection) << trimedLine << " \n"; } + else if (trimedLine.startsWith("param")) + { + trimedLine = trimedLine.tail(5).trimStart(); + Index endOfParamName = 0; + if (trimedLine.getLength() > 0 && trimedLine[0] == '[') + { + endOfParamName = trimedLine.indexOf(']') + 1; + while (endOfParamName < trimedLine.getLength() && CharUtil::isWhitespace(trimedLine[endOfParamName])) + endOfParamName++; + } + while (endOfParamName < trimedLine.getLength() && !CharUtil::isWhitespace(trimedLine[endOfParamName])) + endOfParamName++; + if (isFirstParam) + { + isFirstParam = false; + } + else + { + (*currentSection) << " \n"; + } + if (endOfParamName < trimedLine.getLength()) + { + parameterDocSB << "`" << trimedLine.head(endOfParamName) << "`"; + trimedLine = trimedLine.tail(endOfParamName); + } + currentSection = ¶meterDocSB; + (*currentSection) << trimedLine; + } + } + else + { + (*currentSection) << trimedLine << "\n"; } - result << trimedLine; } result << "\n"; + if (parameterDocSB.getLength()) + { + result << "**Parameters** \n"; + result << parameterDocSB.ProduceString() << "\n\n"; + } + if (returnDocSB.getLength()) + { + result << "**Returns** \n"; + result << returnDocSB.ProduceString(); + } + + if (!hasDoxygen) + { + // For ordinary comments, we want to preserve line breaks in the original comment. + result.Clear(); + for (Index i = 0; i < lines.getCount(); i++) + { + result << lines[i] << " \n"; + } + } return result.ProduceString(); } @@ -278,6 +326,27 @@ static void _tryGetDocumentation(StringBuilder& sb, WorkspaceVersion* workspace, } } +void appendDefinitionLocation(StringBuilder& sb, Workspace* workspace, const HumaneSourceLoc& loc) +{ + auto path = loc.pathInfo.foundPath; + Path::getCanonical(path, path); + UnownedStringSlice pathSlice = path.getUnownedSlice(); + if (workspace) + { + for (auto& root : workspace->rootDirectories) + { + if (pathSlice.startsWith(root.getUnownedSlice())) + { + pathSlice = pathSlice.tail(root.getLength()); + if (pathSlice.startsWith("\\") || pathSlice.startsWith("/")) + pathSlice = pathSlice.tail(1); + break; + } + } + } + sb << "Defined in " << pathSlice << "(" << loc.line << ")\n"; +} + SlangResult LanguageServer::hover( const LanguageServerProtocol::HoverParams& args, const JSONValue& responseId) { @@ -329,8 +398,7 @@ SlangResult LanguageServer::hover( auto humaneLoc = version->linkage->getSourceManager()->getHumaneLoc( declRef.getLoc(), SourceLocType::Actual); - sb << "Defined in " << humaneLoc.pathInfo.foundPath << "(" << humaneLoc.line - << ")\n"; + appendDefinitionLocation(sb, m_workspace, humaneLoc); auto nodeHumaneLoc = version->linkage->getSourceManager()->getHumaneLoc(leafNode->loc); @@ -786,8 +854,7 @@ SlangResult LanguageServer::signatureHelp( StringBuilder docSB; auto humaneLoc = version->linkage->getSourceManager()->getHumaneLoc(declRef.getLoc(), SourceLocType::Actual); _tryGetDocumentation(docSB, version, declRef.getDecl()); - - docSB << "Defined in " << humaneLoc.pathInfo.foundPath << "(" << humaneLoc.line << ")\n"; + appendDefinitionLocation(docSB, m_workspace, humaneLoc); sigInfo.documentation.value = docSB.ProduceString(); sigInfo.documentation.kind = "markdown"; @@ -1013,14 +1080,12 @@ SlangResult LanguageServer::onTypeFormatting(const LanguageServerProtocol::Docum void LanguageServer::publishDiagnostics() { - time_t timeNow = 0; - time(&timeNow); - if (timeNow - m_lastDiagnosticUpdateTime < 3) + if (std::chrono::system_clock::now() - m_lastDiagnosticUpdateTime < std::chrono::milliseconds(1000)) { return; } - m_lastDiagnosticUpdateTime = timeNow; + m_lastDiagnosticUpdateTime = std::chrono::system_clock::now(); auto version = m_workspace->getCurrentVersion(); // Send updates to clear diagnostics for files that no longer have any messages. @@ -1166,6 +1231,25 @@ void LanguageServer::updateInlayHintOptions(const JSONValue& deducedTypes, const m_inlayHintOptions.showParameterNames = showParameterNames; } +void LanguageServer::updateTraceOptions(const JSONValue& value) +{ + if (value.isValid()) + { + auto container = m_connection->getContainer(); + JSONToNativeConverter converter(container, m_connection->getSink()); + String str; + if (SLANG_SUCCEEDED(converter.convert(value, &str))) + { + if (str == "messages") + m_traceOptions = TraceOptions::Messages; + else if (str == "verbose") + m_traceOptions = TraceOptions::Verbose; + else + m_traceOptions = TraceOptions::Off; + } + } +} + void LanguageServer::sendConfigRequest() { ConfigurationParams args; @@ -1186,6 +1270,8 @@ void LanguageServer::sendConfigRequest() args.items.add(item); item.section = "slang.inlayHints.parameterNames"; args.items.add(item); + item.section = "slangLanguageServer.trace.server"; + args.items.add(item); m_connection->sendCall( ConfigurationParams::methodName, &args, @@ -1255,7 +1341,7 @@ SlangResult LanguageServer::tryGetMacroHoverInfo( sb << "\n```\n\n"; auto humaneLoc = version->linkage->getSourceManager()->getHumaneLoc(def->loc, SourceLocType::Actual); - sb << "Defined in " << humaneLoc.pathInfo.foundPath << "(" << humaneLoc.line << ")\n"; + appendDefinitionLocation(sb, m_workspace, humaneLoc); hover.contents.kind = "markdown"; hover.contents.value = sb.ProduceString(); m_connection->sendResult(&hover, responseId); @@ -1576,7 +1662,7 @@ SlangResult LanguageServer::execute() auto workTime = platform::PerformanceCounter::getElapsedTimeInSeconds(parseEnd); - if (commands.getCount() > 0 && m_initialized) + if (commands.getCount() > 0 && m_initialized && m_traceOptions != TraceOptions::Off) { StringBuilder msgBuilder; msgBuilder << "Server processed " << commands.getCount() << " commands, executed in " |
