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

Unified Diff: third_party/pkg/angular/lib/core/parser/dynamic_parser_impl.dart

Issue 257423008: Update all Angular libs (run update_all.sh). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 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: third_party/pkg/angular/lib/core/parser/dynamic_parser_impl.dart
diff --git a/third_party/pkg/angular/lib/core/parser/dynamic_parser_impl.dart b/third_party/pkg/angular/lib/core/parser/dynamic_parser_impl.dart
index 0b893ddcf27389d2924011dc28232c30ba8f3d1e..60c6a004c498baf29b3feec0b0bf1f130e0aaf1e 100644
--- a/third_party/pkg/angular/lib/core/parser/dynamic_parser_impl.dart
+++ b/third_party/pkg/angular/lib/core/parser/dynamic_parser_impl.dart
@@ -3,9 +3,10 @@ library angular.core.parser.dynamic_parser_impl;
import 'package:angular/core/parser/parser.dart' show ParserBackend;
import 'package:angular/core/parser/lexer.dart';
import 'package:angular/core/parser/syntax.dart';
+import 'package:angular/core/parser/characters.dart';
+import 'package:angular/utils.dart' show isReservedWord;
class DynamicParserImpl {
- static Token EOF = new Token(-1, null);
final ParserBackend backend;
final String input;
final List<Token> tokens;
@@ -14,27 +15,33 @@ class DynamicParserImpl {
DynamicParserImpl(Lexer lexer, this.backend, String input)
: this.input = input, tokens = lexer.call(input);
- Token get peek {
- return (index < tokens.length) ? tokens[index] : EOF;
- }
+ Token get next => peek(0);
+ Token peek(int offset) => (index + offset < tokens.length)
+ ? tokens[index + offset]
+ : Token.EOF;
parseChain() {
bool isChain = false;
- while (optional(';')) {
+ while (optionalCharacter($SEMICOLON)) {
isChain = true;
}
List expressions = [];
while (index < tokens.length) {
- if (peek.text == ')' || peek.text == '}' || peek.text == ']') {
- error('Unconsumed token ${peek.text}');
+ if (next.isCharacter($RPAREN) ||
+ next.isCharacter($RBRACE) ||
+ next.isCharacter($RBRACKET)) {
+ error('Unconsumed token $next');
}
var expr = parseFilter();
expressions.add(expr);
- while (optional(';')) {
+ while (optionalCharacter($SEMICOLON)) {
isChain = true;
}
if (isChain && expr is Filter) {
- error('cannot have a filter in a chain');
+ error('Cannot have a formatter in a chain');
+ }
+ if (!isChain && index < tokens.length) {
+ error("'${next}' is an unexpected token", index);
}
}
return (expressions.length == 1)
@@ -44,11 +51,10 @@ class DynamicParserImpl {
parseFilter() {
var result = parseExpression();
- while (optional('|')) {
- String name = peek.text; // TODO(kasperl): Restrict to identifier?
- advance();
+ while (optionalOperator('|')) {
+ String name = expectIdentifierOrKeyword();
List arguments = [];
- while (optional(':')) {
+ while (optionalCharacter($COLON)) {
// TODO(kasperl): Is this really supposed to be expressions?
arguments.add(parseExpression());
}
@@ -58,27 +64,27 @@ class DynamicParserImpl {
}
parseExpression() {
- int start = peek.index;
+ int start = next.index;
var result = parseConditional();
- while (peek.text == '=') {
+ while (next.isOperator('=')) {
if (!backend.isAssignable(result)) {
- int end = (index < tokens.length) ? peek.index : input.length;
+ int end = (index < tokens.length) ? next.index : input.length;
String expression = input.substring(start, end);
error('Expression $expression is not assignable');
}
- expect('=');
+ expectOperator('=');
result = backend.newAssign(result, parseConditional());
}
return result;
}
parseConditional() {
- int start = peek.index;
+ int start = next.index;
var result = parseLogicalOr();
- if (optional('?')) {
+ if (optionalOperator('?')) {
var yes = parseExpression();
- if (!optional(':')) {
- int end = (index < tokens.length) ? peek.index : input.length;
+ if (!optionalCharacter($COLON)) {
+ int end = (index < tokens.length) ? next.index : input.length;
String expression = input.substring(start, end);
error('Conditional expression $expression requires all 3 expressions');
}
@@ -91,7 +97,7 @@ class DynamicParserImpl {
parseLogicalOr() {
// '||'
var result = parseLogicalAnd();
- while (optional('||')) {
+ while (optionalOperator('||')) {
result = backend.newBinaryLogicalOr(result, parseLogicalAnd());
}
return result;
@@ -100,7 +106,7 @@ class DynamicParserImpl {
parseLogicalAnd() {
// '&&'
var result = parseEquality();
- while (optional('&&')) {
+ while (optionalOperator('&&')) {
result = backend.newBinaryLogicalAnd(result, parseEquality());
}
return result;
@@ -110,9 +116,9 @@ class DynamicParserImpl {
// '==','!='
var result = parseRelational();
while (true) {
- if (optional('==')) {
+ if (optionalOperator('==')) {
result = backend.newBinaryEqual(result, parseRelational());
- } else if (optional('!=')) {
+ } else if (optionalOperator('!=')) {
result = backend.newBinaryNotEqual(result, parseRelational());
} else {
return result;
@@ -124,13 +130,13 @@ class DynamicParserImpl {
// '<', '>', '<=', '>='
var result = parseAdditive();
while (true) {
- if (optional('<')) {
+ if (optionalOperator('<')) {
result = backend.newBinaryLessThan(result, parseAdditive());
- } else if (optional('>')) {
+ } else if (optionalOperator('>')) {
result = backend.newBinaryGreaterThan(result, parseAdditive());
- } else if (optional('<=')) {
+ } else if (optionalOperator('<=')) {
result = backend.newBinaryLessThanEqual(result, parseAdditive());
- } else if (optional('>=')) {
+ } else if (optionalOperator('>=')) {
result = backend.newBinaryGreaterThanEqual(result, parseAdditive());
} else {
return result;
@@ -142,9 +148,9 @@ class DynamicParserImpl {
// '+', '-'
var result = parseMultiplicative();
while (true) {
- if (optional('+')) {
+ if (optionalOperator('+')) {
result = backend.newBinaryPlus(result, parseMultiplicative());
- } else if (optional('-')) {
+ } else if (optionalOperator('-')) {
result = backend.newBinaryMinus(result, parseMultiplicative());
} else {
return result;
@@ -156,13 +162,13 @@ class DynamicParserImpl {
// '*', '%', '/', '~/'
var result = parsePrefix();
while (true) {
- if (optional('*')) {
+ if (optionalOperator('*')) {
result = backend.newBinaryMultiply(result, parsePrefix());
- } else if (optional('%')) {
+ } else if (optionalOperator('%')) {
result = backend.newBinaryModulo(result, parsePrefix());
- } else if (optional('/')) {
+ } else if (optionalOperator('/')) {
result = backend.newBinaryDivide(result, parsePrefix());
- } else if (optional('~/')) {
+ } else if (optionalOperator('~/')) {
result = backend.newBinaryTruncatingDivide(result, parsePrefix());
} else {
return result;
@@ -171,12 +177,12 @@ class DynamicParserImpl {
}
parsePrefix() {
- if (optional('+')) {
+ if (optionalOperator('+')) {
// TODO(kasperl): This is different than the original parser.
return backend.newPrefixPlus(parsePrefix());
- } else if (optional('-')) {
+ } else if (optionalOperator('-')) {
return backend.newPrefixMinus(parsePrefix());
- } else if (optional('!')) {
+ } else if (optionalOperator('!')) {
return backend.newPrefixNot(parsePrefix());
} else {
return parseAccessOrCallMember();
@@ -186,24 +192,22 @@ class DynamicParserImpl {
parseAccessOrCallMember() {
var result = parsePrimary();
while (true) {
- if (optional('.')) {
- // TODO(kasperl): Check that this is an identifier. Are keywords okay?
- String name = peek.text;
- advance();
- if (optional('(')) {
- List arguments = parseExpressionList(')');
- expect(')');
+ if (optionalCharacter($PERIOD)) {
+ String name = expectIdentifierOrKeyword();
+ if (optionalCharacter($LPAREN)) {
+ CallArguments arguments = parseCallArguments();
+ expectCharacter($RPAREN);
result = backend.newCallMember(result, name, arguments);
} else {
result = backend.newAccessMember(result, name);
}
- } else if (optional('[')) {
+ } else if (optionalCharacter($LBRACKET)) {
var key = parseExpression();
- expect(']');
+ expectCharacter($RBRACKET);
result = backend.newAccessKeyed(result, key);
- } else if (optional('(')) {
- List arguments = parseExpressionList(')');
- expect(')');
+ } else if (optionalCharacter($LPAREN)) {
+ CallArguments arguments = parseCallArguments();
+ expectCharacter($RPAREN);
result = backend.newCallFunction(result, arguments);
} else {
return result;
@@ -212,77 +216,107 @@ class DynamicParserImpl {
}
parsePrimary() {
- if (optional('(')) {
- var result = parseExpression();
- expect(')');
+ if (optionalCharacter($LPAREN)) {
+ var result = parseFilter();
+ expectCharacter($RPAREN);
return result;
- } else if (optional('null') || optional('undefined')) {
+ } else if (next.isKeywordNull || next.isKeywordUndefined) {
+ advance();
return backend.newLiteralNull();
- } else if (optional('true')) {
+ } else if (next.isKeywordTrue) {
+ advance();
return backend.newLiteralBoolean(true);
- } else if (optional('false')) {
+ } else if (next.isKeywordFalse) {
+ advance();
return backend.newLiteralBoolean(false);
- } else if (optional('[')) {
- List elements = parseExpressionList(']');
- expect(']');
+ } else if (optionalCharacter($LBRACKET)) {
+ List elements = parseExpressionList($RBRACKET);
+ expectCharacter($RBRACKET);
return backend.newLiteralArray(elements);
- } else if (peek.text == '{') {
+ } else if (next.isCharacter($LBRACE)) {
return parseObject();
- } else if (peek.key != null) {
+ } else if (next.isIdentifier) {
return parseAccessOrCallScope();
- } else if (peek.value != null) {
- var value = peek.value;
+ } else if (next.isNumber) {
+ num value = next.toNumber();
advance();
- return (value is num)
- ? backend.newLiteralNumber(value)
- : backend.newLiteralString(value);
+ return backend.newLiteralNumber(value);
+ } else if (next.isString) {
+ String value = next.toString();
+ advance();
+ return backend.newLiteralString(value);
} else if (index >= tokens.length) {
throw 'Unexpected end of expression: $input';
} else {
- error('Unexpected token ${peek.text}');
+ error('Unexpected token $next');
}
}
parseAccessOrCallScope() {
- String name = peek.key;
- advance();
- if (!optional('(')) return backend.newAccessScope(name);
- List arguments = parseExpressionList(')');
- expect(')');
+ String name = expectIdentifierOrKeyword();
+ if (!optionalCharacter($LPAREN)) return backend.newAccessScope(name);
+ CallArguments arguments = parseCallArguments();
+ expectCharacter($RPAREN);
return backend.newCallScope(name, arguments);
}
parseObject() {
List<String> keys = [];
List values = [];
- expect('{');
- if (peek.text != '}') {
+ expectCharacter($LBRACE);
+ if (!optionalCharacter($RBRACE)) {
do {
- // TODO(kasperl): Stricter checking. Only allow identifiers
- // and strings as keys. Maybe also keywords?
- var value = peek.value;
- keys.add(value is String ? value : peek.text);
- advance();
- expect(':');
+ String key = expectIdentifierOrKeywordOrString();
+ keys.add(key);
+ expectCharacter($COLON);
values.add(parseExpression());
- } while (optional(','));
+ } while (optionalCharacter($COMMA));
+ expectCharacter($RBRACE);
}
- expect('}');
return backend.newLiteralObject(keys, values);
}
- List parseExpressionList(String terminator) {
+ List parseExpressionList(int terminator) {
List result = [];
- if (peek.text != terminator) {
+ if (!next.isCharacter(terminator)) {
do {
result.add(parseExpression());
- } while (optional(','));
+ } while (optionalCharacter($COMMA));
}
return result;
}
- bool optional(text) {
- if (peek.text == text) {
+ CallArguments parseCallArguments() {
+ if (next.isCharacter($RPAREN)) {
+ return const CallArguments(const [], const {});
+ }
+ // Parse the positional arguments.
+ List positionals = [];
+ while (true) {
+ if (peek(1).isCharacter($COLON)) break;
+ positionals.add(parseExpression());
+ if (!optionalCharacter($COMMA)) {
+ return new CallArguments(positionals, const {});
+ }
+ }
+ // Parse the named arguments.
+ Map named = {};
+ do {
+ int marker = index;
+ String name = expectIdentifierOrKeyword();
+ if (isReservedWord(name)) {
+ error("Cannot use Dart reserved word '$name' as named argument", marker);
+ } else if (named.containsKey(name)) {
+ error("Duplicate argument named '$name'", marker);
+ }
+ expectCharacter($COLON);
+ named[name] = parseExpression();
+ } while (optionalCharacter($COMMA));
+ return new CallArguments(positionals, named);
+ }
+
+ bool optionalCharacter(int code) {
+ if (next.isCharacter(code)) {
advance();
return true;
} else {
@@ -290,19 +324,49 @@ class DynamicParserImpl {
}
}
- void expect(text) {
- if (peek.text == text) {
+ bool optionalOperator(String operator) {
+ if (next.isOperator(operator)) {
advance();
+ return true;
} else {
- error('Missing expected $text');
+ return false;
+ }
+ }
+
+ void expectCharacter(int code) {
+ if (optionalCharacter(code)) return;
+ error('Missing expected ${new String.fromCharCode(code)}');
+ }
+
+ void expectOperator(String operator) {
+ if (optionalOperator(operator)) return;
+ error('Missing expected operator $operator');
+ }
+
+ String expectIdentifierOrKeyword() {
+ if (!next.isIdentifier && !next.isKeyword) {
+ error('Unexpected token $next, expected identifier or keyword');
}
+ String result = next.toString();
+ advance();
+ return result;
+ }
+
+ String expectIdentifierOrKeywordOrString() {
+ if (!next.isIdentifier && !next.isKeyword && !next.isString) {
+ error('Unexpected token $next, expected identifier, keyword, or string');
+ }
+ String result = next.toString();
+ advance();
+ return result;
}
void advance() {
index++;
}
- void error(message) {
+ void error(message, [int index]) {
+ if (index == null) index = this.index;
String location = (index < tokens.length)
? 'at column ${tokens[index].index + 1} in'
: 'the end of the expression';
« no previous file with comments | « third_party/pkg/angular/lib/core/parser/dynamic_parser.dart ('k') | third_party/pkg/angular/lib/core/parser/eval.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698