Skip to content

Commit

Permalink
Merge pull request #666 from Shopify/jm/liquid_doc_type
Browse files Browse the repository at this point in the history
Add parsing + prettier support for param type in {% doc %} tags
  • Loading branch information
jamesmengo authored Dec 19, 2024
2 parents 4bf7625 + 60f93b8 commit 169d143
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 10 deletions.
3 changes: 2 additions & 1 deletion packages/liquid-html-parser/grammar/liquid-html.ohm
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,8 @@ LiquidDoc <: Helpers {
| fallbackNode

fallbackNode = "@" anyExceptStar<newline>
paramNode = "@param" space* (paramName)? (space+ (paramDescription))?
paramNode = "@param" space* (paramType)? space* (paramName)? paramDescription?
paramType = "{" anyExceptStar<"}"> "}"
paramName = identifierCharacter+
paramDescription = (~newline identifierCharacter | space)+
}
Expand Down
15 changes: 15 additions & 0 deletions packages/liquid-html-parser/src/stage-1-cst.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,21 @@ describe('Unit: Stage 1 (CST)', () => {
expectPath(cst, '0.children.0.paramDescription.value').to.equal('param with description');
});

it('should parse @param with type', () => {
const testStr = `{% doc %} @param {String} paramWithType {% enddoc %}`;
cst = toCST(testStr);

expectPath(cst, '0.children.0.type').to.equal('LiquidDocParamNode');
expectPath(cst, '0.children.0.paramName.value').to.equal('paramWithType');

expectPath(cst, '0.children.0.paramType.type').to.equal('TextNode');
expectPath(cst, '0.children.0.paramType.value').to.equal('String');
expectPath(cst, '0.children.0.paramType.locStart').to.equal(testStr.indexOf('{String}'));
expectPath(cst, '0.children.0.paramType.locEnd').to.equal(
testStr.indexOf('{String}') + '{String}'.length,
);
});

it('should parse unsupported doc tags as text nodes', () => {
const testStr = `{% doc %} @unsupported this tag is not supported {% enddoc %}`;
cst = toCST(testStr);
Expand Down
15 changes: 13 additions & 2 deletions packages/liquid-html-parser/src/stage-1-cst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export interface ConcreteLiquidDocParamNode
value: string;
paramName: ConcreteTextNode;
paramDescription: ConcreteTextNode;
paramType: ConcreteTextNode;
}

export interface ConcreteHtmlNodeBase<T> extends ConcreteBasicNode<T> {
Expand Down Expand Up @@ -1336,8 +1337,18 @@ function toLiquidDocAST(source: string, matchingSource: string, offset: number)
locStart,
locEnd,
source,
paramType: function (nodes: Node[]) {
const typeNode = nodes[2];
return {
type: ConcreteNodeTypes.TextNode,
value: typeNode.sourceString.slice(1, -1).trim(),
source,
locStart: offset + typeNode.source.startIdx,
locEnd: offset + typeNode.source.endIdx,
};
},
paramName: function (nodes: Node[]) {
const nameNode = nodes[2];
const nameNode = nodes[4];
return {
type: ConcreteNodeTypes.TextNode,
value: nameNode.sourceString.trim(),
Expand All @@ -1347,7 +1358,7 @@ function toLiquidDocAST(source: string, matchingSource: string, offset: number)
};
},
paramDescription: function (nodes: Node[]) {
const descriptionNode = nodes[4];
const descriptionNode = nodes[5];
return {
type: ConcreteNodeTypes.TextNode,
value: descriptionNode.sourceString.trim(),
Expand Down
4 changes: 3 additions & 1 deletion packages/liquid-html-parser/src/stage-2-ast.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1232,7 +1232,7 @@ describe('Unit: Stage 2 (AST)', () => {
ast = toLiquidAST(`
{% doc -%}
@param asdf
@param paramWithDescription param with description
@param {String} paramWithDescription param with description
@unsupported this node falls back to a text node
{%- enddoc %}
`);
Expand All @@ -1253,6 +1253,8 @@ describe('Unit: Stage 2 (AST)', () => {
expectPath(ast, 'children.0.body.nodes.1.paramDescription.value').to.eql(
'param with description',
);
expectPath(ast, 'children.0.body.nodes.1.paramType.type').to.eql('TextNode');
expectPath(ast, 'children.0.body.nodes.1.paramType.value').to.eql('String');

expectPath(ast, 'children.0.body.nodes.2.type').to.eql('TextNode');
expectPath(ast, 'children.0.body.nodes.2.value').to.eql(
Expand Down
7 changes: 7 additions & 0 deletions packages/liquid-html-parser/src/stage-2-ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,7 @@ export interface LiquidDocParamNode extends ASTNode<NodeTypes.LiquidDocParamNode
value: string;
paramDescription: TextNode;
paramName: TextNode;
paramType: TextNode;
}

export interface ASTNode<T> {
Expand Down Expand Up @@ -1295,6 +1296,12 @@ function buildAst(
position: position(node.paramDescription),
source: node.paramDescription.source,
},
paramType: {
type: NodeTypes.TextNode,
value: node.paramType.value,
position: position(node.paramType),
source: node.paramType.source,
},
});
break;
}
Expand Down
21 changes: 15 additions & 6 deletions packages/prettier-plugin-liquid/src/printer/print/liquid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -513,12 +513,21 @@ export function printLiquidDocParam(
_args: LiquidPrinterArgs,
): Doc {
const node = path.getValue();
return [
node.name,
' ',
node.paramName.value,
node.paramDescription.value ? ' ' + node.paramDescription.value : '',
];
const parts: Doc[] = ['@param'];

if (node.paramType.value) {
parts.push(' ', `{${node.paramType.value}}`);
}

if (node.paramName.value) {
parts.push(' ', node.paramName.value);
}

if (node.paramDescription.value) {
parts.push(' ', node.paramDescription.value);
}

return parts;
}

function innerLeadingWhitespace(node: LiquidTag | LiquidBranch) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ It should trim whitespace between nodes
{% doc %}
@param paramName param with description
{% enddoc %}

It should format the param type
{% doc %}
@param {string} paramName param with description
{% enddoc %}
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ It should trim whitespace between nodes
{% doc %}
@param paramName param with description
{% enddoc %}

It should format the param type
{% doc %}
@param { string } paramName param with description
{% enddoc %}

0 comments on commit 169d143

Please sign in to comment.