blob: c920e5250729802cf2d1afbffbd2ad1ee5f48198 [file] [log] [blame]
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import '../boolean_selector.dart';
import 'ast.dart';
import 'evaluator.dart';
import 'intersection_selector.dart';
import 'parser.dart';
import 'union_selector.dart';
import 'validator.dart';
/// The concrete implementation of a [BooleanSelector] parsed from a string.
///
/// This is separate from [BooleanSelector] so that [intersect] and [union] can
/// check to see whether they're passed a [BooleanSelectorImpl] or a different
/// class that implements [BooleanSelector].
class BooleanSelectorImpl implements BooleanSelector {
/// The parsed AST.
final Node _selector;
/// Parses [selector].
///
/// This will throw a [SourceSpanFormatException] if the selector is
/// malformed or if it uses an undefined variable.
BooleanSelectorImpl.parse(String selector)
: _selector = new Parser(selector).parse();
BooleanSelectorImpl._(this._selector);
Iterable<String> get variables => _selector.variables;
bool evaluate(semantics) => _selector.accept(new Evaluator(semantics));
BooleanSelector intersection(BooleanSelector other) {
if (other == BooleanSelector.all) return this;
if (other == BooleanSelector.none) return other;
return other is BooleanSelectorImpl
? new BooleanSelectorImpl._(new AndNode(_selector, other._selector))
: new IntersectionSelector(this, other);
}
BooleanSelector union(BooleanSelector other) {
if (other == BooleanSelector.all) return other;
if (other == BooleanSelector.none) return this;
return other is BooleanSelectorImpl
? new BooleanSelectorImpl._(new OrNode(_selector, other._selector))
: new UnionSelector(this, other);
}
void validate(bool isDefined(String variable)) {
_selector.accept(new Validator(isDefined));
}
String toString() => _selector.toString();
bool operator==(other) =>
other is BooleanSelectorImpl && _selector == other._selector;
int get hashCode => _selector.hashCode;
}