diff options
| author | Yong He <yonghe@outlook.com> | 2022-06-27 15:36:00 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-27 15:36:00 -0700 |
| commit | b7638b8fffe78ade657f361cadc08dffc8c10acf (patch) | |
| tree | e27a141cfc6a9cc77356b8cba27b41c495d4ee27 /source/slang/slang-language-server-inlay-hints.cpp | |
| parent | 62d16a23b0ecd72dc624abd7e10b373c40adaa90 (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.cpp | 120 |
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 |
