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 74d55134e..674834571 100644
--- a/packages/liquid-html-parser/src/stage-1-cst.spec.ts
+++ b/packages/liquid-html-parser/src/stage-1-cst.spec.ts
@@ -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('-');
@@ -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,
);
}
});
diff --git a/packages/liquid-html-parser/src/stage-1-cst.ts b/packages/liquid-html-parser/src/stage-1-cst.ts
index 4cbf7f3b2..9debfb798 100644
--- a/packages/liquid-html-parser/src/stage-1-cst.ts
+++ b/packages/liquid-html-parser/src/stage-1-cst.ts
@@ -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,
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 84848ccb2..ed1c2467f 100644
--- a/packages/liquid-html-parser/src/stage-2-ast.spec.ts
+++ b/packages/liquid-html-parser/src/stage-2-ast.spec.ts
@@ -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', () => {
diff --git a/packages/liquid-html-parser/src/stage-2-ast.ts b/packages/liquid-html-parser/src/stage-2-ast.ts
index 15c7e61cb..370f08790 100644
--- a/packages/liquid-html-parser/src/stage-2-ast.ts
+++ b/packages/liquid-html-parser/src/stage-2-ast.ts
@@ -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';
@@ -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 {
@@ -754,6 +756,10 @@ export interface TextNode extends ASTNode {
value: string;
}
+export interface LiquidDocParamNode extends ASTNode {
+ name: string;
+}
+
export interface ASTNode {
/**
* The type of the node, as a string.
@@ -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);
@@ -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);
}
diff --git a/packages/liquid-html-parser/src/types.ts b/packages/liquid-html-parser/src/types.ts
index 29648aebb..49efa1bf3 100644
--- a/packages/liquid-html-parser/src/types.ts
+++ b/packages/liquid-html-parser/src/types.ts
@@ -44,6 +44,7 @@ export enum NodeTypes {
RawMarkup = 'RawMarkup',
RenderMarkup = 'RenderMarkup',
RenderVariableExpression = 'RenderVariableExpression',
+ LiquidDocParamNode = 'LiquidDocParamNode',
}
// These are officially supported with special node types