123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- import * as AST from '../ast';
- import Env, { EnvError } from '../env';
-
- export class RuleSet {
- public selectors: AST.Selector[];
- public children: AST.Child[];
-
- public constructor(selectors: AST.Selector[], children: AST.Child[] = []) {
- this.selectors = selectors;
- this.children = children;
- }
-
- public compile(env: Env, opts: AST.Opts): string | EnvError {
- const lineSpacer = opts.prettyPrint ? '\n' : '';
- const wordSpacer = opts.prettyPrint ? ' ' : '';
- const indentSpacer = opts.prettyPrint ? Array(opts.depth).fill(' ').join('') : '';
- const [lBrace, rBrace] = ['{', '}'];
-
- const lineages = ([] as string[]).concat(
- ...this.selectors.map((sel) => sel.getLineages())
- );
-
- const rules: (String | EnvError)[] = [];
- const children: (String | EnvError)[] = [];
-
- for (const child of this.children) {
- if (child instanceof AST.Rule) {
- rules.push(child.compile(env, opts));
- } else if (child instanceof RuleSet) {
- children.push(child.compile(env, opts));
- } else if (child instanceof AST.Application) {
- const mixin = env.get(child.name.value);
- if (mixin instanceof EnvError) return mixin;
- if (mixin instanceof AST.Mixin) {
- const expansion = mixin.expand(env, opts, this.selectors, child.arguments);
- if (expansion instanceof EnvError) return expansion;
- expansion.rules.forEach((rule: String | EnvError) => rules.push(rule));
- expansion.children.forEach((child: String | EnvError) => children.push(child));
- }
- }
- }
-
- const rulesError = rules.find((node) => node instanceof EnvError);
- if (rulesError instanceof EnvError) return rulesError;
- const childrenError = children.find((node) => node instanceof EnvError);
- if (childrenError instanceof EnvError) return childrenError;
-
- const compiledRules = rules.join(lineSpacer);
- const compiledChildren = children.join(lineSpacer);
-
- const lineage = lineages.join(`,${wordSpacer}`);
- const frontMatter = `${indentSpacer}${lineage}${wordSpacer}${lBrace}${lineSpacer}`;
- const backMatter = `${lineSpacer}${indentSpacer}${rBrace}${
- compiledChildren.length ? lineSpacer : ''
- }`;
- return rules.length
- ? `${frontMatter}${compiledRules}${backMatter}${compiledChildren}`
- : compiledChildren;
- }
- }
|