diff options
| author | Yong He <yonghe@outlook.com> | 2025-07-29 07:35:58 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-29 14:35:58 +0000 |
| commit | 855b1a262f3a769d44765e78f94e566d875b9286 (patch) | |
| tree | ea41db3717f55aa5032b1f04d71729a452ec68b2 /source/slang/slang-language-server.cpp | |
| parent | ea6f8551ad38f2bcc32b542fd52ce17f3829cbeb (diff) | |
[Language Server]: Show signature help on generic parameters. (#7913)
* Show signature help on generic parameters.
* Fix.
* Update tests.
* slang-test: make vvl error go through stderr.
* update slang-rhi
* Update slang-rhi
Diffstat (limited to 'source/slang/slang-language-server.cpp')
| -rw-r--r-- | source/slang/slang-language-server.cpp | 59 |
1 files changed, 54 insertions, 5 deletions
diff --git a/source/slang/slang-language-server.cpp b/source/slang/slang-language-server.cpp index 048fcb44b..dcf7419bd 100644 --- a/source/slang/slang-language-server.cpp +++ b/source/slang/slang-language-server.cpp @@ -160,6 +160,7 @@ SlangResult LanguageServer::parseNextMessage() caps.semanticTokensProvider.full = true; caps.semanticTokensProvider.range = false; caps.signatureHelpProvider.triggerCharacters.add("("); + caps.signatureHelpProvider.triggerCharacters.add("<"); caps.signatureHelpProvider.triggerCharacters.add(","); caps.signatureHelpProvider.retriggerCharacters.add(","); for (auto tokenType : kSemanticTokenTypes) @@ -1705,14 +1706,33 @@ LanguageServerResult<LanguageServerProtocol::SignatureHelp> LanguageServerCore:: bool useOriginalExpr = true; if (auto originalDeclRefExpr = as<DeclRefExpr>(appExpr->originalFunctionExpr)) { + // If the original expr doesn't map to a valid declref, we will use the checked + // func expr instead. if (!originalDeclRefExpr->declRef) { useOriginalExpr = false; } } + if (as<GenericAppExpr>(appExpr->originalFunctionExpr)) + { + if (as<DeclRefExpr>(funcExpr)) + { + // If the original function is a fully specialized generic app, use the checked func + // expr for signature help. + useOriginalExpr = false; + } + } if (useOriginalExpr) funcExpr = appExpr->originalFunctionExpr; } + if (auto partialGenAppExpr = as<PartiallyAppliedGenericExpr>(funcExpr)) + { + funcExpr = partialGenAppExpr->originalExpr; + } + if (auto genAppExpr = as<GenericAppExpr>(funcExpr)) + { + funcExpr = genAppExpr->functionExpr; + } if (!funcExpr) { return std::nullopt; @@ -1741,6 +1761,22 @@ LanguageServerResult<LanguageServerProtocol::SignatureHelp> LanguageServerCore:: if (!declRef.getDecl()) return; + // If funcExpr is a direct reference to a generic, we should either + // show the generic signature if we are inside `<>`, or show the function + // parameter signature if we are inside `()`. If we are inside `()`, we will + // need to form a decl ref to the inner decl and show its signature. + if (!as<GenericAppExpr>(appExpr)) + { + if (auto genDeclRef = as<GenericDecl>(declRef)) + { + declRef = createDefaultSubstitutionsIfNeeded( + version->linkage->getASTBuilder(), + &semanticsVisitor, + version->linkage->getASTBuilder()->getMemberDeclRef( + declRef, + genDeclRef.getDecl()->inner)); + } + } // If we have a better match than the current best, we will update response.activeSignature // to this signature. if (auto callableDeclRef = declRef.as<CallableDecl>()) @@ -1832,12 +1868,20 @@ LanguageServerResult<LanguageServerProtocol::SignatureHelp> LanguageServerCore:: { if (auto typeType = as<TypeType>(declRefExpr->type.type)) { - // Look for initializers - auto ctors = - semanticsVisitor.lookupConstructorsInType(typeType->getType(), declRefExpr->scope); - for (auto ctor : ctors) + if (as<GenericDeclRefType>(typeType->getType())) { - addDeclRef(ctor.declRef); + addDeclRef(declRefExpr->declRef); + } + else + { + // Look for initializers + auto ctors = semanticsVisitor.lookupConstructorsInType( + typeType->getType(), + declRefExpr->scope); + for (auto ctor : ctors) + { + addDeclRef(ctor.declRef); + } } } else @@ -1847,8 +1891,13 @@ LanguageServerResult<LanguageServerProtocol::SignatureHelp> LanguageServerCore:: } else if (auto overloadedExpr = as<OverloadedExpr>(funcExpr)) { + bool isGenApp = as<GenericAppExpr>(appExpr) != nullptr; for (auto item : overloadedExpr->lookupResult2) { + // Skip non-generic candidates if we are inside a generic app expr (e.g. + // `f<WE_ARE_HERE>`). + if (isGenApp && !as<GenericDecl>(item.declRef)) + continue; addDeclRef(item.declRef); } } |
