OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 // Utilities for building JS ASTs at runtime. Contains a builder class | 5 // Utilities for building JS ASTs at runtime. Contains a builder class |
6 // and a parser that parses part of the language. | 6 // and a parser that parses part of the language. |
7 | 7 |
8 part of js_ast; | 8 part of js_ast; |
9 | 9 |
10 | 10 |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
322 } | 322 } |
323 | 323 |
324 /// Creates a literal js string from [value]. | 324 /// Creates a literal js string from [value]. |
325 /// | 325 /// |
326 /// Note that this function only puts quotes around [value]. It does not do | 326 /// Note that this function only puts quotes around [value]. It does not do |
327 /// any escaping, so use only when you can guarantee that [value] does not | 327 /// any escaping, so use only when you can guarantee that [value] does not |
328 /// contain newlines or backslashes. For escaping the string use | 328 /// contain newlines or backslashes. For escaping the string use |
329 /// [escapedString]. | 329 /// [escapedString]. |
330 LiteralString string(String value) => new LiteralString('"$value"'); | 330 LiteralString string(String value) => new LiteralString('"$value"'); |
331 | 331 |
332 /// Creates an instance of [LiteralString] from [value]. | |
333 /// | |
334 /// Does not add quotes or do any escaping. | |
335 LiteralString stringPart(String value) => new LiteralString(value); | |
336 | |
337 StringConcatenation concatenateStrings(Iterable<Literal> parts, | |
338 {addQuotes: false}) { | |
339 List<Literal> _parts; | |
340 if (addQuotes) { | |
341 Literal quote = stringPart('"'); | |
342 _parts = <Literal>[quote] | |
343 ..addAll(parts) | |
344 ..add(quote); | |
345 } else { | |
346 _parts = new List.from(parts, growable: false); | |
347 } | |
348 return new StringConcatenation(_parts); | |
349 } | |
350 | |
351 Iterable<Literal> joinLiterals(Iterable<Literal> list, Literal separator) { | |
352 return new _InterleaveIterable(list, separator); | |
353 } | |
354 | |
332 LiteralNumber number(num value) => new LiteralNumber('$value'); | 355 LiteralNumber number(num value) => new LiteralNumber('$value'); |
333 | 356 |
334 LiteralBool boolean(bool value) => new LiteralBool(value); | 357 LiteralBool boolean(bool value) => new LiteralBool(value); |
335 | 358 |
336 ArrayInitializer numArray(Iterable<int> list) => | 359 ArrayInitializer numArray(Iterable<int> list) => |
337 new ArrayInitializer(list.map(number).toList()); | 360 new ArrayInitializer(list.map(number).toList()); |
338 | 361 |
339 ArrayInitializer stringArray(Iterable<String> list) => | 362 ArrayInitializer stringArray(Iterable<String> list) => |
340 new ArrayInitializer(list.map(string).toList()); | 363 new ArrayInitializer(list.map(string).toList()); |
341 | 364 |
342 Comment comment(String text) => new Comment(text); | 365 Comment comment(String text) => new Comment(text); |
343 | 366 |
344 Call propertyCall(Expression receiver, | 367 Call propertyCall(Expression receiver, |
345 String fieldName, | 368 String fieldName, |
346 List<Expression> arguments) { | 369 List<Expression> arguments) { |
347 return new Call(new PropertyAccess.field(receiver, fieldName), arguments); | 370 return new Call(new PropertyAccess.field(receiver, fieldName), arguments); |
348 } | 371 } |
349 } | 372 } |
350 | 373 |
351 LiteralString string(String value) => js.string(value); | 374 LiteralString string(String value) => js.string(value); |
375 LiteralString stringPart(String value) => js.stringPart(value); | |
376 Iterable<Literal> joinLiterals(Iterable<Literal> list, Literal separator) { | |
377 return js.joinLiterals(list, separator); | |
378 } | |
352 LiteralNumber number(num value) => js.number(value); | 379 LiteralNumber number(num value) => js.number(value); |
353 ArrayInitializer numArray(Iterable<int> list) => js.numArray(list); | 380 ArrayInitializer numArray(Iterable<int> list) => js.numArray(list); |
354 ArrayInitializer stringArray(Iterable<String> list) => js.stringArray(list); | 381 ArrayInitializer stringArray(Iterable<String> list) => js.stringArray(list); |
355 Call propertyCall(Expression receiver, | 382 Call propertyCall(Expression receiver, |
356 String fieldName, | 383 String fieldName, |
357 List<Expression> arguments) { | 384 List<Expression> arguments) { |
358 return js.propertyCall(receiver, fieldName, arguments); | 385 return js.propertyCall(receiver, fieldName, arguments); |
359 } | 386 } |
360 | 387 |
361 class MiniJsParserError { | 388 class MiniJsParserError { |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
765 new InterpolatedExpression(nameOrPosition); | 792 new InterpolatedExpression(nameOrPosition); |
766 interpolatedValues.add(expression); | 793 interpolatedValues.add(expression); |
767 return expression; | 794 return expression; |
768 } else { | 795 } else { |
769 error("Expected primary expression"); | 796 error("Expected primary expression"); |
770 return null; | 797 return null; |
771 } | 798 } |
772 } | 799 } |
773 | 800 |
774 Expression parseFunctionExpression() { | 801 Expression parseFunctionExpression() { |
775 String last = lastToken; | |
776 if (lastCategory == ALPHA || lastCategory == HASH) { | 802 if (lastCategory == ALPHA || lastCategory == HASH) { |
777 Declaration name = parseVariableDeclaration(); | 803 Declaration name = parseVariableDeclaration(); |
778 return new NamedFunction(name, parseFun()); | 804 return new NamedFunction(name, parseFun()); |
779 } | 805 } |
780 return parseFun(); | 806 return parseFun(); |
781 } | 807 } |
782 | 808 |
783 Expression parseFun() { | 809 Expression parseFun() { |
784 List<Parameter> params = <Parameter>[]; | 810 List<Parameter> params = <Parameter>[]; |
785 | 811 |
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1265 | 1291 |
1266 Statement parseFunctionDeclaration() { | 1292 Statement parseFunctionDeclaration() { |
1267 Declaration name = parseVariableDeclaration(); | 1293 Declaration name = parseVariableDeclaration(); |
1268 Expression fun = parseFun(); | 1294 Expression fun = parseFun(); |
1269 return new FunctionDeclaration(name, fun); | 1295 return new FunctionDeclaration(name, fun); |
1270 } | 1296 } |
1271 | 1297 |
1272 Statement parseTry() { | 1298 Statement parseTry() { |
1273 expectCategory(LBRACE); | 1299 expectCategory(LBRACE); |
1274 Block body = parseBlock(); | 1300 Block body = parseBlock(); |
1275 String token = lastToken; | |
1276 Catch catchPart = null; | 1301 Catch catchPart = null; |
1277 if (acceptString('catch')) catchPart = parseCatch(); | 1302 if (acceptString('catch')) catchPart = parseCatch(); |
1278 Block finallyPart = null; | 1303 Block finallyPart = null; |
1279 if (acceptString('finally')) { | 1304 if (acceptString('finally')) { |
1280 expectCategory(LBRACE); | 1305 expectCategory(LBRACE); |
1281 finallyPart = parseBlock(); | 1306 finallyPart = parseBlock(); |
1282 } else { | 1307 } else { |
1283 if (catchPart == null) error("expected 'finally'"); | 1308 if (catchPart == null) error("expected 'finally'"); |
1284 } | 1309 } |
1285 return new Try(body, catchPart, finallyPart); | 1310 return new Try(body, catchPart, finallyPart); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1341 | 1366 |
1342 Catch parseCatch() { | 1367 Catch parseCatch() { |
1343 expectCategory(LPAREN); | 1368 expectCategory(LPAREN); |
1344 Declaration errorName = parseVariableDeclaration(); | 1369 Declaration errorName = parseVariableDeclaration(); |
1345 expectCategory(RPAREN); | 1370 expectCategory(RPAREN); |
1346 expectCategory(LBRACE); | 1371 expectCategory(LBRACE); |
1347 Block body = parseBlock(); | 1372 Block body = parseBlock(); |
1348 return new Catch(errorName, body); | 1373 return new Catch(errorName, body); |
1349 } | 1374 } |
1350 } | 1375 } |
1376 | |
1377 class _InterleaveIterator implements Iterator<Node> { | |
1378 Iterator<Node> source; | |
1379 Node separator; | |
1380 bool isNextSeparator = false; | |
1381 bool isInitialized = false; | |
1382 | |
1383 _InterleaveIterator(this.source, this.separator); | |
1384 | |
1385 bool moveNext() { | |
1386 if (!isInitialized) { | |
1387 isInitialized = true; | |
1388 return source.moveNext(); | |
1389 } else if (isNextSeparator) { | |
1390 isNextSeparator = false; | |
1391 return true; | |
1392 } else { | |
1393 return isNextSeparator = source.moveNext(); | |
1394 } | |
1395 } | |
1396 | |
1397 Node get current { | |
1398 if (isNextSeparator) return separator._clone(); | |
sra1
2015/06/10 19:30:00
Why clone?
_clone() is really just an implementati
herhut
2015/06/11 08:03:55
Done.
| |
1399 return source.current; | |
1400 } | |
1401 } | |
1402 | |
1403 class _InterleaveIterable extends IterableBase { | |
1404 Iterable<Node> source; | |
1405 Node separator; | |
1406 | |
1407 _InterleaveIterable(this.source, this.separator); | |
1408 | |
1409 Iterator<Node> get iterator { | |
1410 return new _InterleaveIterator(source.iterator, separator); | |
1411 } | |
1412 } | |
OLD | NEW |