Skip to content

Commit 5312283

Browse files
committed
Render [] around optional liquidDoc parameters when hovering over render tag
1 parent 357feaa commit 5312283

File tree

5 files changed

+81
-30
lines changed

5 files changed

+81
-30
lines changed

.changeset/shiny-toys-appear.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@shopify/theme-language-server-common': minor
3+
---
4+
5+
Render `[]` around name of optional liquidDoc parameters when hovering over `{% render snip█pet %}` tag

packages/theme-language-server-common/src/hover/providers/RenderSnippetHoverProvider.spec.ts

+49-22
Original file line numberDiff line numberDiff line change
@@ -16,57 +16,42 @@ describe('Module: RenderSnippetHoverProvider', async () => {
1616
name: 'title',
1717
description: 'The title of the product',
1818
type: 'string',
19+
required: true,
1920
},
2021
{
2122
name: 'border-radius',
2223
description: 'The border radius in px',
2324
type: 'number',
25+
required: false,
2426
},
2527
{
2628
name: 'no-type',
2729
description: 'This parameter has no type',
2830
type: null,
31+
required: true,
2932
},
3033
{
3134
name: 'no-description',
3235
description: null,
3336
type: 'string',
37+
required: true,
3438
},
3539
{
3640
name: 'no-type-or-description',
3741
description: null,
3842
type: null,
43+
required: true,
3944
},
4045
],
4146
},
4247
};
4348

44-
const createProvider = (getSnippetDefinition: GetSnippetDefinitionForURI) => {
45-
return new HoverProvider(
46-
new DocumentManager(),
47-
{
48-
filters: async () => [],
49-
objects: async () => [],
50-
tags: async () => [],
51-
systemTranslations: async () => ({}),
52-
},
53-
async (_rootUri: string) => ({} as MetafieldDefinitionMap),
54-
async () => ({}),
55-
async () => [],
56-
getSnippetDefinition,
57-
);
58-
};
59-
60-
beforeEach(async () => {
61-
getSnippetDefinition = async () => mockSnippetDefinition;
62-
provider = createProvider(getSnippetDefinition);
63-
});
64-
6549
describe('hover', () => {
6650
it('should return snippet definition with all parameters', async () => {
51+
provider = createProvider(async () => mockSnippetDefinition);
6752
await expect(provider).to.hover(
6853
`{% render 'product-car█d' %}`,
69-
'### product-card\n\n**Parameters:**\n- `title`: string - The title of the product\n- `border-radius`: number - The border radius in px\n- `no-type` - This parameter has no type\n- `no-description`: string\n- `no-type-or-description`',
54+
'### product-card\n\n**Parameters:**\n- `title`: string - The title of the product\n- `[border-radius]`: number - The border radius in px\n- `no-type` - This parameter has no type\n- `no-description`: string\n- `no-type-or-description`',
7055
);
7156
});
7257

@@ -86,5 +71,47 @@ describe('Module: RenderSnippetHoverProvider', async () => {
8671
await expect(provider).to.hover(`{% assign asdf = 'snip█pet' %}`, null);
8772
await expect(provider).to.hover(`{{ 'snip█pet' }}`, null);
8873
});
74+
75+
it('should wrap optional parameters in []', async () => {
76+
provider = createProvider(async () => ({
77+
name: 'product-card',
78+
liquidDoc: {
79+
parameters: [
80+
{
81+
name: 'title',
82+
description: 'The title of the product',
83+
type: 'string',
84+
required: true,
85+
},
86+
{
87+
name: 'border-radius',
88+
description: 'The border radius in px',
89+
type: 'number',
90+
required: false,
91+
},
92+
],
93+
},
94+
}));
95+
await expect(provider).to.hover(
96+
`{% render 'product-car█d' %}`,
97+
'### product-card\n\n**Parameters:**\n- `title`: string - The title of the product\n- `[border-radius]`: number - The border radius in px',
98+
);
99+
});
89100
});
90101
});
102+
103+
const createProvider = (getSnippetDefinition: GetSnippetDefinitionForURI) => {
104+
return new HoverProvider(
105+
new DocumentManager(),
106+
{
107+
filters: async () => [],
108+
objects: async () => [],
109+
tags: async () => [],
110+
systemTranslations: async () => ({}),
111+
},
112+
async (_rootUri: string) => ({} as MetafieldDefinitionMap),
113+
async () => ({}),
114+
async () => [],
115+
getSnippetDefinition,
116+
);
117+
};

