diff --git a/extensions/ql-vscode/src/view/compare-performance/RAPrettyPrinter.tsx b/extensions/ql-vscode/src/view/compare-performance/RAPrettyPrinter.tsx
index 010523194..d02ef1e9c 100644
--- a/extensions/ql-vscode/src/view/compare-performance/RAPrettyPrinter.tsx
+++ b/extensions/ql-vscode/src/view/compare-performance/RAPrettyPrinter.tsx
@@ -1,4 +1,4 @@
-import { Fragment } from "react";
+import { Fragment, useState } from "react";
import { styled } from "styled-components";
/**
@@ -29,6 +29,21 @@ interface QualifiedName {
args?: QualifiedName[];
}
+function qnameToString(name: QualifiedName): string {
+ const parts: string[] = [];
+ if (name.prefix != null) {
+ parts.push(qnameToString(name.prefix));
+ parts.push("::");
+ }
+ parts.push(name.name);
+ if (name.args != null && name.args.length > 0) {
+ parts.push("<");
+ parts.push(name.args.map(qnameToString).join(","));
+ parts.push(">");
+ }
+ return parts.join("");
+}
+
function tokeniseName(text: string) {
return Array.from(text.matchAll(/:+|<|>|,|"[^"]+"|`[^`]+`|[^:<>,"`]+/g));
}
@@ -137,7 +152,10 @@ class TrieBuilder {
if (args != null) {
result.push("<");
if (trieNodeBeforeArgs.children.size === 1) {
- result.push("...");
+ const argsText = qname
+ .args!.map((arg) => qnameToString(arg))
+ .join(",");
+ result.push({argsText});
} else {
let first = true;
for (const arg of args) {
@@ -157,6 +175,30 @@ class TrieBuilder {
}
}
+const ExpandableTextButton = styled.button`
+ background: none;
+ border: none;
+ cursor: pointer;
+ padding: 0;
+ color: inherit;
+ &:hover {
+ background-color: rgba(128, 128, 128, 0.2);
+ }
+`;
+
+interface ExpandableNamePartProps {
+ children: React.ReactNode;
+}
+
+function ExpandableNamePart(props: ExpandableNamePartProps) {
+ const [isExpanded, setExpanded] = useState(false);
+ return (
+ setExpanded(!isExpanded)}>
+ {isExpanded ? props.children : "..."}
+
+ );
+}
+
/**
* Span enclosing an entire qualified name.
*