Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Unified Diff: tools/testing/dart/status_expression.dart

Issue 2913963002: Add negation to single-identifier tests in status files. (Closed)
Patch Set: Document the isIdentifier optimization. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/testing/dart/status_expression.dart
diff --git a/tools/testing/dart/status_expression.dart b/tools/testing/dart/status_expression.dart
index 10b30953096af0f6f634f6f8c94c6e36e9b3c645..f58884d7dba7f53e36574281bb3faa88e39c11d7 100644
--- a/tools/testing/dart/status_expression.dart
+++ b/tools/testing/dart/status_expression.dart
@@ -13,7 +13,8 @@ abstract class Expression {
/// expression := or
/// or := and ( "||" and )*
/// and := primary ( "&&" primary )*
- /// primary := "$" identifier ( ( "==" | "!=" ) identifier )? |
+ /// primary := "$" identifier ( "==" | "!=" ) identifier |
+ /// "!"? "$" identifier |
/// "(" expression ")"
/// identifier := regex "\w+"
///
@@ -44,6 +45,7 @@ class _Token {
static const notEqual = "!=";
static const and = "&&";
static const or = "||";
+ static const not = "!";
}
/// A reference to a variable.
@@ -70,8 +72,10 @@ class _Variable {
}
/// Tests whether a given variable is or is not equal some literal value, as in:
-///
-/// $variable == someValue
+/// ```
+/// $variable == someValue
+/// ```
+/// Negate the result if [negate] is true.
class _ComparisonExpression implements Expression {
final _Variable left;
final String right;
@@ -92,22 +96,36 @@ class _ComparisonExpression implements Expression {
/// A reference to a variable defined in the environment. The expression
/// evaluates to true if the variable's stringified value is "true".
-///
+/// ```
/// $variable
+/// ```
+/// is equivalent to
+/// ```
+/// $variable == true
+/// ```
+/// Negates result if [negate] is true, so
+/// ```
+/// !$variable
+/// ```
+/// is equivalent to
+/// ```
+/// $variable != true
+/// ```
class _VariableExpression implements Expression {
final _Variable variable;
+ final bool negate;
- _VariableExpression(this.variable);
+ _VariableExpression(this.variable, {this.negate = false});
void validate(List<String> errors) {
// It must be a Boolean, so it should allow either Boolean value.
Environment.validate(variable.name, "true", errors);
}
- bool evaluate(Environment environment) =>
- variable.lookup(environment) == "true";
+ bool evaluate(Map<String, dynamic> environment) =>
+ negate != (variable.lookup(environment) == "true");
- String toString() => "(bool \$${variable.name})";
+ String toString() => "(bool ${negate ? "! " : ""}\$${variable.name})";
}
/// A logical `||` or `&&` expression.
@@ -179,6 +197,11 @@ class _ExpressionParser {
return value;
}
+ bool negate = false;
Bob Nystrom 2017/06/01 23:07:46 Nit: "bool" -> "var". I'm moving test.dart to con
Lasse Reichstein Nielsen 2017/06/07 08:51:49 Done.
+ if (_scanner.match(_Token.not)) {
+ negate = true;
+ }
+
// The only atomic booleans are of the form $variable == value or
// of the form $variable.
if (!_scanner.match(_Token.dollar)) {
@@ -194,8 +217,9 @@ class _ExpressionParser {
var left = new _Variable(_scanner.current);
_scanner.advance();
- if (_scanner.current == _Token.equals ||
- _scanner.current == _Token.notEqual) {
+ if (!negate &&
+ (_scanner.current == _Token.equals ||
+ _scanner.current == _Token.notEqual)) {
var negate = _scanner.advance() == _Token.notEqual;
Bob Nystrom 2017/06/01 23:07:46 How about renaming this local to "isNotEqual" to a
Lasse Reichstein Nielsen 2017/06/07 08:51:49 Done.
if (!_scanner.isIdentifier) {
@@ -206,20 +230,22 @@ class _ExpressionParser {
var right = _scanner.advance();
return new _ComparisonExpression(left, right, negate);
} else {
- return new _VariableExpression(left);
+ return new _VariableExpression(left, negate: negate);
}
}
}
/// An iterator that allows peeking at the current token.
class _Scanner {
- /// Tokens are "(", ")", "$", "&&", "||", "==", "!=", and (maximal) \w+.
- static final _testPattern =
- new RegExp(r"^([()$\w\s]|(\&\&)|(\|\|)|(\=\=)|(\!\=))+$");
- static final _tokenPattern =
- new RegExp(r"[()$]|(\&\&)|(\|\|)|(\=\=)|(\!\=)|\w+");
+ /// Tokens are "(", ")", "$", "&&", "||", "!", ==", "!=", and (maximal) \w+.
+ static final _testPattern = new RegExp(r"^(?:[()$\w\s]|&&|\|\||==|!=?)+$");
+ static final _tokenPattern = new RegExp(r"[()$]|&&|\|\||==|!=?|\w+");
Bob Nystrom 2017/06/01 23:07:46 Much nicer!
Lasse Reichstein Nielsen 2017/06/07 08:51:49 Occupational hazard - I can't pass by a RegExp wit
- static final _identifierPattern = new RegExp(r"^\w+$");
+ /// Pattern that recognizes identifier tokens.
+ ///
+ /// Only checks the first character, since no non-identifier token can start
+ /// with a word character.
+ static final _identifierPattern = new RegExp(r"^\w");
/// The token strings being iterated.
final Iterator<String> tokenIterator;
@@ -244,7 +270,10 @@ class _Scanner {
bool get hasMore => current != null;
/// Returns `true` if the current token is an identifier.
- bool get isIdentifier => _identifierPattern.hasMatch(current);
+ // All non-identifier tokens are one or two characters,
+ // so a longer token must be an identifier.
+ bool get isIdentifier =>
+ current.length > 2 || _identifierPattern.hasMatch(current);
Bob Nystrom 2017/06/01 23:07:46 Is this an optimization? It seems unnecessary to m
Lasse Reichstein Nielsen 2017/06/07 08:51:49 Yes, optimization. Necessary? Maybe not, but it se
/// If the current token is [token], consumes it and returns `true`.
bool match(String token) {

Powered by Google App Engine
This is Rietveld 408576698