Merge null_safety branch into master (#24)
diff --git a/.travis.yml b/.travis.yml
index d2a0ee3..5647d2c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,24 +1,38 @@
language: dart
dart:
- - 2.4.0
- - dev
+- dev
-dart_task:
- - test: -p vm
- xvfb: false
- # Set concurrency to 1 to avoid flakes on Travis
- - test: -p firefox -j 1
- - dartanalyzer: --fatal-infos --fatal-warnings .
-
-matrix:
+jobs:
include:
- - dart: dev
- dart_task: dartfmt
+ - stage: analyze_and_format
+ name: "Analyze"
+ dart: dev
+ os: linux
+ script: dartanalyzer --enable-experiment=non-nullable --fatal-warnings --fatal-infos .
+ - stage: analyze_and_format
+ name: "Format"
+ dart: dev
+ os: linux
+ script: dartfmt -n --set-exit-if-changed .
+ - stage: test
+ name: "Vm Tests"
+ dart: dev
+ os: linux
+ script: pub run --enable-experiment=non-nullable test -p vm
+ - stage: test
+ name: "Web Tests"
+ dart: dev
+ os: linux
+ script: pub run --enable-experiment=non-nullable test -p chrome
+
+stages:
+ - analyze_and_format
+ - test
# Only building master means that we don't run two builds for each pull request.
branches:
- only: [master]
+ only: [master, null_safety]
cache:
directories:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7e2aef0..63beaaf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.1.0-nullsafety
+
+* Migrate to null safety. There are no expected semantic changes.
+
## 2.0.0
* Breaking: `BooleanSelector.evaluate` always takes a `bool Function(String)`.
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 73acb8d..e4e899c 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1,4 +1,7 @@
include: package:pedantic/analysis_options.yaml
+analyzer:
+ enable-experiment:
+ - non-nullable
linter:
rules:
- avoid_null_checks_in_equality_operators
diff --git a/lib/src/all.dart b/lib/src/all.dart
index 9255709..3424319 100644
--- a/lib/src/all.dart
+++ b/lib/src/all.dart
@@ -9,7 +9,7 @@
// TODO(nweiz): Stop explicitly providing a type argument when sdk#32412 is
// fixed.
@override
- final variables = const <String>[];
+ final Iterable<String> variables = const <String>[];
const All();
diff --git a/lib/src/ast.dart b/lib/src/ast.dart
index d16098a..0adfe99 100644
--- a/lib/src/ast.dart
+++ b/lib/src/ast.dart
@@ -15,7 +15,7 @@
/// statically-parsed annotation or from a parameter.
///
/// This may be `null` for nodes without source information.
- FileSpan get span;
+ FileSpan? get span;
/// All the variables in this node, in the order they appear.
Iterable<String> get variables;
@@ -27,7 +27,7 @@
/// A single variable.
class VariableNode implements Node {
@override
- final FileSpan span;
+ final FileSpan? span;
/// The variable name.
final String name;
@@ -53,7 +53,7 @@
/// A negation expression.
class NotNode implements Node {
@override
- final FileSpan span;
+ final FileSpan? span;
/// The expression being negated.
final Node child;
@@ -80,7 +80,7 @@
/// An or expression.
class OrNode implements Node {
@override
- FileSpan get span => _expandSafe(left.span, right.span);
+ FileSpan? get span => _expandSafe(left.span, right.span);
/// The left-hand branch of the expression.
final Node left;
@@ -119,7 +119,7 @@
/// An and expression.
class AndNode implements Node {
@override
- FileSpan get span => _expandSafe(left.span, right.span);
+ FileSpan? get span => _expandSafe(left.span, right.span);
/// The left-hand branch of the expression.
final Node left;
@@ -158,7 +158,7 @@
/// A ternary conditional expression.
class ConditionalNode implements Node {
@override
- FileSpan get span => _expandSafe(condition.span, whenFalse.span);
+ FileSpan? get span => _expandSafe(condition.span, whenFalse.span);
/// The condition expression to check.
final Node condition;
@@ -203,7 +203,7 @@
/// Like [FileSpan.expand], except if [start] and [end] are `null` or from
/// different files it returns `null` rather than throwing an error.
-FileSpan _expandSafe(FileSpan start, FileSpan end) {
+FileSpan? _expandSafe(FileSpan? start, FileSpan? end) {
if (start == null || end == null) return null;
if (start.file != end.file) return null;
return start.expand(end);
diff --git a/lib/src/none.dart b/lib/src/none.dart
index 42340b1..08ac08a 100644
--- a/lib/src/none.dart
+++ b/lib/src/none.dart
@@ -6,10 +6,8 @@
/// A selector that matches no inputs.
class None implements BooleanSelector {
- // TODO(nweiz): Stop explicitly providing a type argument when sdk#32412 is
- // fixed.
@override
- final variables = const <String>[];
+ final Iterable<String> variables = const [];
const None();
diff --git a/lib/src/parser.dart b/lib/src/parser.dart
index 1a0a73b..368ce5e 100644
--- a/lib/src/parser.dart
+++ b/lib/src/parser.dart
@@ -83,7 +83,7 @@
switch (token.type) {
case TokenType.not:
var child = _simpleExpression();
- return NotNode(child, token.span.expand(child.span));
+ return NotNode(child, token.span.expand(child.span!));
case TokenType.leftParen:
var child = _conditional();
diff --git a/lib/src/scanner.dart b/lib/src/scanner.dart
index 3516817..00e5ef7 100644
--- a/lib/src/scanner.dart
+++ b/lib/src/scanner.dart
@@ -29,7 +29,7 @@
final SpanScanner _scanner;
/// The next token to emit.
- Token _next;
+ Token? _next;
/// Whether the scanner has emitted a [TokenType.endOfFile] token.
bool _endOfFileEmitted = false;
@@ -124,7 +124,7 @@
/// Scans and returns an identifier token.
Token _scanIdentifier() {
_scanner.expect(_hyphenatedIdentifier, name: 'expression');
- return IdentifierToken(_scanner.lastMatch[0], _scanner.lastSpan);
+ return IdentifierToken(_scanner.lastMatch![0]!, _scanner.lastSpan!);
}
/// Consumes all whitespace and comments immediately following the cursor's
diff --git a/pubspec.yaml b/pubspec.yaml
index 73cd68b..15616a4 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,22 +1,94 @@
name: boolean_selector
-version: 2.0.0
+version: 2.1.0-nullsafety
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.4.0 <3.0.0'
+ sdk: '>=2.9.0-18.0 <2.9.0'
dependencies:
- source_span: ^1.0.0
- string_scanner: ^1.0.0
+ source_span: '>=1.8.0-nullsafety <1.8.0'
+ string_scanner: '>=1.1.0-nullsafety <1.1.0'
dev_dependencies:
pedantic: ^1.0.0
- test: ^1.2.0
+ test: any
+ test_api: any
+ test_core: any
dependency_overrides:
- test: 1.11.1
- test_api: 0.2.13
- test_core: 0.2.18
+ async:
+ git:
+ url: git://github.com/dart-lang/async.git
+ ref: null_safety
+ charcode:
+ git:
+ url: git://github.com/dart-lang/charcode.git
+ ref: null_safety
+ collection: 1.15.0-nullsafety
+ js:
+ git:
+ url: git://github.com/dart-lang/sdk.git
+ path: pkg/js
+ matcher:
+ git:
+ url: git://github.com/dart-lang/matcher.git
+ ref: null_safety
+ meta: 1.3.0-nullsafety
+ path:
+ git:
+ url: git://github.com/dart-lang/path.git
+ ref: null_safety
+ pedantic:
+ git:
+ url: git://github.com/dart-lang/pedantic.git
+ ref: null_safety
+ pool:
+ git:
+ url: git://github.com/dart-lang/pool.git
+ ref: null_safety
+ source_maps:
+ git:
+ url: git://github.com/dart-lang/source_maps.git
+ ref: null_safety
+ source_map_stack_trace:
+ git:
+ url: git://github.com/dart-lang/source_map_stack_trace.git
+ ref: null_safety
+ source_span:
+ git:
+ url: git://github.com/dart-lang/source_span.git
+ ref: null_safety
+ stack_trace:
+ git:
+ url: git://github.com/dart-lang/stack_trace.git
+ ref: null_safety
+ stream_channel:
+ git:
+ url: git://github.com/dart-lang/stream_channel.git
+ ref: null_safety
+ string_scanner:
+ git:
+ url: git://github.com/dart-lang/string_scanner.git
+ ref: null_safety
+ term_glyph:
+ git:
+ url: git://github.com/dart-lang/term_glyph.git
+ ref: null_safety
+ test_api:
+ git:
+ url: git://github.com/dart-lang/test.git
+ ref: null_safety
+ path: pkgs/test_api
+ test_core:
+ git:
+ url: git://github.com/dart-lang/test.git
+ ref: null_safety
+ path: pkgs/test_core
+ test:
+ git:
+ url: git://github.com/dart-lang/test.git
+ ref: null_safety
+ path: pkgs/test
diff --git a/test/evaluate_test.dart b/test/evaluate_test.dart
index 5dfc2cc..eb69335 100644
--- a/test/evaluate_test.dart
+++ b/test/evaluate_test.dart
@@ -46,7 +46,7 @@
///
/// By default, "true" is true and all other variables are "false".
void _expectEval(String expression, bool result,
- {bool Function(String variable) semantics}) {
+ {bool Function(String variable)? semantics}) {
expect(_eval(expression, semantics: semantics), equals(result),
reason: 'Expected "$expression" to evaluate to $result.');
}
@@ -54,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, {bool Function(String variable) semantics}) {
+bool _eval(String expression, {bool Function(String variable)? semantics}) {
var selector = BooleanSelector.parse(expression);
return selector.evaluate(semantics ?? (v) => v == 'true');
}
diff --git a/test/parser_test.dart b/test/parser_test.dart
index 5a1bd83..5eca512 100644
--- a/test/parser_test.dart
+++ b/test/parser_test.dart
@@ -254,10 +254,10 @@
/// A matcher that asserts that a value is a [VariableNode] with the given
/// [name].
Matcher _isVar(String name) => predicate(
- (value) => value is VariableNode && value.name == name,
+ (dynamic value) => value is VariableNode && value.name == name,
'is a variable named "$name"');
-void _expectToString(String selector, [String result]) {
+void _expectToString(String selector, [String? result]) {
result ??= selector;
expect(_toString(selector), equals(result),
reason: 'Expected toString of "$selector" to be "$result".');
diff --git a/test/to_string_test.dart b/test/to_string_test.dart
index ec1b4de..1047fd1 100644
--- a/test/to_string_test.dart
+++ b/test/to_string_test.dart
@@ -76,7 +76,7 @@
});
}
-void _expectToString(String selector, [String result]) {
+void _expectToString(String selector, [String? result]) {
result ??= selector;
expect(_toString(selector), equals(result),
reason: 'Expected toString of "$selector" to be "$result".');