summaryrefslogtreecommitdiff
path: root/source/slang/slang-language-server-inlay-hints.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-06-27 15:36:00 -0700
committerGitHub <noreply@github.com>2022-06-27 15:36:00 -0700
commitb7638b8fffe78ade657f361cadc08dffc8c10acf (patch)
treee27a141cfc6a9cc77356b8cba27b41c495d4ee27 /source/slang/slang-language-server-inlay-hints.cpp
parent62d16a23b0ecd72dc624abd7e10b373c40adaa90 (diff)
Language server fixes and improvements (#2304)
* Language server: Inlay hints. * Signature help for base exprs that is not a declref. * Fix checking of jvp operator. * Fix. * Add clang-format based auto formatting. * Fix clang error. * Fix clang-format discovery logic. * Fine tune auto formatting and completion experience. * Update macos workflow. * Fixes to configurations. * Fix parser recovery to trigger completion for index exprs. * Typo fix. Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-language-server-inlay-hints.cpp')
-rw-r--r--source/slang/slang-language-server-inlay-hints.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/source/slang/slang-language-server-inlay-hints.cpp b/source/slang/slang-language-server-inlay-hints.cpp
new file mode 100644
index 000000000..22c9ce21e
--- /dev/null
+++ b/source/slang/slang-language-server-inlay-hints.cpp
@@ -0,0 +1,120 @@
+#include "slang-language-server-inlay-hints.h"
+#include "slang-visitor.h"
+#include "slang-ast-support-types.h"
+#include "slang-ast-iterator.h"
+#include "slang-language-server.h"
+#include "../core/slang-char-util.h"
+
+namespace Slang
+{
+List<LanguageServerProtocol::InlayHint> getInlayHints(
+ Linkage* linkage,
+ Module* module,
+ UnownedStringSlice fileName,
+ DocumentVersion* doc,
+ LanguageServerProtocol::Range range,
+ const InlayHintOptions& options)
+{
+ List<LanguageServerProtocol::InlayHint> result;
+ auto manager = linkage->getSourceManager();
+ auto docText = doc->getText().getUnownedSlice();
+ iterateAST(fileName, manager, module->getModuleDecl(), [&](SyntaxNode* node)
+ {
+ if (auto invokeExpr = as<InvokeExpr>(node))
+ {
+ if (!options.showParameterNames)
+ return;
+ auto humaneLoc = manager->getHumaneLoc(node->loc);
+ if (humaneLoc.line - 1 < range.start.line || humaneLoc.line - 1 > range.end.line)
+ return;
+ if (humaneLoc.pathInfo.foundPath != fileName)
+ return;
+ auto funcExpr = as<DeclRefExpr>(invokeExpr->functionExpr);
+ if (!funcExpr)
+ return;
+ if (as<ConstructorDecl>(funcExpr->declRef.getDecl()))
+ return;
+ auto callable = as<CallableDecl>(funcExpr->declRef.getDecl());
+ if (!callable)
+ return;
+ auto params = callable->getParameters();
+ Index i = 0;
+ for (auto param : params)
+ {
+ if (i >= invokeExpr->argumentDelimeterLocs.getCount() - 1)
+ break;
+ if (auto name = param->getName())
+ {
+ LanguageServerProtocol::InlayHint hint;
+ auto loc = manager->getHumaneLoc(invokeExpr->argumentDelimeterLocs[i]);
+ auto offset = doc->getOffset(loc.line, loc.column);
+ offset++;
+ while (offset < docText.getLength() && CharUtil::isWhitespace(docText[offset]))
+ offset++;
+ Index posLine, posCol;
+ doc->offsetToLineCol(offset, posLine, posCol);
+ Index utf16line, utf16col;
+ doc->oneBasedUTF8LocToZeroBasedUTF16Loc(posLine, posCol, utf16line, utf16col);
+ hint.position.line = (int)utf16line;
+ hint.position.character = (int)utf16col;
+ hint.paddingLeft = false;
+ hint.kind = LanguageServerProtocol::kInlayHintKindParameter;
+ StringBuilder lblSb;
+ if (param->hasModifier<OutModifier>()) lblSb << "out ";
+ else if (param->hasModifier<InOutModifier>()) lblSb << "inout ";
+ else if (param->hasModifier<RefModifier>()) lblSb << "ref ";
+ lblSb << name->text;
+ lblSb << ":";
+ hint.label = lblSb.ProduceString();
+ result.add(hint);
+ }
+ i++;
+ }
+ }
+ else if (auto varDecl = as<VarDeclBase>(node))
+ {
+ if (!options.showDeducedType)
+ return;
+ auto humaneLoc = manager->getHumaneLoc(node->loc);
+ if (humaneLoc.line - 1 < range.start.line || humaneLoc.line - 1 > range.end.line)
+ return;
+ if (humaneLoc.pathInfo.foundPath != fileName)
+ return;
+ if (varDecl->type.exp)
+ return;
+ if (!varDecl->type.type)
+ return;
+ if (as<ErrorType>(varDecl->type.type))
+ return;
+ if (!varDecl->getName())
+ return;
+
+ LanguageServerProtocol::InlayHint hint;
+ auto loc = manager->getHumaneLoc(varDecl->nameAndLoc.loc);
+ auto offset = doc->getOffset(loc.line, loc.column);
+ offset++;
+ while (offset < docText.getLength() && _isIdentifierChar(docText[offset]))
+ offset++;
+ Index posLine, posCol;
+ doc->offsetToLineCol(offset, posLine, posCol);
+ Index utf16line, utf16col;
+ doc->oneBasedUTF8LocToZeroBasedUTF16Loc(posLine, posCol, utf16line, utf16col);
+ hint.position.line = (int)utf16line;
+ hint.position.character = (int)utf16col;
+ hint.kind = LanguageServerProtocol::kInlayHintKindType;
+ StringBuilder lblSb;
+ lblSb << ": " << varDecl->type.type->toString();
+ hint.label = lblSb.ProduceString();
+
+ LanguageServerProtocol::TextEdit edit;
+ edit.range.start = hint.position;
+ edit.range.end = hint.position;
+ edit.newText = " " + hint.label;
+ hint.textEdits.add(edit);
+ result.add(hint);
+ }
+ });
+ return result;
+}
+
+} // namespace Slang