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 876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 | 887 |
888 Expression parseObjectInitializer() { | 888 Expression parseObjectInitializer() { |
889 List<Property> properties = <Property>[]; | 889 List<Property> properties = <Property>[]; |
890 for (;;) { | 890 for (;;) { |
891 if (acceptCategory(RBRACE)) break; | 891 if (acceptCategory(RBRACE)) break; |
892 // Limited subset of ES6 object initializers. | 892 // Limited subset of ES6 object initializers. |
893 // | 893 // |
894 // PropertyDefinition : | 894 // PropertyDefinition : |
895 // PropertyName : AssignmentExpression | 895 // PropertyName : AssignmentExpression |
896 // MethodDefinition | 896 // MethodDefinition |
| 897 properties.add(parseMethodOrProperty()); |
897 | 898 |
898 if (acceptCategory(HASH)) { | 899 if (acceptCategory(RBRACE)) break; |
899 properties.add(parseInterpolatedMember()); | 900 expectCategory(COMMA); |
900 } else { | |
901 bool isGetter = acceptString('get'); | |
902 bool isSetter = isGetter ? false : acceptString('set'); | |
903 Expression name = parsePropertyName(); | |
904 | |
905 if (lastCategory == LPAREN) { | |
906 Fun fun = parseFun(); | |
907 properties.add( | |
908 new Method(name, fun, isGetter: isGetter, isSetter: isSetter)); | |
909 } else { | |
910 expectCategory(COLON); | |
911 Expression value = parseAssignment(); | |
912 properties.add(new Property(name, value)); | |
913 } | |
914 if (acceptCategory(RBRACE)) break; | |
915 expectCategory(COMMA); | |
916 } | |
917 } | 901 } |
918 return new ObjectInitializer(properties); | 902 return new ObjectInitializer(properties); |
919 } | 903 } |
920 | 904 |
921 Expression parseMember() { | 905 Expression parseMember() { |
922 Expression receiver = parsePrimary(); | 906 Expression receiver = parsePrimary(); |
923 while (true) { | 907 while (true) { |
924 if (acceptCategory(DOT)) { | 908 if (acceptCategory(DOT)) { |
925 receiver = getDotRhs(receiver); | 909 receiver = getDotRhs(receiver); |
926 } else if (acceptCategory(LSQUARE)) { | 910 } else if (acceptCategory(LSQUARE)) { |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1460 name = new VariableDeclaration(lastToken); | 1444 name = new VariableDeclaration(lastToken); |
1461 expectCategory(ALPHA); | 1445 expectCategory(ALPHA); |
1462 } | 1446 } |
1463 Expression heritage = null; | 1447 Expression heritage = null; |
1464 if (acceptString('extends')) { | 1448 if (acceptString('extends')) { |
1465 heritage = parseLeftHandSide(); | 1449 heritage = parseLeftHandSide(); |
1466 } | 1450 } |
1467 expectCategory(LBRACE); | 1451 expectCategory(LBRACE); |
1468 var methods = new List<Method>(); | 1452 var methods = new List<Method>(); |
1469 while (lastCategory != RBRACE) { | 1453 while (lastCategory != RBRACE) { |
1470 methods.add(parseMethod()); | 1454 methods.add(parseMethodOrProperty(onlyMethods: true)); |
1471 } | 1455 } |
1472 expectCategory(RBRACE); | 1456 expectCategory(RBRACE); |
1473 return new ClassExpression(name, heritage, methods); | 1457 return new ClassExpression(name, heritage, methods); |
1474 } | 1458 } |
1475 | 1459 |
1476 Method parseMethod() { | 1460 /** |
1477 if (acceptCategory(HASH)) return parseInterpolatedMember(); | 1461 * Parses a [Method] or a [Property]. |
| 1462 * |
| 1463 * Most of the complexity is from supporting interpolation. Several forms |
| 1464 * are supported: |
| 1465 * |
| 1466 * - getter/setter names: `get #() { ... }` |
| 1467 * - method names: `#() { ... }` |
| 1468 * - property names: `#: ...` |
| 1469 * - entire methods: `#` |
| 1470 */ |
| 1471 Property parseMethodOrProperty({bool onlyMethods: false}) { |
| 1472 bool isStatic = acceptString('static'); |
1478 | 1473 |
1479 bool isStatic = acceptString('static'); | 1474 bool isGetter = false; |
1480 bool isGetter = acceptString('get'); | 1475 bool isSetter = false; |
1481 bool isSetter = isGetter ? false : acceptString('set'); | 1476 Expression name = null; |
1482 var name = parsePropertyName(); | 1477 if (acceptCategory(HASH)) { |
1483 var fun = parseFun(); | 1478 if (lastCategory != LPAREN && (onlyMethods || lastCategory != COLON)) { |
1484 return new Method(name, fun, | 1479 // Interpolated method |
1485 isGetter: isGetter, isSetter: isSetter, isStatic: isStatic); | 1480 var member = new InterpolatedMethod(parseHash()); |
1486 } | 1481 interpolatedValues.add(member); |
| 1482 return member; |
| 1483 } |
| 1484 name = parseInterpolatedExpression(); |
| 1485 } else { |
| 1486 name = parsePropertyName(); |
| 1487 } |
1487 | 1488 |
1488 InterpolatedMethod parseInterpolatedMember() { | 1489 // Allow get or set to be followed by another property name. |
1489 var member = new InterpolatedMethod(parseHash()); | 1490 if (lastCategory == ALPHA && name is PropertyName) { |
1490 interpolatedValues.add(member); | 1491 PropertyName p = name; |
1491 return member; | 1492 isGetter = p.name == 'get'; |
| 1493 isSetter = p.name == 'set'; |
| 1494 if (isGetter || isSetter) { |
| 1495 name = parsePropertyName(); |
| 1496 } |
| 1497 } |
| 1498 |
| 1499 if (!onlyMethods && acceptCategory(COLON)) { |
| 1500 Expression value = parseAssignment(); |
| 1501 return new Property(name, value); |
| 1502 } else { |
| 1503 var fun = parseFun(); |
| 1504 return new Method(name, fun, |
| 1505 isGetter: isGetter, isSetter: isSetter, isStatic: isStatic); |
| 1506 } |
1492 } | 1507 } |
1493 | 1508 |
1494 Expression parsePropertyName() { | 1509 Expression parsePropertyName() { |
1495 String identifier = lastToken; | 1510 String identifier = lastToken; |
1496 if (acceptCategory(ALPHA)) { | 1511 if (acceptCategory(ALPHA)) { |
1497 return new PropertyName(identifier); | 1512 return new PropertyName(identifier); |
1498 } else if (acceptCategory(STRING)) { | 1513 } else if (acceptCategory(STRING)) { |
1499 return new LiteralString(identifier); | 1514 return new LiteralString(identifier); |
1500 } else if (acceptCategory(SYMBOL)) { | 1515 } else if (acceptCategory(SYMBOL)) { |
1501 // e.g. void | 1516 // e.g. void |
1502 return new LiteralString('"$identifier"'); | 1517 return new LiteralString('"$identifier"'); |
1503 } else if (acceptCategory(LSQUARE)) { | 1518 } else if (acceptCategory(LSQUARE)) { |
1504 var expr = parseAssignment(); | 1519 var expr = parseAssignment(); |
1505 expectCategory(RSQUARE); | 1520 expectCategory(RSQUARE); |
1506 return expr; | 1521 return expr; |
1507 } else if (acceptCategory(HASH)) { | 1522 } else if (acceptCategory(HASH)) { |
1508 var nameOrPosition = parseHash(); | 1523 return parseInterpolatedExpression(); |
1509 var interpolatedLiteral = new InterpolatedLiteral(nameOrPosition); | |
1510 interpolatedValues.add(interpolatedLiteral); | |
1511 return interpolatedLiteral; | |
1512 } else { | 1524 } else { |
1513 error('Expected property name'); | 1525 error('Expected property name'); |
1514 return null; | 1526 return null; |
1515 } | 1527 } |
1516 } | 1528 } |
| 1529 |
| 1530 InterpolatedExpression parseInterpolatedExpression() { |
| 1531 var interpolated = new InterpolatedExpression(parseHash()); |
| 1532 interpolatedValues.add(interpolated); |
| 1533 return interpolated; |
| 1534 } |
1517 } | 1535 } |
OLD | NEW |