[tintd] Improve signature help
Use the 'documentation' field of SignatureInformation to hold the
template constraints. Improves the visual quality of this popup in
VSCode.
Bug: tint:2127
Change-Id: I6b523e9ef92809306eb09278ce64ef018cca29f9
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/183001
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/wgsl/ls/signature_help.cc b/src/tint/lang/wgsl/ls/signature_help.cc
index 6e4f422..d0f1850 100644
--- a/src/tint/lang/wgsl/ls/signature_help.cc
+++ b/src/tint/lang/wgsl/ls/signature_help.cc
@@ -25,6 +25,8 @@
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#include <sstream>
+#include "src/tint/lang/wgsl/diagnostic_severity.h"
#include "src/tint/lang/wgsl/ls/server.h"
#include "langsvr/lsp/comparators.h"
@@ -34,6 +36,7 @@
#include "src/tint/lang/wgsl/sem/call.h"
#include "src/tint/utils/rtti/switch.h"
#include "src/tint/utils/text/string_stream.h"
+#include "src/tint/utils/text/text_style.h"
namespace lsp = langsvr::lsp;
@@ -98,72 +101,67 @@
}
/// PrintOverload() emits a description of the intrinsic overload @p overload of the function with
-/// name @p intrinsic_name to @p ss.
-void PrintOverload(StyledText& ss,
+/// name @p intrinsic_name to @p name and @p description.
+void PrintOverload(std::string& name,
+ StyledText& description,
core::intrinsic::Context& context,
const core::intrinsic::OverloadInfo& overload,
std::string_view intrinsic_name) {
- // Restore old style before returning.
- auto prev_style = ss.Style();
- TINT_DEFER(ss << prev_style);
-
core::intrinsic::TemplateState templates;
auto earliest_eval_stage = core::EvaluationStage::kConstant;
- ss << style::Code << style::Function(intrinsic_name);
-
+ StyledText name_st;
+ name_st << style::Code << intrinsic_name;
if (overload.num_explicit_templates > 0) {
- ss << "<";
+ name_st << "<";
for (size_t i = 0; i < overload.num_explicit_templates; i++) {
const auto& tmpl = context.data[overload.templates + i];
if (i > 0) {
- ss << ", ";
+ name_st << ", ";
}
- ss << style::Type(tmpl.name) << " ";
+ name_st << style::Type(tmpl.name) << " ";
}
- ss << ">";
+ name_st << ">";
}
- ss << "(";
+ name_st << "(";
for (size_t i = 0; i < overload.num_parameters; i++) {
const auto& parameter = context.data[overload.parameters + i];
auto* matcher_indices = context.data[parameter.matcher_indices];
if (i > 0) {
- ss << ", ";
+ name_st << ", ";
}
if (parameter.usage != core::ParameterUsage::kNone) {
- ss << style::Variable(parameter.usage, ": ");
+ name_st << style::Variable(parameter.usage, ": ");
}
- context.Match(templates, overload, matcher_indices, earliest_eval_stage).PrintType(ss);
+ context.Match(templates, overload, matcher_indices, earliest_eval_stage).PrintType(name_st);
}
- ss << ")";
+ name_st << ")";
if (overload.return_matcher_indices.IsValid()) {
- ss << " -> ";
+ name_st << " -> ";
auto* matcher_indices = context.data[overload.return_matcher_indices];
- context.Match(templates, overload, matcher_indices, earliest_eval_stage).PrintType(ss);
+ context.Match(templates, overload, matcher_indices, earliest_eval_stage).PrintType(name_st);
}
- bool first = true;
- auto separator = [&] {
- ss << style::Plain(first ? " where:\n " : "\n ");
- first = false;
- };
+ { // Like name_st.Plain(), but no code quotes.
+ StringStream ss;
+ name_st.Walk([&](std::string_view text, TextStyle) { ss << text; });
+ name = ss.str();
+ }
for (size_t i = 0; i < overload.num_templates; i++) {
auto& tmpl = context.data[overload.templates + i];
if (auto* matcher_indices = context.data[tmpl.matcher_indices]) {
- separator();
-
- ss << style::Type(tmpl.name) << style::Plain(" is ");
+ description << "\n" << style::Type(tmpl.name) << style::Plain(" is ");
if (tmpl.kind == core::intrinsic::TemplateInfo::Kind::kType) {
context.Match(templates, overload, matcher_indices, earliest_eval_stage)
- .PrintType(ss);
+ .PrintType(description);
} else {
context.Match(templates, overload, matcher_indices, earliest_eval_stage)
- .PrintNum(ss);
+ .PrintNum(description);
}
}
}
@@ -193,7 +191,6 @@
auto& data = wgsl::intrinsic::Dialect::kData;
auto& builtins = data.builtins;
auto& intrinsic_info = builtins[static_cast<size_t>(target->Fn())];
- std::string name{wgsl::str(target->Fn())};
for (size_t i = 0; i < intrinsic_info.num_overloads; i++) {
auto& overload = data[intrinsic_info.overloads + i];
@@ -203,13 +200,15 @@
auto type_mgr = core::type::Manager::Wrap(program.Types());
auto symbols = SymbolTable::Wrap(program.Symbols());
- StyledText ss;
+ StyledText description;
core::intrinsic::Context ctx{data, type_mgr, symbols};
- PrintOverload(ss, ctx, overload, name);
+ std::string name;
+ PrintOverload(name, description, ctx, overload, wgsl::str(target->Fn()));
lsp::SignatureInformation sig;
sig.parameters = params;
- sig.label = ss.Plain();
+ sig.label = name;
+ sig.documentation = Conv(description);
help.signatures.push_back(sig);
if (&overload == &target->Overload()) {
diff --git a/src/tint/lang/wgsl/ls/signature_help_test.cc b/src/tint/lang/wgsl/ls/signature_help_test.cc
index 31fcaba..f1f67b6 100644
--- a/src/tint/lang/wgsl/ls/signature_help_test.cc
+++ b/src/tint/lang/wgsl/ls/signature_help_test.cc
@@ -55,9 +55,15 @@
/* documentation */ {},
});
+ lsp::MarkupContent documentation;
+ documentation.kind = lsp::MarkupKind::kMarkdown;
+ documentation.value =
+ R"(
+`T` is `abstract-float`, `abstract-int`, `f32`, `i32`, `u32` or `f16`)";
+
lsp::SignatureInformation sig{};
- sig.label = R"('max(T, T) -> T' where:
- 'T' is 'abstract-float', 'abstract-int', 'f32', 'i32', 'u32' or 'f16')";
+ sig.label = "max(T, T) -> T";
+ sig.documentation = documentation;
sig.parameters = std::move(parameters);
out.push_back(std::move(sig));
@@ -74,9 +80,15 @@
/* documentation */ {},
});
+ lsp::MarkupContent documentation;
+ documentation.kind = lsp::MarkupKind::kMarkdown;
+ documentation.value =
+ R"(
+`T` is `abstract-float`, `abstract-int`, `f32`, `i32`, `u32` or `f16`)";
+
lsp::SignatureInformation sig{};
- sig.label = R"('max(vecN<T>, vecN<T>) -> vecN<T>' where:
- 'T' is 'abstract-float', 'abstract-int', 'f32', 'i32', 'u32' or 'f16')";
+ sig.label = R"(max(vecN<T>, vecN<T>) -> vecN<T>)";
+ sig.documentation = documentation;
sig.parameters = std::move(parameters);
out.push_back(std::move(sig));