Skip to content

Commit f999e46

Browse files
committed
refactor(parser): drop redundant hasTopLevelBareVariable scan
#4462 added a hand-rolled hasTopLevelBareVariable() that re-scanned prelude text with a paren-depth counter to flag a top-level bare @variable. It duplicated machinery the parser already has and was subtly wrong: - permissiveValue's entity loop already reports a bare @var structurally (it parses a Variable entity and warns), covering every real case — bare, glued (bar-@baz), post-keyword (@A and @b), and comma lists — verified. - the hand-rolled scan only tracked (), not []/{} or strings, unlike the existing nesting-aware $parseUntil, so a bare @var inside […] could be mis-flagged. Remove the function and suppress the value-context 'variable-in-unknown-value' notice for at-rule preludes (the entity loop owns that warning). Behaviour is unchanged: the at-rule-variable-deprecated fixture renders byte-identically and emits the same 5 prelude warnings; @foo (x:@v) still does not warn.
1 parent 92c62bb commit f999e46

1 file changed

Lines changed: 7 additions & 33 deletions

File tree

packages/less/lib/less/parser/parser.js

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -106,31 +106,6 @@ const Parser = function Parser(context, imports, fileInfo, currentIndex) {
106106
warn('A bare @variable in an at-rule prelude is deprecated. Use @{variable} interpolation instead.', index, 'DEPRECATED', 'variable-in-at-rule-prelude');
107107
}
108108

109-
/**
110-
* Whether `text` contains a bare `@variable` at the top level — i.e. outside
111-
* any `(...)` group. A `@variable` inside parentheses is a declaration value
112-
* (e.g. the `@v` in `@supports (display: @v)`) and remains valid; only a bare
113-
* `@variable` in a structural position is deprecated.
114-
*
115-
* @param {string} text
116-
* @returns {boolean}
117-
*/
118-
function hasTopLevelBareVariable(text) {
119-
let depth = 0;
120-
for (let j = 0; j < text.length; j++) {
121-
const c = text.charAt(j);
122-
if (c === '(') {
123-
depth++;
124-
} else if (c === ')') {
125-
if (depth > 0) { depth--; }
126-
} else if (c === '@' && depth === 0) {
127-
// a bare `@ident`, not `@{ident}` interpolation
128-
if (/[\w-]/.test(text.charAt(j + 1))) { return true; }
129-
}
130-
}
131-
return false;
132-
}
133-
134109
function expect(arg, msg) {
135110
// some older browsers return typeof 'function' for RegExp
136111
const result = (arg instanceof Function) ? arg.call(parsers) : parserInput.$re(arg);
@@ -1838,14 +1813,13 @@ const Parser = function Parser(context, imports, fileInfo, currentIndex) {
18381813
const quote = new tree.Quoted('\'', item, true, index, fileInfo);
18391814
const variableRegex = /@([\w-]+)/g;
18401815
const propRegex = /\$([\w-]+)/g;
1841-
if (deprecateVariables) {
1842-
// At-rule prelude: only a bare @var in a structural
1843-
// (top-level) position is deprecated; @vars inside
1844-
// `(...)` are declaration values and stay valid.
1845-
if (hasTopLevelBareVariable(item)) {
1846-
warnBareAtRuleVariable(index);
1847-
}
1848-
} else if (variableRegex.test(item)) {
1816+
// A bare `@var` in an at-rule prelude (deprecateVariables)
1817+
// is already reported structurally by the entity loop
1818+
// above (a parsed `Variable` entity), so no text re-scan is
1819+
// needed here. The `variable-in-unknown-value` notice below
1820+
// is for unknown declaration values only, not at-rule
1821+
// preludes, so it is suppressed when deprecateVariables.
1822+
if (!deprecateVariables && variableRegex.test(item)) {
18491823
warn('@variable in unknown values will not be evaluated as variables in the future. Use @{variable}', index, 'DEPRECATED', 'variable-in-unknown-value');
18501824
}
18511825
if (propRegex.test(item)) {

0 commit comments

Comments
 (0)