From a6f73dd6fee3e4f378b3e92012f73c0146dc266d Mon Sep 17 00:00:00 2001 From: JohnnyMorganz Date: Fri, 28 Oct 2022 20:14:21 +0100 Subject: [PATCH] Correctly handle highlighting varargs in sig help --- CHANGELOG.md | 1 + src/operations/SignatureHelp.cpp | 46 +++++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e9f3156..42f302ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fixed signature help highlighting of parameters named `_` - Fixed documentation comments of parent function being attached to a nested function - Use location to determine which parameter is active in signature help +- Correctly handle highlighting variadic arguments in signature help ## [1.12.1] - 2022-10-18 diff --git a/src/operations/SignatureHelp.cpp b/src/operations/SignatureHelp.cpp index 581b802a..6b48f204 100644 --- a/src/operations/SignatureHelp.cpp +++ b/src/operations/SignatureHelp.cpp @@ -88,17 +88,14 @@ std::optional WorkspaceFolder::signatureHelp(const lsp::Sign size_t idx = 0; size_t previousParamPos = 0; - while (it != Luau::end(ftv->argTypes)) + for (; it != Luau::end(ftv->argTypes); it++, idx++) { // If the function has self, and the caller has called as a method (i.e., :), then omit the self parameter // TODO: hasSelf is not always specified, so we manually check for the "self" name (https://github.com/Roblox/luau/issues/551) if (idx == 0 && (ftv->hasSelf || (ftv->argNames.size() > 0 && ftv->argNames[0].has_value() && ftv->argNames[0]->name == "self")) && candidate->self) - { - it++; - idx++; continue; - } + // Show parameter documentation // TODO: parse moonwave docs for param documentation? @@ -126,8 +123,43 @@ std::optional WorkspaceFolder::signatureHelp(const lsp::Sign paramLabel = labelString; parameters.push_back(lsp::ParameterInformation{paramLabel, parameterDocumentation}); - it++; - idx++; + } + + // Handle varargs + if (auto tp = it.tail()) + { + if (auto vtp = Luau::get(*tp); !vtp || !vtp->hidden) + { + // Show parameter documentation + // TODO: parse moonwave docs for param documentation? + lsp::MarkupContent parameterDocumentation{lsp::MarkupKind::Markdown, ""}; + if (baseDocumentationSymbol) + parameterDocumentation.value = + printDocumentation(client->documentation, *baseDocumentationSymbol + "/param/" + std::to_string(idx)); + + // Compute the label + // We attempt to search for the position in the string for this label, and if we don't find it, + // then we give up and just use the string label + std::variant> paramLabel; + std::string labelString = "...: "; + + if (vtp) + labelString += Luau::toString(vtp->ty); + else + labelString += Luau::toString(*tp); + + auto position = label.find(labelString, previousParamPos); + if (position != std::string::npos) + { + auto length = labelString.size(); + previousParamPos = position + length; + paramLabel = std::vector{position, position + length}; + } + else + paramLabel = labelString; + + parameters.push_back(lsp::ParameterInformation{paramLabel, parameterDocumentation}); + } } signatures.push_back(lsp::SignatureInformation{