Tighten type for argument to `evaluate` (#22)
Taking a `dynamic` throws away the static help that a caller would get
with an argument type. Since it is easy to refactor callers currently
passing an `Iterable<String>` to tear off the `.contains` method we can
take the Function type always. This also improves inference for argument
types in places that are passing a function literal.
diff --git a/.travis.yml b/.travis.yml
index 8590a67..d2a0ee3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,7 @@
language: dart
dart:
- - 2.0.0
+ - 2.4.0
- dev
dart_task:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d6cdc28..7e2aef0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 2.0.0
+
+* Breaking: `BooleanSelector.evaluate` always takes a `bool Function(String)`.
+ For use cases previously passing a `Set<String>`, tear off the `.contains`
+ method. For use cases passing an `Iterable<String>` it may be worthwhile to
+ first use `.toSet()` before tearing off `.contains`.
+
## 1.0.5
* Update package metadata & add `example/` folder
diff --git a/README.md b/README.md
index 33c2eb5..8f636a6 100644
--- a/README.md
+++ b/README.md
@@ -17,9 +17,8 @@
A boolean selector is parsed from a string using
[`new BooleanSelector.parse()`][parse], and evaluated against a set of variables
-using [`BooleanSelector.evaluate()`][evaluate]. The variables may be supplied as
-a list of strings, or as a function that takes a variable name and returns its
-value. For example:
+using [`BooleanSelector.evaluate()`][evaluate]. The variables are supplied as
+a function that takes a variable name and returns its value. For example:
[parse]: https://pub.dev/documentation/boolean_selector/latest/boolean_selector/BooleanSelector/BooleanSelector.parse.html
diff --git a/lib/boolean_selector.dart b/lib/boolean_selector.dart
index e32eb40..3a66ec4 100644
--- a/lib/boolean_selector.dart
+++ b/lib/boolean_selector.dart
@@ -36,11 +36,9 @@
/// Returns whether the selector matches the given [semantics].
///
- /// The [semantics] define which variables evaluate to `true` or `false`. The
- /// parameter can be either an `Iterable<String>` containing variables that
- /// should evaluate to `true`, or a function `bool semantics(String variable)`
- /// that returns a variable's value.
- bool evaluate(semantics);
+ /// The [semantics] define which variables evaluate to `true` or `false`. When
+ /// passed a variable name it should return the value of that variable.
+ bool evaluate(bool Function(String variable) semantics);
/// Returns a new [BooleanSelector] that matches only inputs matched by both
/// [this] and [other].
diff --git a/lib/src/all.dart b/lib/src/all.dart
index d634b9f..9255709 100644
--- a/lib/src/all.dart
+++ b/lib/src/all.dart
@@ -14,7 +14,7 @@
const All();
@override
- bool evaluate(semantics) => true;
+ bool evaluate(bool Function(String variable) semantics) => true;
@override
BooleanSelector intersection(BooleanSelector other) => other;
diff --git a/lib/src/evaluator.dart b/lib/src/evaluator.dart
index c15c0ca..ee57149 100644
--- a/lib/src/evaluator.dart
+++ b/lib/src/evaluator.dart
@@ -5,18 +5,12 @@
import 'ast.dart';
import 'visitor.dart';
-typedef _Semantics = bool Function(String variable);
-
/// A visitor for evaluating boolean selectors against a specific set of
/// semantics.
class Evaluator implements Visitor<bool> {
- /// The semantics to evaluate against.
- final _Semantics _semantics;
+ final bool Function(String variable) _semantics;
- Evaluator(semantics)
- : _semantics = semantics is Iterable
- ? semantics.toSet().contains
- : semantics as _Semantics;
+ Evaluator(this._semantics);
@override
bool visitVariable(VariableNode node) => _semantics(node.name);
diff --git a/lib/src/impl.dart b/lib/src/impl.dart
index 3cd87c8..16dc3ec 100644
--- a/lib/src/impl.dart
+++ b/lib/src/impl.dart
@@ -32,7 +32,8 @@
Iterable<String> get variables => _selector.variables;
@override
- bool evaluate(semantics) => _selector.accept(Evaluator(semantics));
+ bool evaluate(bool Function(String variable) semantics) =>
+ _selector.accept(Evaluator(semantics));
@override
BooleanSelector intersection(BooleanSelector other) {
diff --git a/lib/src/none.dart b/lib/src/none.dart
index 1fc616f..42340b1 100644
--- a/lib/src/none.dart
+++ b/lib/src/none.dart
@@ -14,7 +14,7 @@
const None();
@override
- bool evaluate(semantics) => false;
+ bool evaluate(bool Function(String variable) semantics) => false;
@override
BooleanSelector intersection(BooleanSelector other) => this;
diff --git a/lib/src/union_selector.dart b/lib/src/union_selector.dart
index c985be9..838e3d4 100644
--- a/lib/src/union_selector.dart
+++ b/lib/src/union_selector.dart
@@ -17,7 +17,7 @@
_selector1.variables.toList()..addAll(_selector2.variables);
@override
- bool evaluate(semantics) =>
+ bool evaluate(bool Function(String variable) semantics) =>
_selector1.evaluate(semantics) || _selector2.evaluate(semantics);
@override
diff --git a/pubspec.yaml b/pubspec.yaml
index ba9a4b8..73cd68b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,12 +1,12 @@
name: boolean_selector
-version: 1.0.6-dev
+version: 2.0.0
description: >-
A flexible syntax for boolean expressions, based on a simplified version of
Dart's expression syntax.
homepage: https://github.com/dart-lang/boolean_selector
environment:
- sdk: '>=2.0.0 <3.0.0'
+ sdk: '>=2.4.0 <3.0.0'
dependencies:
source_span: ^1.0.0
@@ -15,3 +15,8 @@
dev_dependencies:
pedantic: ^1.0.0
test: ^1.2.0
+
+dependency_overrides:
+ test: 1.11.1
+ test_api: 0.2.13
+ test_core: 0.2.18
diff --git a/test/evaluate_test.dart b/test/evaluate_test.dart
index 9df5fdc..5dfc2cc 100644
--- a/test/evaluate_test.dart
+++ b/test/evaluate_test.dart
@@ -36,19 +36,17 @@
});
test('with a semantics function', () {
- _expectEval('foo', false,
- semantics: (String variable) => variable.contains('a'));
- _expectEval('bar', true,
- semantics: (String variable) => variable.contains('a'));
- _expectEval('baz', true,
- semantics: (String variable) => variable.contains('a'));
+ _expectEval('foo', false, semantics: (variable) => variable.contains('a'));
+ _expectEval('bar', true, semantics: (variable) => variable.contains('a'));
+ _expectEval('baz', true, semantics: (variable) => variable.contains('a'));
});
}
/// Asserts that [expression] evaluates to [result] against [semantics].
///
/// By default, "true" is true and all other variables are "false".
-void _expectEval(String expression, bool result, {semantics}) {
+void _expectEval(String expression, bool result,
+ {bool Function(String variable) semantics}) {
expect(_eval(expression, semantics: semantics), equals(result),
reason: 'Expected "$expression" to evaluate to $result.');
}
@@ -56,7 +54,7 @@
/// Returns the result of evaluating [expression] on [semantics].
///
/// By default, "true" is true and all other variables are "false".
-bool _eval(String expression, {semantics}) {
+bool _eval(String expression, {bool Function(String variable) semantics}) {
var selector = BooleanSelector.parse(expression);
- return selector.evaluate(semantics ?? ['true']);
+ return selector.evaluate(semantics ?? (v) => v == 'true');
}