@jesscss/scss-parser 2.0.0-alpha.7 → 2.0.0-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -12
- package/lib/ast/grammar.cjs +36610 -0
- package/lib/ast/grammar.d.ts +1 -0
- package/lib/ast/grammar.js +36609 -0
- package/lib/ast/lower-user-function-calls.d.ts +6 -0
- package/lib/cst.cjs +1 -1
- package/lib/cst.js +1 -1
- package/lib/grammar.cjs +2 -55568
- package/lib/grammar.js +1 -55567
- package/lib/grammar2.cjs +88858 -0
- package/lib/grammar2.js +88853 -0
- package/lib/index.cjs +108 -11
- package/lib/index.d.ts +10 -7
- package/lib/index.js +107 -5
- package/package.json +10 -20
- package/lib/builders.d.ts +0 -154
- package/lib/functional-parser.cjs +0 -2872
- package/lib/functional-parser.d.ts +0 -46
- package/lib/functional-parser.js +0 -2855
- package/lib/interp.d.ts +0 -26
- package/lib/jess.cjs +0 -6
- package/lib/jess.d.ts +0 -2
- package/lib/jess.js +0 -2
- package/lib/scss-atroot-helpers.d.ts +0 -4
- package/lib/scss-atrule-helpers.d.ts +0 -36
- package/lib/scss-value-helpers.d.ts +0 -11
- package/src/builders.ts +0 -1408
- package/src/cst.ts +0 -25
- package/src/functional-parser.ts +0 -135
- package/src/grammar.ts +0 -621
- package/src/index.ts +0 -14
- package/src/interp.ts +0 -158
- package/src/jess.ts +0 -11
- package/src/scss-atroot-helpers.ts +0 -105
- package/src/scss-atrule-helpers.ts +0 -191
- package/src/scss-value-helpers.ts +0 -105
package/lib/index.cjs
CHANGED
|
@@ -1,14 +1,111 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
const require_ast_grammar = require("./ast/grammar.cjs");
|
|
3
|
+
let parseman = require("parseman");
|
|
4
|
+
let _jesscss_core_ast = require("@jesscss/core/ast");
|
|
5
|
+
//#region src/ast/lower-user-function-calls.ts
|
|
6
|
+
/**
|
|
7
|
+
* SCSS call-site lowering: a user `@function f(...)` was lowered (in the grammar)
|
|
8
|
+
* to a `$var`-bound value lambda (`AnonymousMixin` with `params`). A CALL to that
|
|
9
|
+
* function — `f(2)` — parses as an ordinary `FunctionCall`, indistinguishable at
|
|
10
|
+
* the leaf from a builtin Sass call (`darken(...)`). This post-parse pass rewrites
|
|
11
|
+
* every `FunctionCall` whose name is a USER-defined `@function` into the shared
|
|
12
|
+
* `$f(args)` invoke form (a `Reference` with a `Call` step on the bound variable),
|
|
13
|
+
* so it reaches the general "call a value-lambda" evaluator path. Builtin Sass
|
|
14
|
+
* functions are left as `FunctionCall`s and continue to route to `fns`.
|
|
15
|
+
*
|
|
16
|
+
* User-function names are collected from the WHOLE document first (Sass hoists and
|
|
17
|
+
* effectively globalises function definitions), so a call may precede its `@function`.
|
|
18
|
+
* The only SCSS construct that binds an `AnonymousMixin` to a `$var` is `@function`,
|
|
19
|
+
* so "a VariableDeclaration whose value is an AnonymousMixin" is an exact marker.
|
|
20
|
+
*/
|
|
21
|
+
function isRecord(value) {
|
|
22
|
+
return typeof value === "object" && value !== null;
|
|
23
|
+
}
|
|
24
|
+
function isFunctionCall(value) {
|
|
25
|
+
return isRecord(value) && value.type === "FunctionCall" && typeof value.name === "string" && Array.isArray(value.args);
|
|
26
|
+
}
|
|
27
|
+
/** A non-array value slot is a single value node. */
|
|
28
|
+
function isValueNode(slot) {
|
|
29
|
+
return !Array.isArray(slot);
|
|
30
|
+
}
|
|
31
|
+
function isStylesheet$1(value) {
|
|
32
|
+
return isRecord(value) && value.type === "Stylesheet" && Array.isArray(value.children);
|
|
33
|
+
}
|
|
34
|
+
/** Collect every user `@function` name: a VariableDeclaration bound to an
|
|
35
|
+
* AnonymousMixin (the only SCSS shape that produces one). */
|
|
36
|
+
function collectUserFunctionNames(node, into) {
|
|
37
|
+
if (Array.isArray(node)) {
|
|
38
|
+
for (const child of node) collectUserFunctionNames(child, into);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (!isRecord(node)) return;
|
|
42
|
+
if (node.type === "VariableDeclaration" && typeof node.name === "string" && isRecord(node.value) && node.value.type === "AnonymousMixin") into.add(node.name);
|
|
43
|
+
for (const key of Object.keys(node)) collectUserFunctionNames(node[key], into);
|
|
44
|
+
}
|
|
45
|
+
/** Best-effort authored spelling of a call argument, for a Reference `raw`
|
|
46
|
+
* fallback (only ever emitted if the invoke fails to resolve). */
|
|
47
|
+
function argRaw(slot) {
|
|
48
|
+
if (!isValueNode(slot)) return slot.map(argRaw).join(" ");
|
|
49
|
+
if (slot.type === "VariableReference") return `$${slot.name}`;
|
|
50
|
+
if ("src" in slot && typeof slot.src === "string") return slot.src;
|
|
51
|
+
return "";
|
|
52
|
+
}
|
|
53
|
+
/** Deep-transform the tree, rewriting user-function `FunctionCall`s (post-order,
|
|
54
|
+
* so nested user calls inside the args lower first). Non-AST scalars pass through. */
|
|
55
|
+
function rewrite(node, userFns) {
|
|
56
|
+
if (Array.isArray(node)) return node.map((child) => rewrite(child, userFns));
|
|
57
|
+
if (!isRecord(node)) return node;
|
|
58
|
+
const out = {};
|
|
59
|
+
for (const key of Object.keys(node)) out[key] = rewrite(node[key], userFns);
|
|
60
|
+
if (isFunctionCall(out) && userFns.has(out.name)) {
|
|
61
|
+
const args = out.args.map((value) => ({ value }));
|
|
62
|
+
const raw = `${out.name}(${out.args.map(argRaw).join(", ")})`;
|
|
63
|
+
return (0, _jesscss_core_ast.reference)((0, _jesscss_core_ast.variableReference)(out.name, "live"), [{
|
|
64
|
+
type: "Call",
|
|
65
|
+
args
|
|
66
|
+
}], raw);
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Rewrite user-`@function` call sites in a parsed SCSS document to `$f(args)`
|
|
72
|
+
* lambda invokes. Returns the document unchanged when it defines no user function.
|
|
73
|
+
*/
|
|
74
|
+
function lowerUserFunctionCalls(sheet) {
|
|
75
|
+
const userFns = /* @__PURE__ */ new Set();
|
|
76
|
+
collectUserFunctionNames(sheet.children, userFns);
|
|
77
|
+
if (userFns.size === 0) return sheet;
|
|
78
|
+
const lowered = rewrite(sheet, userFns);
|
|
79
|
+
if (!isStylesheet$1(lowered)) throw new TypeError("SCSS user-function lowering did not preserve the Stylesheet root.");
|
|
80
|
+
return lowered;
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
5
83
|
//#region src/index.ts
|
|
6
|
-
|
|
84
|
+
/** Structured failure from the public direct SCSS parser. */
|
|
85
|
+
var ScssParseError = class extends SyntaxError {
|
|
86
|
+
code = "parse/syntax-error";
|
|
87
|
+
offset;
|
|
88
|
+
expected;
|
|
89
|
+
constructor(offset, expected) {
|
|
90
|
+
const detail = expected.length > 0 ? ` Expected: ${expected.join(", ")}.` : "";
|
|
91
|
+
super(`SCSS parser error.${detail}`);
|
|
92
|
+
this.name = "ScssParseError";
|
|
93
|
+
this.offset = offset;
|
|
94
|
+
this.expected = expected;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
function isStylesheet(value) {
|
|
98
|
+
return typeof value === "object" && value !== null && "type" in value && value.type === "Stylesheet" && "children" in value && Array.isArray(value.children);
|
|
99
|
+
}
|
|
100
|
+
/** Parse SCSS directly into the canonical AST v2 document. */
|
|
101
|
+
function parse(input) {
|
|
102
|
+
const entry = require_ast_grammar.scssAstGrammar.ScssAstDocument;
|
|
103
|
+
const trivia = require_ast_grammar.scssAstGrammar.whitespace;
|
|
104
|
+
if (entry === void 0 || trivia === void 0) throw new TypeError("SCSS AST grammar is missing its public document entry.");
|
|
105
|
+
const result = (0, parseman.run)(entry, input, { trivia });
|
|
106
|
+
if (!result.ok || result.unconsumedFrom !== null || !isStylesheet(result.value)) throw new ScssParseError(result.ok ? result.unconsumedFrom ?? result.span.end : result.span.start, result.expected);
|
|
107
|
+
return lowerUserFunctionCalls(result.value);
|
|
108
|
+
}
|
|
7
109
|
//#endregion
|
|
8
|
-
exports.
|
|
9
|
-
exports.
|
|
10
|
-
exports.ScssParser = require_functional_parser.ScssParser;
|
|
11
|
-
exports.parseScssCst = require_cst.parseScssCst;
|
|
12
|
-
exports.parseScssDoc = require_cst.parseScssDoc;
|
|
13
|
-
exports.parseScssFn = require_functional_parser.parseScssFn;
|
|
14
|
-
exports.scssGrammar = require_grammar.scssGrammar;
|
|
110
|
+
exports.ScssParseError = ScssParseError;
|
|
111
|
+
exports.parse = parse;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import type { Stylesheet } from '@jesscss/core/ast';
|
|
2
|
+
/** Structured failure from the public direct SCSS parser. */
|
|
3
|
+
export declare class ScssParseError extends SyntaxError {
|
|
4
|
+
readonly code: 'parse/syntax-error';
|
|
5
|
+
readonly offset: number;
|
|
6
|
+
readonly expected: readonly string[];
|
|
7
|
+
constructor(offset: number, expected: readonly string[]);
|
|
8
|
+
}
|
|
9
|
+
/** Parse SCSS directly into the canonical AST v2 document. */
|
|
10
|
+
export declare function parse(input: string): Stylesheet;
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,109 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { scssAstGrammar } from "./ast/grammar.js";
|
|
2
|
+
import { run } from "parseman";
|
|
3
|
+
import { reference, variableReference } from "@jesscss/core/ast";
|
|
4
|
+
//#region src/ast/lower-user-function-calls.ts
|
|
5
|
+
/**
|
|
6
|
+
* SCSS call-site lowering: a user `@function f(...)` was lowered (in the grammar)
|
|
7
|
+
* to a `$var`-bound value lambda (`AnonymousMixin` with `params`). A CALL to that
|
|
8
|
+
* function — `f(2)` — parses as an ordinary `FunctionCall`, indistinguishable at
|
|
9
|
+
* the leaf from a builtin Sass call (`darken(...)`). This post-parse pass rewrites
|
|
10
|
+
* every `FunctionCall` whose name is a USER-defined `@function` into the shared
|
|
11
|
+
* `$f(args)` invoke form (a `Reference` with a `Call` step on the bound variable),
|
|
12
|
+
* so it reaches the general "call a value-lambda" evaluator path. Builtin Sass
|
|
13
|
+
* functions are left as `FunctionCall`s and continue to route to `fns`.
|
|
14
|
+
*
|
|
15
|
+
* User-function names are collected from the WHOLE document first (Sass hoists and
|
|
16
|
+
* effectively globalises function definitions), so a call may precede its `@function`.
|
|
17
|
+
* The only SCSS construct that binds an `AnonymousMixin` to a `$var` is `@function`,
|
|
18
|
+
* so "a VariableDeclaration whose value is an AnonymousMixin" is an exact marker.
|
|
19
|
+
*/
|
|
20
|
+
function isRecord(value) {
|
|
21
|
+
return typeof value === "object" && value !== null;
|
|
22
|
+
}
|
|
23
|
+
function isFunctionCall(value) {
|
|
24
|
+
return isRecord(value) && value.type === "FunctionCall" && typeof value.name === "string" && Array.isArray(value.args);
|
|
25
|
+
}
|
|
26
|
+
/** A non-array value slot is a single value node. */
|
|
27
|
+
function isValueNode(slot) {
|
|
28
|
+
return !Array.isArray(slot);
|
|
29
|
+
}
|
|
30
|
+
function isStylesheet$1(value) {
|
|
31
|
+
return isRecord(value) && value.type === "Stylesheet" && Array.isArray(value.children);
|
|
32
|
+
}
|
|
33
|
+
/** Collect every user `@function` name: a VariableDeclaration bound to an
|
|
34
|
+
* AnonymousMixin (the only SCSS shape that produces one). */
|
|
35
|
+
function collectUserFunctionNames(node, into) {
|
|
36
|
+
if (Array.isArray(node)) {
|
|
37
|
+
for (const child of node) collectUserFunctionNames(child, into);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (!isRecord(node)) return;
|
|
41
|
+
if (node.type === "VariableDeclaration" && typeof node.name === "string" && isRecord(node.value) && node.value.type === "AnonymousMixin") into.add(node.name);
|
|
42
|
+
for (const key of Object.keys(node)) collectUserFunctionNames(node[key], into);
|
|
43
|
+
}
|
|
44
|
+
/** Best-effort authored spelling of a call argument, for a Reference `raw`
|
|
45
|
+
* fallback (only ever emitted if the invoke fails to resolve). */
|
|
46
|
+
function argRaw(slot) {
|
|
47
|
+
if (!isValueNode(slot)) return slot.map(argRaw).join(" ");
|
|
48
|
+
if (slot.type === "VariableReference") return `$${slot.name}`;
|
|
49
|
+
if ("src" in slot && typeof slot.src === "string") return slot.src;
|
|
50
|
+
return "";
|
|
51
|
+
}
|
|
52
|
+
/** Deep-transform the tree, rewriting user-function `FunctionCall`s (post-order,
|
|
53
|
+
* so nested user calls inside the args lower first). Non-AST scalars pass through. */
|
|
54
|
+
function rewrite(node, userFns) {
|
|
55
|
+
if (Array.isArray(node)) return node.map((child) => rewrite(child, userFns));
|
|
56
|
+
if (!isRecord(node)) return node;
|
|
57
|
+
const out = {};
|
|
58
|
+
for (const key of Object.keys(node)) out[key] = rewrite(node[key], userFns);
|
|
59
|
+
if (isFunctionCall(out) && userFns.has(out.name)) {
|
|
60
|
+
const args = out.args.map((value) => ({ value }));
|
|
61
|
+
const raw = `${out.name}(${out.args.map(argRaw).join(", ")})`;
|
|
62
|
+
return reference(variableReference(out.name, "live"), [{
|
|
63
|
+
type: "Call",
|
|
64
|
+
args
|
|
65
|
+
}], raw);
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Rewrite user-`@function` call sites in a parsed SCSS document to `$f(args)`
|
|
71
|
+
* lambda invokes. Returns the document unchanged when it defines no user function.
|
|
72
|
+
*/
|
|
73
|
+
function lowerUserFunctionCalls(sheet) {
|
|
74
|
+
const userFns = /* @__PURE__ */ new Set();
|
|
75
|
+
collectUserFunctionNames(sheet.children, userFns);
|
|
76
|
+
if (userFns.size === 0) return sheet;
|
|
77
|
+
const lowered = rewrite(sheet, userFns);
|
|
78
|
+
if (!isStylesheet$1(lowered)) throw new TypeError("SCSS user-function lowering did not preserve the Stylesheet root.");
|
|
79
|
+
return lowered;
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
4
82
|
//#region src/index.ts
|
|
5
|
-
|
|
83
|
+
/** Structured failure from the public direct SCSS parser. */
|
|
84
|
+
var ScssParseError = class extends SyntaxError {
|
|
85
|
+
code = "parse/syntax-error";
|
|
86
|
+
offset;
|
|
87
|
+
expected;
|
|
88
|
+
constructor(offset, expected) {
|
|
89
|
+
const detail = expected.length > 0 ? ` Expected: ${expected.join(", ")}.` : "";
|
|
90
|
+
super(`SCSS parser error.${detail}`);
|
|
91
|
+
this.name = "ScssParseError";
|
|
92
|
+
this.offset = offset;
|
|
93
|
+
this.expected = expected;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
function isStylesheet(value) {
|
|
97
|
+
return typeof value === "object" && value !== null && "type" in value && value.type === "Stylesheet" && "children" in value && Array.isArray(value.children);
|
|
98
|
+
}
|
|
99
|
+
/** Parse SCSS directly into the canonical AST v2 document. */
|
|
100
|
+
function parse(input) {
|
|
101
|
+
const entry = scssAstGrammar.ScssAstDocument;
|
|
102
|
+
const trivia = scssAstGrammar.whitespace;
|
|
103
|
+
if (entry === void 0 || trivia === void 0) throw new TypeError("SCSS AST grammar is missing its public document entry.");
|
|
104
|
+
const result = run(entry, input, { trivia });
|
|
105
|
+
if (!result.ok || result.unconsumedFrom !== null || !isStylesheet(result.value)) throw new ScssParseError(result.ok ? result.unconsumedFrom ?? result.span.end : result.span.start, result.expected);
|
|
106
|
+
return lowerUserFunctionCalls(result.value);
|
|
107
|
+
}
|
|
6
108
|
//#endregion
|
|
7
|
-
export {
|
|
109
|
+
export { ScssParseError, parse };
|
package/package.json
CHANGED
|
@@ -4,47 +4,37 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"description": "",
|
|
7
|
-
"version": "2.0.0-alpha.
|
|
7
|
+
"version": "2.0.0-alpha.9",
|
|
8
8
|
"main": "lib/index.cjs",
|
|
9
9
|
"types": "lib/index.d.ts",
|
|
10
10
|
"exports": {
|
|
11
11
|
".": {
|
|
12
12
|
"types": "./lib/index.d.ts",
|
|
13
|
-
"source": "./src/index.ts",
|
|
14
13
|
"import": "./lib/index.js",
|
|
15
14
|
"require": "./lib/index.cjs"
|
|
16
15
|
},
|
|
17
16
|
"./cst": {
|
|
18
17
|
"types": "./lib/cst.d.ts",
|
|
19
|
-
"source": "./src/cst.ts",
|
|
20
18
|
"import": "./lib/cst.js",
|
|
21
19
|
"require": "./lib/cst.cjs"
|
|
22
20
|
},
|
|
23
21
|
"./grammar": {
|
|
24
22
|
"types": "./lib/grammar.d.ts",
|
|
25
|
-
"source": "./src/grammar.ts",
|
|
26
23
|
"import": "./lib/grammar.js",
|
|
27
24
|
"require": "./lib/grammar.cjs"
|
|
28
25
|
},
|
|
29
|
-
"./jess": {
|
|
30
|
-
"types": "./lib/jess.d.ts",
|
|
31
|
-
"source": "./src/jess.ts",
|
|
32
|
-
"import": "./lib/jess.js",
|
|
33
|
-
"require": "./lib/jess.cjs"
|
|
34
|
-
},
|
|
35
26
|
"./package.json": "./package.json"
|
|
36
27
|
},
|
|
37
28
|
"files": [
|
|
38
|
-
"lib"
|
|
39
|
-
"src"
|
|
29
|
+
"lib"
|
|
40
30
|
],
|
|
41
31
|
"dependencies": {
|
|
42
|
-
"
|
|
43
|
-
"@jesscss/
|
|
44
|
-
"@jesscss/less-parser": "2.0.0-alpha.7"
|
|
32
|
+
"@jesscss/css-parser": "2.0.0-alpha.9",
|
|
33
|
+
"@jesscss/less-parser": "2.0.0-alpha.9"
|
|
45
34
|
},
|
|
46
35
|
"peerDependencies": {
|
|
47
|
-
"
|
|
36
|
+
"parseman": "^0.30.0",
|
|
37
|
+
"@jesscss/core": "2.0.0-alpha.9"
|
|
48
38
|
},
|
|
49
39
|
"peerDependenciesMeta": {
|
|
50
40
|
"@jesscss/core": {
|
|
@@ -52,9 +42,10 @@
|
|
|
52
42
|
}
|
|
53
43
|
},
|
|
54
44
|
"devDependencies": {
|
|
55
|
-
"parseman": "0.
|
|
45
|
+
"parseman": "0.30.0",
|
|
56
46
|
"sass-spec": "github:sass/sass-spec",
|
|
57
|
-
"@jesscss/core": "2.0.0-alpha.
|
|
47
|
+
"@jesscss/core": "2.0.0-alpha.9",
|
|
48
|
+
"@jesscss/internal-css-recognition": "0.0.0"
|
|
58
49
|
},
|
|
59
50
|
"author": "Matthew Dean <matthew-dean@users.noreply.github.com>",
|
|
60
51
|
"license": "MIT",
|
|
@@ -67,12 +58,11 @@
|
|
|
67
58
|
"scripts": {
|
|
68
59
|
"postinstall": "node ./scripts/materialize-sass-spec-cache.cjs",
|
|
69
60
|
"ci": "pnpm build && pnpm test",
|
|
70
|
-
"build": "pnpm compile",
|
|
61
|
+
"build": "pnpm --filter @jesscss/internal-css-recognition build && pnpm compile",
|
|
71
62
|
"compile": "tsdown --tsconfig tsconfig.build.json --no-dts && ../../node_modules/.bin/tsc -p tsconfig.build.json --emitDeclarationOnly --noCheck",
|
|
72
63
|
"dev": "tsdown --tsconfig tsconfig.build.json --no-dts --watch",
|
|
73
64
|
"sass-spec:cache": "node ./scripts/materialize-sass-spec-cache.cjs",
|
|
74
65
|
"test": "vitest --run --passWithNoTests",
|
|
75
|
-
"test:parse": "vitest --run --passWithNoTests test/parse-only.test.ts test/sass-spec.smoke.test.ts",
|
|
76
66
|
"lint:fix": "eslint --fix '**/*.{js,ts}'",
|
|
77
67
|
"lint": "eslint '**/*.{js,ts}'"
|
|
78
68
|
}
|
package/lib/builders.d.ts
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ScssGrammar — Parséman-based SCSS parser, extending LessGrammar.
|
|
3
|
-
*
|
|
4
|
-
* Adds SCSS-specific grammar on top of Less (which in turn extends CSS):
|
|
5
|
-
* - Variable declarations: $var: value [!default|!global]; → VarDeclaration
|
|
6
|
-
* - Variable references: $var → Reference
|
|
7
|
-
* - Line comments: // ... (added to rw trivia)
|
|
8
|
-
*
|
|
9
|
-
* Inherits from LessGrammar:
|
|
10
|
-
* - Nested rulesets, & ampersand, relative selectors
|
|
11
|
-
* - anyDeclaration entry point
|
|
12
|
-
* - atRuleBody, declarationList, Stylesheet overrides
|
|
13
|
-
* - Less merge operators on Declaration (harmless for SCSS)
|
|
14
|
-
*
|
|
15
|
-
* Chevrotain note: in the Chevrotain architecture, ScssRecursiveParser
|
|
16
|
-
* extends CssRecursiveParser independently of LessRecursiveParser.
|
|
17
|
-
* Here we take the Parséman inheritance chain
|
|
18
|
-
* CssParser → LessGrammar → ScssGrammar to maximise code reuse.
|
|
19
|
-
*/
|
|
20
|
-
import type { FieldMap, Span } from 'parseman';
|
|
21
|
-
import type { CSTLeaf, CSTError } from 'parseman';
|
|
22
|
-
import { LessGrammar } from '@jesscss/less-parser/jess';
|
|
23
|
-
import { type Node, type LocationInfo, type TreeContext, Rules, Quoted } from '@jesscss/core';
|
|
24
|
-
type JessNode = Node<any, any>;
|
|
25
|
-
type Child = JessNode | CSTLeaf | CSTError;
|
|
26
|
-
export declare class ScssGrammar extends LessGrammar {
|
|
27
|
-
rw: import("parseman").Combinator<string>;
|
|
28
|
-
protected _trivia: import("parseman").Combinator<string>;
|
|
29
|
-
protected _parseContext?: TreeContext;
|
|
30
|
-
setContext(context?: TreeContext): void;
|
|
31
|
-
scssVar: import("parseman").Combinator<string>;
|
|
32
|
-
VarDeclaration: (g: any) => import("parseman").Combinator<[unknown, string, unknown, string | null, string | null]>;
|
|
33
|
-
Reference: (g: any) => any;
|
|
34
|
-
protected buildNode(type: string, span: Span, children: ReadonlyArray<JessNode | CSTLeaf | CSTError>, _state: unknown, _rawChildren: ReadonlyArray<{
|
|
35
|
-
_tag: string;
|
|
36
|
-
}>, fields?: FieldMap, triviaLog?: readonly number[]): JessNode;
|
|
37
|
-
private _buildScssVarDeclaration;
|
|
38
|
-
/**
|
|
39
|
-
* `ns.$member: value [!default|!global];` — a namespaced variable ASSIGNMENT.
|
|
40
|
-
* Built as a `VarDeclaration` whose name carries the namespace (`ns.member`);
|
|
41
|
-
* `!default` → conditional-assign, `!global` → `setDefined`. Mirrors the
|
|
42
|
-
* member-read shape (`Reference{ target, key }`) on the write side while
|
|
43
|
-
* staying within the `string | Interpolated` declaration-name contract.
|
|
44
|
-
*/
|
|
45
|
-
private _buildScssNsVarDeclaration;
|
|
46
|
-
private _buildScssReference;
|
|
47
|
-
/**
|
|
48
|
-
* `left [op right]` → Condition, or a bare operand when there is no operator.
|
|
49
|
-
* `!=` desugars to `=` + negate (matches the Chevrotain scssComparison).
|
|
50
|
-
*/
|
|
51
|
-
private _buildScssComparison;
|
|
52
|
-
/**
|
|
53
|
-
* Every condition term is wrapped in a Paren, matching the Chevrotain
|
|
54
|
-
* `scssConditionInParens` production (both the `( … )` group and the bare
|
|
55
|
-
* comparison / value branch wrap their result in a single Paren).
|
|
56
|
-
*/
|
|
57
|
-
private _buildScssCondInParens;
|
|
58
|
-
/** Optional leading `not` negates the term. */
|
|
59
|
-
private _buildScssCondTerm;
|
|
60
|
-
/** Fold a left-associative `and` / `or` chain of terms into Conditions. */
|
|
61
|
-
private _buildScssCondJoin;
|
|
62
|
-
/** A `{ … }` control-block body → Rules. */
|
|
63
|
-
private _buildScssRules;
|
|
64
|
-
/**
|
|
65
|
-
* `@if cond { … } (@else if cond { … })* (@else { … })?` → nested `If` chain.
|
|
66
|
-
* Children arrive as alternating condition / Rules nodes, with an optional
|
|
67
|
-
* trailing bare Rules (the final `@else`). Fold from the last branch inward.
|
|
68
|
-
*/
|
|
69
|
-
private _buildScssIf;
|
|
70
|
-
/** A `$name` loop-binding with no value (`paramVar` — prints as `$name`). */
|
|
71
|
-
private _scssParamVar;
|
|
72
|
-
/**
|
|
73
|
-
* `@each $a[, $b …] in <expr> { … }` → `For` with a node iterable.
|
|
74
|
-
* Normalizes to Jess `$for ($a of …)` / `$for ([$a, $b] of …)`.
|
|
75
|
-
*/
|
|
76
|
-
private _buildScssEach;
|
|
77
|
-
/**
|
|
78
|
-
* `@for $i from <start> (to|through) <end> { … }` → `For` with a range iterable.
|
|
79
|
-
* `through` is inclusive end; `to` is exclusive (`includeEnd: false`).
|
|
80
|
-
*/
|
|
81
|
-
private _buildScssFor;
|
|
82
|
-
/** `@while <cond> { … }` → `While`. */
|
|
83
|
-
private _buildScssWhile;
|
|
84
|
-
/** Build a module-qualified or plain mixin `Reference`. */
|
|
85
|
-
private _buildScssMixinName;
|
|
86
|
-
/** `$x: val` keyword arg, `val...` spread, or plain value. */
|
|
87
|
-
private _buildScssCallArg;
|
|
88
|
-
private _buildScssCallArgsInner;
|
|
89
|
-
/** Mixin param: `...$rest`, `$rest...`, `$a: default`, or bare `$a`. */
|
|
90
|
-
private _buildScssMixinParam;
|
|
91
|
-
private _buildScssMixinParams;
|
|
92
|
-
/** `@mixin name($params) { … }` → `Mixin` (inner vars default to private). */
|
|
93
|
-
private _buildScssMixin;
|
|
94
|
-
/** `using ($c, $n)` param list for `@include … using (…)`. */
|
|
95
|
-
private _buildScssIncludeUsing;
|
|
96
|
-
/**
|
|
97
|
-
* `@include name(args) [using (…)] [ { … } ];` → `Call(Reference(type=mixin))`.
|
|
98
|
-
* An optional content block becomes an anonymous visible `Mixin` on the call.
|
|
99
|
-
*/
|
|
100
|
-
private _buildScssInclude;
|
|
101
|
-
/** `@content[(args)];` → `Call(Reference('content', type=mixin))`. */
|
|
102
|
-
private _buildScssContent;
|
|
103
|
-
/** `@function name($params) { … }` → `Func` with `returnName: 'result'`. */
|
|
104
|
-
private _buildScssFunction;
|
|
105
|
-
/** `@return <value>;` → `$result: <value>;` */
|
|
106
|
-
private _buildScssReturn;
|
|
107
|
-
private _buildScssInterpBare;
|
|
108
|
-
/** `foo-#{$bar}` name segments → Interpolated(role=name) or plain Any. */
|
|
109
|
-
private _buildScssInterpolatedName;
|
|
110
|
-
private _buildScssInterpValue;
|
|
111
|
-
private _buildScssInterpolatedSelector;
|
|
112
|
-
private _scssInterpDeclName;
|
|
113
|
-
private _buildScssDeclaration;
|
|
114
|
-
private _buildScssCustomDeclaration;
|
|
115
|
-
protected _buildQuoted(children: ReadonlyArray<Child>, loc: LocationInfo): Node<any, any> | Quoted;
|
|
116
|
-
/** `("k": v, …)` pair inside a map literal. */
|
|
117
|
-
private _buildScssMapPair;
|
|
118
|
-
private _buildScssMapLiteral;
|
|
119
|
-
/** `ns.$var`, `ns.fn(…)`, `ns.\#foo(…)`, or a plain ident. */
|
|
120
|
-
private _buildScssIdentValue;
|
|
121
|
-
protected _buildStylesheet(children: ReadonlyArray<Child>, loc: LocationInfo): Rules<never, import("@jesscss/core").RulesOptions & Record<string, any> & {
|
|
122
|
-
semi?: boolean;
|
|
123
|
-
}>;
|
|
124
|
-
private _flattenScssImportLists;
|
|
125
|
-
private _buildScssNestedProps;
|
|
126
|
-
private _buildScssDiagnostic;
|
|
127
|
-
private _buildScssAtRootFilter;
|
|
128
|
-
private _buildScssAtRootSelector;
|
|
129
|
-
private _buildScssAtRootPlain;
|
|
130
|
-
private _buildScssWithConfigEntry;
|
|
131
|
-
private _buildScssWithConfig;
|
|
132
|
-
private _buildScssUseAs;
|
|
133
|
-
private _buildScssUse;
|
|
134
|
-
private _buildScssForward;
|
|
135
|
-
private _buildScssPlaceholderSelector;
|
|
136
|
-
private _buildScssPermissiveAtRule;
|
|
137
|
-
private _buildScssLayerBlock;
|
|
138
|
-
protected _buildQueryAtRuleBlock(children: ReadonlyArray<Child>, loc: LocationInfo): JessNode;
|
|
139
|
-
protected _buildScssParen(rawChildren: ReadonlyArray<{
|
|
140
|
-
_tag: string;
|
|
141
|
-
}>, loc: LocationInfo): JessNode;
|
|
142
|
-
private _buildScssExtendTarget;
|
|
143
|
-
private _scssExtendTargetFrom;
|
|
144
|
-
private _buildScssExtend;
|
|
145
|
-
private _buildScssImportItem;
|
|
146
|
-
private _buildScssImportAtRule;
|
|
147
|
-
protected _buildCall(rawChildren: ReadonlyArray<{
|
|
148
|
-
_tag: string;
|
|
149
|
-
}>, loc: LocationInfo): JessNode;
|
|
150
|
-
protected _buildSquareParen(rawChildren: ReadonlyArray<{
|
|
151
|
-
_tag: string;
|
|
152
|
-
}>, loc: LocationInfo): JessNode;
|
|
153
|
-
}
|
|
154
|
-
export {};
|