Skip to content

Commit 169d143

Browse files
authored
Merge pull request #666 from Shopify/jm/liquid_doc_type
Add parsing + prettier support for param type in {% doc %} tags
2 parents 4bf7625 + 60f93b8 commit 169d143

File tree

8 files changed

+65
-10
lines changed

8 files changed

+65
-10
lines changed

packages/liquid-html-parser/grammar/liquid-html.ohm

+2-1
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,8 @@ LiquidDoc <: Helpers {
395395
| fallbackNode
396396

397397
fallbackNode = "@" anyExceptStar<newline>
398-
paramNode = "@param" space* (paramName)? (space+ (paramDescription))?
398+
paramNode = "@param" space* (paramType)? space* (paramName)? paramDescription?
399+
paramType = "{" anyExceptStar<"}"> "}"
399400
paramName = identifierCharacter+
400401
paramDescription = (~newline identifierCharacter | space)+
401402
}

packages/liquid-html-parser/src/stage-1-cst.spec.ts

+15
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,21 @@ describe('Unit: Stage 1 (CST)', () => {
10431043
expectPath(cst, '0.children.0.paramDescription.value').to.equal('param with description');
10441044
});
10451045

1046+
it('should parse @param with type', () => {
1047+
const testStr = `{% doc %} @param {String} paramWithType {% enddoc %}`;
1048+
cst = toCST(testStr);
1049+
1050+
expectPath(cst, '0.children.0.type').to.equal('LiquidDocParamNode');
1051+
expectPath(cst, '0.children.0.paramName.value').to.equal('paramWithType');
1052+
1053+
expectPath(cst, '0.children.0.paramType.type').to.equal('TextNode');
1054+
expectPath(cst, '0.children.0.paramType.value').to.equal('String');
1055+
expectPath(cst, '0.children.0.paramType.locStart').to.equal(testStr.indexOf('{String}'));
1056+
expectPath(cst, '0.children.0.paramType.locEnd').to.equal(
1057+
testStr.indexOf('{String}') + '{String}'.length,
1058+
);
1059+
});
1060+
10461061
it('should parse unsupported doc tags as text nodes', () => {
10471062
const testStr = `{% doc %} @unsupported this tag is not supported {% enddoc %}`;
10481063
cst = toCST(testStr);

packages/liquid-html-parser/src/stage-1-cst.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ export interface ConcreteLiquidDocParamNode
114114
value: string;
115115
paramName: ConcreteTextNode;
116116
paramDescription: ConcreteTextNode;
117+
paramType: ConcreteTextNode;
117118
}
118119

119120
export interface ConcreteHtmlNodeBase<T> extends ConcreteBasicNode<T> {
@@ -1336,8 +1337,18 @@ function toLiquidDocAST(source: string, matchingSource: string, offset: number)
13361337
locStart,
13371338
locEnd,
13381339
source,
1340+
paramType: function (nodes: Node[]) {
1341+
const typeNode = nodes[2];
1342+
return {
1343+
type: ConcreteNodeTypes.TextNode,
1344+
value: typeNode.sourceString.slice(1, -1).trim(),
1345+
source,
1346+
locStart: offset + typeNode.source.startIdx,
1347+
locEnd: offset + typeNode.source.endIdx,
1348+
};
1349+
},
13391350
paramName: function (nodes: Node[]) {
1340-
const nameNode = nodes[2];
1351+
const nameNode = nodes[4];
13411352
return {
13421353
type: ConcreteNodeTypes.TextNode,
13431354
value: nameNode.sourceString.trim(),
@@ -1347,7 +1358,7 @@ function toLiquidDocAST(source: string, matchingSource: string, offset: number)
13471358
};
13481359
},
13491360
paramDescription: function (nodes: Node[]) {
1350-
const descriptionNode = nodes[4];
1361+
const descriptionNode = nodes[5];
13511362
return {
13521363
type: ConcreteNodeTypes.TextNode,
13531364
value: descriptionNode.sourceString.trim(),

packages/liquid-html-parser/src/stage-2-ast.spec.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1232,7 +1232,7 @@ describe('Unit: Stage 2 (AST)', () => {
12321232
ast = toLiquidAST(`
12331233
{% doc -%}
12341234
@param asdf
1235-
@param paramWithDescription param with description
1235+
@param {String} paramWithDescription param with description
12361236
@unsupported this node falls back to a text node
12371237
{%- enddoc %}
12381238
`);
@@ -1253,6 +1253,8 @@ describe('Unit: Stage 2 (AST)', () => {
12531253
expectPath(ast, 'children.0.body.nodes.1.paramDescription.value').to.eql(
12541254
'param with description',
12551255
);
1256+
expectPath(ast, 'children.0.body.nodes.1.paramType.type').to.eql('TextNode');
1257+
expectPath(ast, 'children.0.body.nodes.1.paramType.value').to.eql('String');
12561258

12571259
expectPath(ast, 'children.0.body.nodes.2.type').to.eql('TextNode');
12581260
expectPath(ast, 'children.0.body.nodes.2.value').to.eql(

packages/liquid-html-parser/src/stage-2-ast.ts

+7
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,7 @@ export interface LiquidDocParamNode extends ASTNode<NodeTypes.LiquidDocParamNode
760760
value: string;
761761
paramDescription: TextNode;
762762
paramName: TextNode;
763+
paramType: TextNode;
763764
}
764765

765766
export interface ASTNode<T> {
@@ -1295,6 +1296,12 @@ function buildAst(
12951296
position: position(node.paramDescription),
12961297
source: node.paramDescription.source,
12971298
},
1299+
paramType: {
1300+
type: NodeTypes.TextNode,
1301+
value: node.paramType.value,
1302+
position: position(node.paramType),
1303+
source: node.paramType.source,
1304+
},
12981305
});
12991306
break;
13001307
}

packages/prettier-plugin-liquid/src/printer/print/liquid.ts

+15-6
Original file line numberDiff line numberDiff line change
@@ -513,12 +513,21 @@ export function printLiquidDocParam(
513513
_args: LiquidPrinterArgs,
514514
): Doc {
515515
const node = path.getValue();
516-
return [
517-
node.name,
518-
' ',
519-
node.paramName.value,
520-
node.paramDescription.value ? ' ' + node.paramDescription.value : '',
521-
];
516+
const parts: Doc[] = ['@param'];
517+
518+
if (node.paramType.value) {
519+
parts.push(' ', `{${node.paramType.value}}`);
520+
}
521+
522+
if (node.paramName.value) {
523+
parts.push(' ', node.paramName.value);
524+
}
525+
526+
if (node.paramDescription.value) {
527+
parts.push(' ', node.paramDescription.value);
528+
}
529+
530+
return parts;
522531
}
523532

524533
function innerLeadingWhitespace(node: LiquidTag | LiquidBranch) {

packages/prettier-plugin-liquid/src/test/liquid-doc/fixed.liquid

+5
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,8 @@ It should trim whitespace between nodes
1212
{% doc %}
1313
@param paramName param with description
1414
{% enddoc %}
15+
16+
It should format the param type
17+
{% doc %}
18+
@param {string} paramName param with description
19+
{% enddoc %}

packages/prettier-plugin-liquid/src/test/liquid-doc/index.liquid

+5
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,8 @@ It should trim whitespace between nodes
1212
{% doc %}
1313
@param paramName param with description
1414
{% enddoc %}
15+
16+
It should format the param type
17+
{% doc %}
18+
@param { string } paramName param with description
19+
{% enddoc %}

0 commit comments

Comments
 (0)