diff --git a/packages/liquid-html-parser/grammar/liquid-html.ohm b/packages/liquid-html-parser/grammar/liquid-html.ohm index 3d83d0f0..0d481f6c 100644 --- a/packages/liquid-html-parser/grammar/liquid-html.ohm +++ b/packages/liquid-html-parser/grammar/liquid-html.ohm @@ -395,7 +395,8 @@ LiquidDoc <: Helpers { | fallbackNode fallbackNode = "@" anyExceptStar - paramNode = "@param" space* (paramName)? (space+ (paramDescription))? + paramNode = "@param" space* (paramType)? space* (paramName)? paramDescription? + paramType = "{" anyExceptStar<"}"> "}" paramName = identifierCharacter+ paramDescription = (~newline identifierCharacter | space)+ } diff --git a/packages/liquid-html-parser/src/stage-1-cst.spec.ts b/packages/liquid-html-parser/src/stage-1-cst.spec.ts index 32f85e4d..1acf2518 100644 --- a/packages/liquid-html-parser/src/stage-1-cst.spec.ts +++ b/packages/liquid-html-parser/src/stage-1-cst.spec.ts @@ -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); diff --git a/packages/liquid-html-parser/src/stage-1-cst.ts b/packages/liquid-html-parser/src/stage-1-cst.ts index 163a9e4e..272c0a0d 100644 --- a/packages/liquid-html-parser/src/stage-1-cst.ts +++ b/packages/liquid-html-parser/src/stage-1-cst.ts @@ -114,6 +114,7 @@ export interface ConcreteLiquidDocParamNode value: string; paramName: ConcreteTextNode; paramDescription: ConcreteTextNode; + paramType: ConcreteTextNode; } export interface ConcreteHtmlNodeBase extends ConcreteBasicNode { @@ -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(), @@ -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(), diff --git a/packages/liquid-html-parser/src/stage-2-ast.spec.ts b/packages/liquid-html-parser/src/stage-2-ast.spec.ts index c7e19a92..7a4fc308 100644 --- a/packages/liquid-html-parser/src/stage-2-ast.spec.ts +++ b/packages/liquid-html-parser/src/stage-2-ast.spec.ts @@ -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 %} `); @@ -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( diff --git a/packages/liquid-html-parser/src/stage-2-ast.ts b/packages/liquid-html-parser/src/stage-2-ast.ts index 1ba940c8..77ec6607 100644 --- a/packages/liquid-html-parser/src/stage-2-ast.ts +++ b/packages/liquid-html-parser/src/stage-2-ast.ts @@ -760,6 +760,7 @@ export interface LiquidDocParamNode extends ASTNode { @@ -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; } diff --git a/packages/prettier-plugin-liquid/src/printer/print/liquid.ts b/packages/prettier-plugin-liquid/src/printer/print/liquid.ts index 782d45cf..54fae7cc 100644 --- a/packages/prettier-plugin-liquid/src/printer/print/liquid.ts +++ b/packages/prettier-plugin-liquid/src/printer/print/liquid.ts @@ -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) { diff --git a/packages/prettier-plugin-liquid/src/test/liquid-doc/fixed.liquid b/packages/prettier-plugin-liquid/src/test/liquid-doc/fixed.liquid index 1eda1569..04662ec8 100644 --- a/packages/prettier-plugin-liquid/src/test/liquid-doc/fixed.liquid +++ b/packages/prettier-plugin-liquid/src/test/liquid-doc/fixed.liquid @@ -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 %} diff --git a/packages/prettier-plugin-liquid/src/test/liquid-doc/index.liquid b/packages/prettier-plugin-liquid/src/test/liquid-doc/index.liquid index 66f7de6f..aaff7073 100644 --- a/packages/prettier-plugin-liquid/src/test/liquid-doc/index.liquid +++ b/packages/prettier-plugin-liquid/src/test/liquid-doc/index.liquid @@ -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 %}