Skip to content

Commit

Permalink
Add liquidDocParam handling to stage2 AST
Browse files Browse the repository at this point in the history
- Updated the `toLiquidDocAST` function to include handling for `@param` syntax and fallback text node
  • Loading branch information
jamesmengo committed Dec 4, 2024
1 parent 740599d commit 944ecb4
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 20 deletions.
12 changes: 6 additions & 6 deletions packages/liquid-html-parser/src/stage-1-cst.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -980,16 +980,16 @@ describe('Unit: Stage 1 (CST)', () => {

it('should parse doc tags', () => {
for (const { toCST, expectPath } of testCases) {
const testStr = `{% doc -%}
@param asdf
@unsupported
{%- enddoc %}`;
const testStr =
'{% doc -%} @param asdf\n@unsupported this tag should fall back {%- enddoc %}';

cst = toCST(testStr);

expectPath(cst, '0.type').to.equal('LiquidRawTag');
expectPath(cst, '0.name').to.equal('doc');
expectPath(cst, '0.body').to.include('@param asdf');
expectPath(cst, '0.body').to.equal(
' @param asdf\n@unsupported this tag should fall back ',
);
expectPath(cst, '0.whitespaceStart').to.equal('');
expectPath(cst, '0.whitespaceEnd').to.equal('-');
expectPath(cst, '0.delimiterWhitespaceStart').to.equal('-');
Expand All @@ -1006,7 +1006,7 @@ describe('Unit: Stage 1 (CST)', () => {
expectPath(cst, '0.children.1.type').to.equal('TextNode');
expectPath(cst, '0.children.1.locStart').to.equal(testStr.indexOf('@unsupported'));
expectPath(cst, '0.children.1.locEnd').to.equal(
testStr.indexOf('@unsupported') + '@unsupported'.length,
testStr.indexOf('@unsupported') + '@unsupported this tag should fall back '.length,
);
}
});
Expand Down
13 changes: 13 additions & 0 deletions packages/liquid-html-parser/src/stage-1-cst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1306,14 +1306,27 @@ function toLiquidDocAST(source: string, matchingSource: string, offset: number)

const LiquidDocMappings: Mapping = {
Node: 0,
textNode: {
type: ConcreteNodeTypes.TextNode,
value: function () {
return (this as any).sourceString;
},
locStart,
locEnd,
source,
},
paramNode: {
type: ConcreteNodeTypes.LiquidDocParamNode,
name: 0,
locStart,
locEnd,
source,
},
fallbackNode: {
type: ConcreteNodeTypes.TextNode,
value: function () {
return (this as any).sourceString;
},
locStart,
locEnd,
source,
Expand Down
23 changes: 11 additions & 12 deletions packages/liquid-html-parser/src/stage-2-ast.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1229,22 +1229,21 @@ describe('Unit: Stage 2 (AST)', () => {
expectPath(ast, 'children.0.body.type').toEqual('RawMarkup');
expectPath(ast, 'children.0.body.nodes').toEqual([]);

ast = toLiquidAST(`{% doc -%} single line doc {%- enddoc %}`);
ast = toLiquidAST(`
{% doc -%}
@param asdf
@unsupported this node falls back to a text node
{%- enddoc %}
`);
expectPath(ast, 'children.0.type').to.eql('LiquidRawTag');
expectPath(ast, 'children.0.name').to.eql('doc');
expectPath(ast, 'children.0.body.value').to.eql(' single line doc ');
expectPath(ast, 'children.0.body.nodes.0.type').toEqual('TextNode');
expectPath(ast, 'children.0.body.nodes.0.type').to.eql('LiquidDocParamNode');
expectPath(ast, 'children.0.body.nodes.0.name').to.eql('@param');

ast = toLiquidAST(`{% doc -%}
multi line doc
multi line doc
{%- enddoc %}`);
expectPath(ast, 'children.0.type').to.eql('LiquidRawTag');
expectPath(ast, 'children.0.name').to.eql('doc');
expectPath(ast, 'children.0.body.nodes.0.value').to.eql(
`multi line doc\n multi line doc`,
expectPath(ast, 'children.0.body.nodes.1.type').to.eql('TextNode');
expectPath(ast, 'children.0.body.nodes.1.value').to.eql(
'@unsupported this node falls back to a text node',
);
expectPath(ast, 'children.0.body.nodes.0.type').toEqual('TextNode');
});

it('should parse unclosed tables with assignments', () => {
Expand Down
20 changes: 18 additions & 2 deletions packages/liquid-html-parser/src/stage-2-ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ import {
LiquidHtmlConcreteNode,
ConcreteLiquidTagBaseCase,
ConcreteLiquidTagContentForMarkup,
LiquidDocCST,
} from './stage-1-cst';
import { Comparators, NamedTags, NodeTypes, nonTraversableProperties, Position } from './types';
import { assertNever, deepGet, dropLast } from './utils';
Expand Down Expand Up @@ -107,7 +108,8 @@ export type LiquidHtmlNode =
| RenderVariableExpression
| LiquidLogicalExpression
| LiquidComparison
| TextNode;
| TextNode
| LiquidDocParamNode;

/** The root node of all LiquidHTML ASTs. */
export interface DocumentNode extends ASTNode<NodeTypes.Document> {
Expand Down Expand Up @@ -754,6 +756,10 @@ export interface TextNode extends ASTNode<NodeTypes.TextNode> {
value: string;
}

export interface LiquidDocParamNode extends ASTNode<NodeTypes.LiquidDocParamNode> {
name: string;
}

export interface ASTNode<T> {
/**
* The type of the node, as a string.
Expand Down Expand Up @@ -1103,7 +1109,7 @@ export function cstToAst(
}

function buildAst(
cst: LiquidHtmlCST | LiquidCST | ConcreteAttributeNode[],
cst: LiquidHtmlCST | LiquidCST | LiquidDocCST | ConcreteAttributeNode[],
options: ASTBuildOptions,
) {
const builder = new ASTBuilder(cst[0].source);
Expand Down Expand Up @@ -1268,6 +1274,16 @@ function buildAst(
break;
}

case ConcreteNodeTypes.LiquidDocParamNode: {
builder.push({
type: NodeTypes.LiquidDocParamNode,
name: node.name,
position: position(node),
source: node.source,
});
break;
}

default: {
assertNever(node);
}
Expand Down
1 change: 1 addition & 0 deletions packages/liquid-html-parser/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export enum NodeTypes {
RawMarkup = 'RawMarkup',
RenderMarkup = 'RenderMarkup',
RenderVariableExpression = 'RenderVariableExpression',
LiquidDocParamNode = 'LiquidDocParamNode',
}

// These are officially supported with special node types
Expand Down

0 comments on commit 944ecb4

Please sign in to comment.