1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- import * as AST from '../ast';
- import Env, { EnvError } from '../env';
- import Token from '../token';
-
- interface Expansion {
- rules: (String | EnvError)[];
- children: (String | EnvError)[];
- }
-
- export class Mixin {
- public name: Token;
- public parameters: AST.Identifier[];
- public children: AST.Child[];
-
- public constructor(
- name: Token,
- parameters: AST.Identifier[],
- children: AST.Child[]
- ) {
- this.name = name;
- this.parameters = parameters;
- this.children = children;
- }
-
- public compile(env: Env, _opts: AST.Opts) {
- env.set(this.name.value, this);
- return '';
- }
-
- public expand(
- env: Env,
- opts: AST.Opts,
- parents: AST.Selector[],
- args: AST.Node[]
- ): Expansion | EnvError {
- if (this.parameters.length !== args.length) {
- return new EnvError(
- this.name.line,
- `Expected ${this.parameters.length} arguments but received ${
- args.length
- }`
- );
- }
-
- const mixinEnv = new Env(env);
- this.parameters.forEach((param, index) => {
- mixinEnv.set(param.name.value, args[index]);
- });
-
- const rules = this.children
- .filter((child: AST.Node): child is AST.Rule => child instanceof AST.Rule)
- .map((child: AST.Rule) => child.compile(mixinEnv, opts));
-
- const children = this.children
- .filter(
- (child: AST.Node): child is AST.RuleSet => child instanceof AST.RuleSet
- )
- .map((child: AST.RuleSet) => {
- child.selectors.forEach((sel) => (sel.parents = parents));
- return child.compile(mixinEnv, opts);
- });
-
- return { rules, children };
- }
- }
|