packages/theme-language-server-common/src/hover/providers/RenderSnippetHoverProvider.ts

+12-7
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,7 @@ export class RenderSnippetHoverProvider implements BaseHoverProvider {
5050
const parts = [`### ${snippetDefinition.name}`];
5151

5252
if (liquidDoc.parameters?.length) {
53-
const parameters = liquidDoc.parameters
54-
?.map(
55-
({ name, type, description }: LiquidDocParameter) =>
56-
`- \`${name}\`${type ? `: ${type}` : ''}${description ? ` - ${description}` : ''}`,
57-
)
58-
.join('\n');
59-
53+
const parameters = this.buildParameters(liquidDoc.parameters);
6054
parts.push('', '**Parameters:**', parameters);
6155
}
6256

@@ -67,4 +61,15 @@ export class RenderSnippetHoverProvider implements BaseHoverProvider {
6761
},
6862
};
6963
}
64+
65+
private buildParameters(parameters: LiquidDocParameter[]) {
66+
return parameters
67+
.map(({ name, type, description, required }: LiquidDocParameter) => {
68+
const nameStr = required ? `\`${name}\`` : `\`[${name}]\``;
69+
const typeStr = type ? `: ${type}` : '';
70+
const descStr = description ? ` - ${description}` : '';
71+
return `- ${nameStr}${typeStr}${descStr}`;
72+
})
73+
.join('\n');
74+
}
7075
}

packages/theme-language-server-common/src/liquidDoc.spec.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { toSourceCode } from '@shopify/theme-check-common';
44
import { describe } from 'vitest';
55
import { getSnippetDefinition } from './liquidDoc';
66

7-
describe('Unit: makeGetLiquidDocDefinitions', () => {
7+
describe('Unit: getSnippetDefinition', () => {
88
function toAST(code: string) {
99
return toSourceCode('/tmp/foo.liquid', code).ast as LiquidHtmlNode;
1010
}
@@ -31,6 +31,7 @@ describe('Unit: makeGetLiquidDocDefinitions', () => {
3131
{% doc %}
3232
@param {String} firstParam - The first param
3333
@param {Number} secondParam - The second param
34+
@param {String} [optionalParam] - The optional param
3435
@param paramWithNoType - param with no type
3536
@param paramWithOnlyName
3637
@param {Number} paramWithNoDescription
@@ -46,26 +47,37 @@ describe('Unit: makeGetLiquidDocDefinitions', () => {
4647
name: 'firstParam',
4748
description: 'The first param',
4849
type: 'String',
50+
required: true,
4951
},
5052
{
5153
name: 'secondParam',
5254
description: 'The second param',
5355
type: 'Number',
56+
required: true,
57+
},
58+
{
59+
name: 'optionalParam',
60+
description: 'The optional param',
61+
type: 'String',
62+
required: false,
5463
},
5564
{
5665
name: 'paramWithNoType',
5766
description: 'param with no type',
5867
type: null,
68+
required: true,
5969
},
6070
{
6171
name: 'paramWithOnlyName',
6272
description: null,
6373
type: null,
74+
required: true,
6475
},
6576
{
6677
name: 'paramWithNoDescription',
6778
description: null,
6879
type: 'Number',
80+
required: true,
6981
},
7082
],
7183
},

packages/theme-language-server-common/src/liquidDoc.ts

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export type LiquidDocParameter = {
2222
name: string;
2323
description: string | null;
2424
type: string | null;
25+
required: boolean;
2526
};
2627

2728
export function getSnippetDefinition(
@@ -36,6 +37,7 @@ export function getSnippetDefinition(
3637
name: node.paramName.value,
3738
description: node.paramDescription?.value ?? null,
3839
type: node.paramType?.value ?? null,
40+
required: node.required,
3941
};
4042
},
4143
},

0 commit comments

Comments
 (0)