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

Side by Side Diff: third_party/pkg/angular/lib/core/parser/lexer.dart

Issue 148453003: Updating Angular version (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 part of angular.core.parser; 1 library angular.core.parser.lexer;
2 2
3 import 'package:angular/core/module.dart' show NgInjectableService;
4 import 'package:angular/core/parser/characters.dart';
5
6 class Token {
7 final int index;
8 final String text;
9
10 var value;
11 // Tokens should have one of these set.
12 String opKey;
13 String key;
14
15 Token(this.index, this.text);
16
17 withOp(op) {
18 this.opKey = op;
19 }
20
21 withGetterSetter(key) {
22 this.key = key;
23 }
24
25 withValue(value) { this.value = value; }
26
27 toString() => "Token($text)";
28 }
29
30
3 @NgInjectableService() 31 @NgInjectableService()
4 class Lexer { 32 class Lexer {
5 List<Token> call(String text) { 33 List<Token> call(String text) {
6 Scanner scanner = new Scanner(text); 34 Scanner scanner = new Scanner(text);
7 List<Token> tokens = []; 35 List<Token> tokens = [];
8 Token token = scanner.scanToken(); 36 Token token = scanner.scanToken();
9 while (token != null) { 37 while (token != null) {
10 tokens.add(token); 38 tokens.add(token);
11 token = scanner.scanToken(); 39 token = scanner.scanToken();
12 } 40 }
13 return tokens; 41 return tokens;
14 } 42 }
15 } 43 }
16 44
17 class Scanner { 45 class Scanner {
18 final String input; 46 final String input;
19 final int length; 47 final int length;
20 48
21 // TODO(kasperl): Get rid of this buffer. It is currently used for
22 // pushing back tokens for method calls found while scanning
23 // identifiers. We should be able to do this in the parser instead.
24 final List<Token> buffer = [];
25
26 int peek = 0; 49 int peek = 0;
27 int index = -1; 50 int index = -1;
28 51
29 Scanner(String input) : this.input = input, this.length = input.length { 52 Scanner(String input) : this.input = input, this.length = input.length {
30 advance(); 53 advance();
31 } 54 }
32 55
33 Token scanToken() { 56 Token scanToken() {
34 // TODO(kasperl): The current handling of method calls is somewhat
35 // complicated. We should simplify it by dealing with it in the parser.
36 if (!buffer.isEmpty) return buffer.removeLast();
37
38 // Skip whitespace. 57 // Skip whitespace.
39 while (isWhitespace(peek)) advance(); 58 while (peek <= $SPACE) {
59 if (++index >= length) {
60 peek = $EOF;
61 return null;
62 } else {
63 peek = input.codeUnitAt(index);
64 }
65 }
40 66
41 // Handle identifiers and numbers. 67 // Handle identifiers and numbers.
42 if (isIdentifierStart(peek)) return scanIdentifier(); 68 if (isIdentifierStart(peek)) return scanIdentifier();
43 if (isDigit(peek)) return scanNumber(index); 69 if (isDigit(peek)) return scanNumber(index);
44 70
45 int start = index; 71 int start = index;
46 switch (peek) { 72 switch (peek) {
47 case $EOF:
48 return null;
49 case $PERIOD: 73 case $PERIOD:
50 advance(); 74 advance();
51 return isDigit(peek) ? scanNumber(start) : new Token(start, '.'); 75 return isDigit(peek) ? scanNumber(start) : new Token(start, '.');
52 case $LPAREN: 76 case $LPAREN:
53 return scanCharacter(start, '(');
54 case $RPAREN: 77 case $RPAREN:
55 return scanCharacter(start, ')');
56 case $LBRACE: 78 case $LBRACE:
57 return scanCharacter(start, '{');
58 case $RBRACE: 79 case $RBRACE:
59 return scanCharacter(start, '}');
60 case $LBRACKET: 80 case $LBRACKET:
61 return scanCharacter(start, '[');
62 case $RBRACKET: 81 case $RBRACKET:
63 return scanCharacter(start, ']');
64 case $COMMA: 82 case $COMMA:
65 return scanCharacter(start, ',');
66 case $COLON: 83 case $COLON:
67 return scanCharacter(start, ':');
68 case $SEMICOLON: 84 case $SEMICOLON:
69 return scanCharacter(start, ';'); 85 return scanCharacter(start, new String.fromCharCode(peek));
70 case $SQ: 86 case $SQ:
71 case $DQ: 87 case $DQ:
72 return scanString(); 88 return scanString();
73 case $PLUS: 89 case $PLUS:
74 return scanOperator(start, '+');
75 case $MINUS: 90 case $MINUS:
76 return scanOperator(start, '-');
77 case $STAR: 91 case $STAR:
78 return scanOperator(start, '*');
79 case $SLASH: 92 case $SLASH:
80 return scanOperator(start, '/');
81 case $PERCENT: 93 case $PERCENT:
82 return scanOperator(start, '%');
83 case $CARET: 94 case $CARET:
84 return scanOperator(start, '^');
85 case $QUESTION: 95 case $QUESTION:
86 return scanOperator(start, '?'); 96 return scanOperator(start, new String.fromCharCode(peek));
87 case $LT: 97 case $LT:
88 return scanComplexOperator(start, $EQ, '<', '<=');
89 case $GT: 98 case $GT:
90 return scanComplexOperator(start, $EQ, '>', '>=');
91 case $BANG: 99 case $BANG:
92 return scanComplexOperator(start, $EQ, '!', '!=');
93 case $EQ: 100 case $EQ:
94 return scanComplexOperator(start, $EQ, '=', '=='); 101 return scanComplexOperator(start, $EQ, new String.fromCharCode(peek), '= ');
95 case $AMPERSAND: 102 case $AMPERSAND:
96 return scanComplexOperator(start, $AMPERSAND, '&', '&&'); 103 return scanComplexOperator(start, $AMPERSAND, '&', '&');
97 case $BAR: 104 case $BAR:
98 return scanComplexOperator(start, $BAR, '|', '||'); 105 return scanComplexOperator(start, $BAR, '|', '|');
99 case $TILDE: 106 case $TILDE:
100 return scanComplexOperator(start, $SLASH, '~', '~/'); 107 return scanComplexOperator(start, $SLASH, '~', '/');
108 case $NBSP:
109 while (isWhitespace(peek)) advance();
110 return scanToken();
101 } 111 }
102 112
103 String character = new String.fromCharCode(peek); 113 String character = new String.fromCharCode(peek);
104 error('Unexpected character [$character]'); 114 error('Unexpected character [$character]');
105 } 115 }
106 116
107 Token scanCharacter(int start, String string) { 117 Token scanCharacter(int start, String string) {
108 assert(peek == string.codeUnitAt(0)); 118 assert(peek == string.codeUnitAt(0));
109 advance(); 119 advance();
110 return new Token(start, string); 120 return new Token(start, string);
111 } 121 }
112 122
113 Token scanOperator(int start, String string) { 123 Token scanOperator(int start, String string) {
114 assert(peek == string.codeUnitAt(0)); 124 assert(peek == string.codeUnitAt(0));
115 assert(OPERATORS.containsKey(string)); 125 assert(OPERATORS.contains(string));
116 advance(); 126 advance();
117 return new Token(start, string)..withOp(string); 127 return new Token(start, string)..withOp(string);
118 } 128 }
119 129
120 Token scanComplexOperator(int start, int code, String one, String two) { 130 Token scanComplexOperator(int start, int code, String one, String two) {
121 assert(peek == one.codeUnitAt(0)); 131 assert(peek == one.codeUnitAt(0));
122 advance(); 132 advance();
123 String string = one; 133 String string = one;
124 if (peek == code) { 134 if (peek == code) {
125 advance(); 135 advance();
126 string = two; 136 string += two;
127 } 137 }
128 assert(OPERATORS.containsKey(string)); 138 assert(OPERATORS.contains(string));
129 return new Token(start, string)..withOp(string); 139 return new Token(start, string)..withOp(string);
130 } 140 }
131 141
132 Token scanIdentifier() { 142 Token scanIdentifier() {
133 assert(isIdentifierStart(peek)); 143 assert(isIdentifierStart(peek));
134 int start = index; 144 int start = index;
135 int dot = -1;
136 advance(); 145 advance();
137 while (true) { 146 while (isIdentifierPart(peek)) advance();
138 if (peek == $PERIOD) { 147 String string = input.substring(start, index);
139 dot = index; 148 Token result = new Token(start, string);
140 } else if (!isIdentifierPart(peek)) { 149 // TODO(kasperl): Deal with null, undefined, true, and false in
141 break; 150 // a cleaner and faster way.
142 } 151 if (OPERATORS.contains(string)) {
143 advance(); 152 result.withOp(string);
153 } else {
154 result.withGetterSetter(string);
144 } 155 }
145 if (dot == -1) { 156 return result;
146 String string = input.substring(start, index);
147 Token result = new Token(start, string);
148 // TODO(kasperl): Deal with null, undefined, true, and false in
149 // a cleaner and faster way.
150 if (OPERATORS.containsKey(string)) {
151 result.withOp(string);
152 } else {
153 result.withGetterSetter(string);
154 }
155 return result;
156 }
157
158 int end = index;
159 while (isWhitespace(peek)) advance();
160 if (peek == $LPAREN) {
161 buffer.add(new Token(dot + 1, input.substring(dot + 1, end)));
162 buffer.add(new Token(dot, '.'));
163 end = dot;
164 }
165 String string = input.substring(start, end);
166 return new Token(start, string)..withGetterSetter(string);
167 } 157 }
168 158
169 Token scanNumber(int start) { 159 Token scanNumber(int start) {
170 assert(isDigit(peek)); 160 assert(isDigit(peek));
171 bool simple = (index == start); 161 bool simple = (index == start);
162 advance(); // Skip initial digit.
172 while (true) { 163 while (true) {
173 if (isDigit(peek)) { 164 if (isDigit(peek)) {
174 // Do nothing. 165 // Do nothing.
175 } else if (peek == $PERIOD) { 166 } else if (peek == $PERIOD) {
176 simple = false; 167 simple = false;
177 } else if (isExponentStart(peek)) { 168 } else if (isExponentStart(peek)) {
178 advance(); 169 advance();
179 if (isExponentSign(peek)) advance(); 170 if (isExponentSign(peek)) advance();
180 if (!isDigit(peek)) error('Invalid exponent', -1); 171 if (!isDigit(peek)) error('Invalid exponent', -1);
181 simple = false; 172 simple = false;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 else peek = input.codeUnitAt(index); 233 else peek = input.codeUnitAt(index);
243 } 234 }
244 235
245 void error(String message, [int offset = 0]) { 236 void error(String message, [int offset = 0]) {
246 // TODO(kasperl): Try to get rid of the offset. It is only used to match 237 // TODO(kasperl): Try to get rid of the offset. It is only used to match
247 // the error expectations in the lexer tests for numbers with exponents. 238 // the error expectations in the lexer tests for numbers with exponents.
248 int position = index + offset; 239 int position = index + offset;
249 throw "Lexer Error: $message at column $position in expression [$input]"; 240 throw "Lexer Error: $message at column $position in expression [$input]";
250 } 241 }
251 } 242 }
243
244 Set<String> OPERATORS = new Set<String>.from([
245 'undefined',
246 'null',
247 'true',
248 'false',
249 '+',
250 '-',
251 '*',
252 '/',
253 '~/',
254 '%',
255 '^',
256 '=',
257 '==',
258 '!=',
259 '<',
260 '>',
261 '<=',
262 '>=',
263 '&&',
264 '||',
265 '&',
266 '|',
267 '!',
268 '?',
269 ]);
270
OLDNEW
« no previous file with comments | « third_party/pkg/angular/lib/core/parser/eval_calls.dart ('k') | third_party/pkg/angular/lib/core/parser/parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698