Skip to content

Commit fa207a1

Browse files
committed
update the check so that it's scope aware
1 parent 6189068 commit fa207a1

2 files changed

Lines changed: 31 additions & 6 deletions

File tree

packages/theme-check-common/src/checks/undefined-object/index.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
LiquidTagDecrement,
88
LiquidTagFor,
99
LiquidTagIncrement,
10+
LiquidTagSnippet,
1011
LiquidTagTablerow,
1112
LiquidVariableLookup,
1213
NamedTags,
@@ -16,7 +17,7 @@ import {
1617
import { LiquidCheckDefinition, Severity, SourceCodeType, ThemeDocset } from '../../types';
1718
import { isError, last } from '../../utils';
1819
import { hasLiquidDoc } from '../../liquid-doc/liquidDoc';
19-
import { isWithinRawTagThatDoesNotParseItsContents } from '../utils';
20+
import { isWithinRawTagThatDoesNotParseItsContents, findInlineSnippetAncestor } from '../utils';
2021

2122
type Scope = { start?: number; end?: number };
2223

@@ -66,9 +67,16 @@ export const UndefinedObject: LiquidCheckDefinition = {
6667
}
6768

6869
return {
69-
async LiquidDocParamNode(node: LiquidDocParamNode) {
70+
async LiquidDocParamNode(node: LiquidDocParamNode, ancestors: LiquidHtmlNode[]) {
7071
const paramName = node.paramName?.value;
71-
if (paramName) {
72+
if (!paramName) return;
73+
const snippetAncestor = findInlineSnippetAncestor(ancestors);
74+
if (snippetAncestor) {
75+
indexVariableScope(paramName, {
76+
start: snippetAncestor.blockStartPosition.end,
77+
end: snippetAncestor.blockEndPosition?.start,
78+
});
79+
} else {
7280
fileScopedVariables.add(paramName);
7381
}
7482
},
@@ -134,6 +142,10 @@ export const UndefinedObject: LiquidCheckDefinition = {
134142
end: node.blockEndPosition?.start,
135143
});
136144
}
145+
146+
if (isLiquidTagSnippet(node) && node.markup.name) {
147+
fileScopedVariables.add(node.markup.name);
148+
}
137149
},
138150

139151
async VariableLookup(node, ancestors) {
@@ -142,9 +154,7 @@ export const UndefinedObject: LiquidCheckDefinition = {
142154
const parent = last(ancestors);
143155
if (isLiquidTag(parent) && isLiquidTagCapture(parent)) return;
144156

145-
if (parent?.type === NodeTypes.RenderMarkup && parent.snippet === node) return;
146-
147-
if (isLiquidTag(parent) && parent.name === 'snippet' && parent.markup === node) return;
157+
if (isLiquidTag(parent) && isLiquidTagSnippet(parent) && parent.markup === node) return;
148158

149159
variables.push(node);
150160
},
@@ -272,6 +282,10 @@ function isLiquidTagCapture(node: LiquidTag): node is LiquidTagCapture {
272282
return node.name === NamedTags.capture;
273283
}
274284

285+
function isLiquidTagSnippet(node: LiquidTag): node is LiquidTagSnippet {
286+
return node.name === NamedTags.snippet;
287+
}
288+
275289
function isLiquidTagAssign(node: LiquidTag): node is LiquidTagAssign {
276290
return node.name === NamedTags.assign && typeof node.markup !== 'string';
277291
}

packages/theme-check-common/src/checks/utils.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
LiquidTagTablerow,
1414
LiquidTag,
1515
LoopNamedTags,
16+
NamedTags,
1617
} from '@shopify/liquid-html-parser';
1718
import { LiquidHtmlNodeOfType as NodeOfType } from '../types';
1819

@@ -104,6 +105,16 @@ export function isLoopLiquidTag(tag: LiquidTag): tag is LiquidTagFor | LiquidTag
104105
return LoopNamedTags.includes(tag.name as any);
105106
}
106107

108+
export function findInlineSnippetAncestor(ancestors: LiquidHtmlNode[]) {
109+
for (let i = ancestors.length - 1; i >= 0; i--) {
110+
const ancestor = ancestors[i];
111+
if (ancestor.type === NodeTypes.LiquidTag && ancestor.name === NamedTags.snippet) {
112+
return ancestor;
113+
}
114+
}
115+
return null;
116+
}
117+
107118
const RawTagsThatDoNotParseTheirContents = ['raw', 'stylesheet', 'javascript', 'schema'];
108119

109120
function isRawTagThatDoesNotParseItsContent(node: LiquidHtmlNode) {

0 commit comments

Comments
 (0)