call method

Ruleset call (
  1. Ruleset root,
  2. LessOptions options
)

Transform root according the visitors

Implementation

Ruleset call(Ruleset root, LessOptions options) {
  Ruleset evaldRoot;
  final _options = options ?? LessOptions();

  final variables = _options.variables;
  final evalEnv = Contexts.eval(_options);

  // Allows setting variables with a hash, so:
  //
  // variables = {'my-color': new Color('ff0000')}; will become:
  //
  //   new Declaration('@my-color',
  //     new Value([
  //       new Expression)([
  //         new Color('ff0000')
  //       ])
  //     ])
  //   )
  if (variables != null) {
    final vars = <Node>[];

    variables.forEach((String k, Node value) {
      if (value is! Value) {
        if (value is! Expression) value = Expression(<Node>[value]);
        value = Value(<Node>[value]);
      }
      vars.add(Declaration('@$k', value, index: 0));
    });
    evalEnv.frames = <Node>[Ruleset(null, vars)];
  }

  final preEvalVisitors = <VisitorBase>[];
  final visitors = <VisitorBase>[
    JoinSelectorVisitor(),
    SetTreeVisibilityVisitor(visible: true), // MarkVisibleSelectorsVisitor
    ProcessExtendsVisitor(),
    ToCSSVisitor(Contexts()
      ..compress = _options.compress
      ..numPrecision = _options.numPrecision)
  ];

  //
  // In js allows visitors to be added while visiting (?)
  //
  // js, @todo Add scoping for visitors just like functions for @plugin; right now they're global
  //
  if (_options.pluginManager != null) {
    _options.pluginManager.getVisitors().forEach((VisitorBase pluginVisitor) {
      if (pluginVisitor.isPreEvalVisitor) {
        preEvalVisitors.add(pluginVisitor);
      } else {
        if (pluginVisitor.isPreVisitor) {
          visitors.insert(0, pluginVisitor);
        } else {
          visitors.add(pluginVisitor);
        }
      }
    });
  }

  for (var i = 0; i < preEvalVisitors.length; i++) {
    preEvalVisitors[i].run(root);
  }

  evaldRoot = root.eval(evalEnv);

  for (var i = 0; i < visitors.length; i++) {
    visitors[i].run(evaldRoot);
  }

  return evaldRoot;
}