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

Side by Side Diff: lib/src/js/builder.dart

Issue 1029583011: [js_ast] adds Identifier that merges VariableDeclaration/Use and Parameter (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 9 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
OLDNEW
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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 still has one semicolon: 57 still has one semicolon:
58 58
59 js.statement('if (happy) #;', ret) 59 js.statement('if (happy) #;', ret)
60 --> 60 -->
61 if (happy) 61 if (happy)
62 return 123; 62 return 123;
63 63
64 If the placeholder is not followed by a semicolon, it is part of an expression. 64 If the placeholder is not followed by a semicolon, it is part of an expression.
65 Here the paceholder is in the position of the function in a function call: 65 Here the paceholder is in the position of the function in a function call:
66 66
67 var vFoo = new VariableUse('foo'); 67 var vFoo = new Identifier('foo');
68 js.statement('if (happy) #("Happy!")', vFoo) 68 js.statement('if (happy) #("Happy!")', vFoo)
69 --> 69 -->
70 if (happy) 70 if (happy)
71 foo("Happy!"); 71 foo("Happy!");
72 72
73 Generally, a placeholder in an expression position requires an Expression AST as 73 Generally, a placeholder in an expression position requires an Expression AST as
74 an argument and a placeholder in a statement position requires a Statement AST. 74 an argument and a placeholder in a statement position requires a Statement AST.
75 An expression will be converted to a Statement if needed by creating an 75 An expression will be converted to a Statement if needed by creating an
76 ExpessionStatement. A String argument will be converted into a VariableUse and 76 ExpessionStatement. A String argument will be converted into a Identifier and
77 requires that the string is a JavaScript identifier. 77 requires that the string is a JavaScript identifier.
78 78
79 js('# + 1', vFoo) --> foo + 1 79 js('# + 1', vFoo) --> foo + 1
80 js('# + 1', 'foo') --> foo + 1 80 js('# + 1', 'foo') --> foo + 1
81 js('# + 1', 'foo.bar') --> assertion failure 81 js('# + 1', 'foo.bar') --> assertion failure
82 82
83 Some placeholder positions are _splicing contexts_. A function argument list is 83 Some placeholder positions are _splicing contexts_. A function argument list is
84 a splicing expression context. A placeholder in a splicing expression context 84 a splicing expression context. A placeholder in a splicing expression context
85 can take a single Expression (or String, converted to VariableUse) or an 85 can take a single Expression (or String, converted to Identifier) or an
86 Iterable of Expressions (and/or Strings). 86 Iterable of Expressions (and/or Strings).
87 87
88 // non-splicing argument: 88 // non-splicing argument:
89 js('#(#)', ['say', s]) --> say("hello") 89 js('#(#)', ['say', s]) --> say("hello")
90 // splicing arguments: 90 // splicing arguments:
91 js('#(#)', ['say', []]) --> say() 91 js('#(#)', ['say', []]) --> say()
92 js('#(#)', ['say', [s]]) --> say("hello") 92 js('#(#)', ['say', [s]]) --> say("hello")
93 js('#(#)', ['say', [s, n]]) --> say("hello", 123) 93 js('#(#)', ['say', [s, n]]) --> say("hello", 123)
94 94
95 A splicing context can be used to append 'lists' and add extra elements: 95 A splicing context can be used to append 'lists' and add extra elements:
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 return new LiteralNull(); 730 return new LiteralNull();
731 } else if (last == "function") { 731 } else if (last == "function") {
732 return parseFunctionExpression(); 732 return parseFunctionExpression();
733 } else if (last == "this") { 733 } else if (last == "this") {
734 return new This(); 734 return new This();
735 } else if (last == "super") { 735 } else if (last == "super") {
736 return new Super(); 736 return new Super();
737 } else if (last == "class") { 737 } else if (last == "class") {
738 return parseClass(); 738 return parseClass();
739 } else { 739 } else {
740 return new VariableUse(last); 740 return new Identifier(last);
741 } 741 }
742 } else if (acceptCategory(LPAREN)) { 742 } else if (acceptCategory(LPAREN)) {
743 return parseExpressionOrArrowFunction(); 743 return parseExpressionOrArrowFunction();
744 } else if (acceptCategory(STRING)) { 744 } else if (acceptCategory(STRING)) {
745 return new LiteralString(last); 745 return new LiteralString(last);
746 } else if (acceptCategory(NUMERIC)) { 746 } else if (acceptCategory(NUMERIC)) {
747 return new LiteralNumber(last); 747 return new LiteralNumber(last);
748 } else if (acceptCategory(LBRACE)) { 748 } else if (acceptCategory(LBRACE)) {
749 return parseObjectInitializer(); 749 return parseObjectInitializer();
750 } else if (acceptCategory(LSQUARE)) { 750 } else if (acceptCategory(LSQUARE)) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 /** 785 /**
786 * CoverParenthesizedExpressionAndArrowParameterList[Yield] : 786 * CoverParenthesizedExpressionAndArrowParameterList[Yield] :
787 * ( Expression ) 787 * ( Expression )
788 * ( ) 788 * ( )
789 * ( ... BindingIdentifier ) 789 * ( ... BindingIdentifier )
790 * ( Expression , ... BindingIdentifier ) 790 * ( Expression , ... BindingIdentifier )
791 */ 791 */
792 Expression parseExpressionOrArrowFunction() { 792 Expression parseExpressionOrArrowFunction() {
793 if (acceptCategory(RPAREN)) { 793 if (acceptCategory(RPAREN)) {
794 expectCategory(ARROW); 794 expectCategory(ARROW);
795 return parseArrowFunctionBody(<Parameter>[]); 795 return parseArrowFunctionBody(<Identifier>[]);
796 } 796 }
797 Expression expression = parseExpression(); 797 Expression expression = parseExpression();
798 expectCategory(RPAREN); 798 expectCategory(RPAREN);
799 if (acceptCategory(ARROW)) { 799 if (acceptCategory(ARROW)) {
800 var params = <Parameter>[]; 800 var params = <Identifier>[];
801 _expressionToParameterList(expression, params); 801 _expressionToParameterList(expression, params);
802 return parseArrowFunctionBody(params); 802 return parseArrowFunctionBody(params);
803 } 803 }
804 return expression; 804 return expression;
805 805
806 } 806 }
807 807
808 /** 808 /**
809 * Converts a parenthesized expression into a list of parameters, issuing an 809 * Converts a parenthesized expression into a list of parameters, issuing an
810 * error if the conversion fails. 810 * error if the conversion fails.
811 */ 811 */
812 void _expressionToParameterList(Expression node, List<Parameter> params) { 812 void _expressionToParameterList(Expression node, List<Identifier> params) {
813 if (node is VariableUse) { 813 if (node is Identifier) {
814 // TODO(jmesserly): support default/rest parameters 814 // TODO(jmesserly): support default/rest parameters
815 params.add(new Parameter(node.name)); 815 params.add(node);
816 } else if (node is Binary && node.op == ',') { 816 } else if (node is Binary && node.op == ',') {
817 // TODO(jmesserly): this will allow illegal parens, such as 817 // TODO(jmesserly): this will allow illegal parens, such as
818 // `((a, b), (c, d))`. Fixing it on the left side needs an explicit 818 // `((a, b), (c, d))`. Fixing it on the left side needs an explicit
819 // ParenthesizedExpression node, so we can distinguish 819 // ParenthesizedExpression node, so we can distinguish
820 // `((a, b), c)` from `(a, b, c)`. 820 // `((a, b), c)` from `(a, b, c)`.
821 _expressionToParameterList(node.left, params); 821 _expressionToParameterList(node.left, params);
822 _expressionToParameterList(node.right, params); 822 _expressionToParameterList(node.right, params);
823 } else if (node is InterpolatedExpression) { 823 } else if (node is InterpolatedExpression) {
824 params.add(new InterpolatedParameter(node.nameOrPosition)); 824 params.add(new InterpolatedParameter(node.nameOrPosition));
825 } else { 825 } else {
826 error("Expected arrow function parameter list"); 826 error("Expected arrow function parameter list");
827 } 827 }
828 } 828 }
829 829
830 Expression parseArrowFunctionBody(List<Parameter> params) { 830 Expression parseArrowFunctionBody(List<Identifier> params) {
831 Node body; 831 Node body;
832 if (acceptCategory(LBRACE)) { 832 if (acceptCategory(LBRACE)) {
833 body = parseBlock(); 833 body = parseBlock();
834 } else { 834 } else {
835 body = parseAssignment(); 835 body = parseAssignment();
836 } 836 }
837 return new ArrowFun(params, body); 837 return new ArrowFun(params, body);
838 } 838 }
839 839
840 Expression parseFunctionExpression() { 840 Expression parseFunctionExpression() {
841 String last = lastToken; 841 String last = lastToken;
842 if (acceptCategory(ALPHA)) { 842 if (acceptCategory(ALPHA)) {
843 String functionName = last; 843 String functionName = last;
844 return new NamedFunction(new VariableDeclaration(functionName), 844 return new NamedFunction(new Identifier(functionName),
845 parseFun()); 845 parseFun());
846 } 846 }
847 return parseFun(); 847 return parseFun();
848 } 848 }
849 849
850 Expression parseFun() { 850 Expression parseFun() {
851 List<Parameter> params = <Parameter>[]; 851 List<Identifier> params = <Identifier>[];
852 852
853 expectCategory(LPAREN); 853 expectCategory(LPAREN);
854 if (!acceptCategory(RPAREN)) { 854 if (!acceptCategory(RPAREN)) {
855 for (;;) { 855 for (;;) {
856 if (acceptCategory(HASH)) { 856 if (acceptCategory(HASH)) {
857 var nameOrPosition = parseHash(); 857 var nameOrPosition = parseHash();
858 InterpolatedParameter parameter = 858 InterpolatedParameter parameter =
859 new InterpolatedParameter(nameOrPosition); 859 new InterpolatedParameter(nameOrPosition);
860 interpolatedValues.add(parameter); 860 interpolatedValues.add(parameter);
861 params.add(parameter); 861 params.add(parameter);
862 } else { 862 } else {
863 String argumentName = lastToken; 863 String argumentName = lastToken;
864 expectCategory(ALPHA); 864 expectCategory(ALPHA);
865 params.add(new Parameter(argumentName)); 865 params.add(new Identifier(argumentName));
866 } 866 }
867 if (acceptCategory(COMMA)) continue; 867 if (acceptCategory(COMMA)) continue;
868 expectCategory(RPAREN); 868 expectCategory(RPAREN);
869 break; 869 break;
870 } 870 }
871 } 871 }
872 AsyncModifier asyncModifier; 872 AsyncModifier asyncModifier;
873 if (acceptString('async')) { 873 if (acceptString('async')) {
874 if (acceptString('*')) { 874 if (acceptString('*')) {
875 asyncModifier = const AsyncModifier.asyncStar(); 875 asyncModifier = const AsyncModifier.asyncStar();
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 expression = new Binary(',', expression, right); 1072 expression = new Binary(',', expression, right);
1073 } 1073 }
1074 return expression; 1074 return expression;
1075 } 1075 }
1076 1076
1077 /** Parse a variable declaration list, with `var` or `let` [keyword] */ 1077 /** Parse a variable declaration list, with `var` or `let` [keyword] */
1078 VariableDeclarationList parseVariableDeclarationList(String keyword) { 1078 VariableDeclarationList parseVariableDeclarationList(String keyword) {
1079 // Supports one form for interpolated variable declaration: 1079 // Supports one form for interpolated variable declaration:
1080 // let # = ... 1080 // let # = ...
1081 if (acceptCategory(HASH)) { 1081 if (acceptCategory(HASH)) {
1082 var name = new InterpolatedVariableDeclaration(parseHash()); 1082 var name = new InterpolatedIdentifier(parseHash());
1083 interpolatedValues.add(name); 1083 interpolatedValues.add(name);
1084 1084
1085 Expression initializer = acceptString("=") ? parseAssignment() : null; 1085 Expression initializer = acceptString("=") ? parseAssignment() : null;
1086 return new VariableDeclarationList(keyword, 1086 return new VariableDeclarationList(keyword,
1087 [new VariableInitialization(name, initializer)]); 1087 [new VariableInitialization(name, initializer)]);
1088 } 1088 }
1089 1089
1090 String firstVariable = lastToken; 1090 String firstVariable = lastToken;
1091 expectCategory(ALPHA); 1091 expectCategory(ALPHA);
1092 return finishVariableDeclarationList(keyword, firstVariable); 1092 return finishVariableDeclarationList(keyword, firstVariable);
1093 } 1093 }
1094 1094
1095 VariableDeclarationList finishVariableDeclarationList( 1095 VariableDeclarationList finishVariableDeclarationList(
1096 String keyword, String firstVariable) { 1096 String keyword, String firstVariable) {
1097 var initialization = []; 1097 var initialization = [];
1098 1098
1099 void declare(String variable) { 1099 void declare(String variable) {
1100 Expression initializer = null; 1100 Expression initializer = null;
1101 if (acceptString("=")) { 1101 if (acceptString("=")) {
1102 initializer = parseAssignment(); 1102 initializer = parseAssignment();
1103 } 1103 }
1104 var declaration = new VariableDeclaration(variable); 1104 var declaration = new Identifier(variable);
1105 initialization.add(new VariableInitialization(declaration, initializer)); 1105 initialization.add(new VariableInitialization(declaration, initializer));
1106 } 1106 }
1107 1107
1108 declare(firstVariable); 1108 declare(firstVariable);
1109 while (acceptCategory(COMMA)) { 1109 while (acceptCategory(COMMA)) {
1110 String variable = lastToken; 1110 String variable = lastToken;
1111 expectCategory(ALPHA); 1111 expectCategory(ALPHA);
1112 declare(variable); 1112 declare(variable);
1113 } 1113 }
1114 return new VariableDeclarationList(keyword, initialization); 1114 return new VariableDeclarationList(keyword, initialization);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 if (lastToken == 'with') { 1207 if (lastToken == 'with') {
1208 error('Not implemented in mini parser'); 1208 error('Not implemented in mini parser');
1209 } 1209 }
1210 1210
1211 } 1211 }
1212 1212
1213 bool checkForInterpolatedStatement = lastCategory == HASH; 1213 bool checkForInterpolatedStatement = lastCategory == HASH;
1214 1214
1215 Expression expression = parseExpression(); 1215 Expression expression = parseExpression();
1216 1216
1217 if (expression is VariableUse && acceptCategory(COLON)) { 1217 if (expression is Identifier && acceptCategory(COLON)) {
1218 return new LabeledStatement(expression.name, parseStatement()); 1218 return new LabeledStatement(expression.name, parseStatement());
1219 } 1219 }
1220 1220
1221 expectSemicolon(); 1221 expectSemicolon();
1222 1222
1223 if (checkForInterpolatedStatement) { 1223 if (checkForInterpolatedStatement) {
1224 // 'Promote' the interpolated expression `#;` to an interpolated 1224 // 'Promote' the interpolated expression `#;` to an interpolated
1225 // statement. 1225 // statement.
1226 if (expression is InterpolatedExpression) { 1226 if (expression is InterpolatedExpression) {
1227 assert(identical(interpolatedValues.last, expression)); 1227 assert(identical(interpolatedValues.last, expression));
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1340 1340
1341 Expression init = parseExpression(); 1341 Expression init = parseExpression();
1342 expectCategory(SEMICOLON); 1342 expectCategory(SEMICOLON);
1343 return finishFor(init); 1343 return finishFor(init);
1344 } 1344 }
1345 1345
1346 static VariableDeclarationList _createVariableDeclarationList( 1346 static VariableDeclarationList _createVariableDeclarationList(
1347 String keyword, String identifier) { 1347 String keyword, String identifier) {
1348 return new VariableDeclarationList(keyword, [ 1348 return new VariableDeclarationList(keyword, [
1349 new VariableInitialization( 1349 new VariableInitialization(
1350 new VariableDeclaration(identifier), null)]); 1350 new Identifier(identifier), null)]);
1351 } 1351 }
1352 1352
1353 Statement parseFunctionDeclaration() { 1353 Statement parseFunctionDeclaration() {
1354 String name = lastToken; 1354 String name = lastToken;
1355 expectCategory(ALPHA); 1355 expectCategory(ALPHA);
1356 Expression fun = parseFun(); 1356 Expression fun = parseFun();
1357 return new FunctionDeclaration(new VariableDeclaration(name), fun); 1357 return new FunctionDeclaration(new Identifier(name), fun);
1358 } 1358 }
1359 1359
1360 Statement parseTry() { 1360 Statement parseTry() {
1361 expectCategory(LBRACE); 1361 expectCategory(LBRACE);
1362 Block body = parseBlock(); 1362 Block body = parseBlock();
1363 Catch catchPart = null; 1363 Catch catchPart = null;
1364 if (acceptString('catch')) catchPart = parseCatch(); 1364 if (acceptString('catch')) catchPart = parseCatch();
1365 Block finallyPart = null; 1365 Block finallyPart = null;
1366 if (acceptString('finally')) { 1366 if (acceptString('finally')) {
1367 expectCategory(LBRACE); 1367 expectCategory(LBRACE);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1426 return new Switch(key, clauses); 1426 return new Switch(key, clauses);
1427 } 1427 }
1428 1428
1429 Catch parseCatch() { 1429 Catch parseCatch() {
1430 expectCategory(LPAREN); 1430 expectCategory(LPAREN);
1431 String identifier = lastToken; 1431 String identifier = lastToken;
1432 expectCategory(ALPHA); 1432 expectCategory(ALPHA);
1433 expectCategory(RPAREN); 1433 expectCategory(RPAREN);
1434 expectCategory(LBRACE); 1434 expectCategory(LBRACE);
1435 Block body = parseBlock(); 1435 Block body = parseBlock();
1436 return new Catch(new VariableDeclaration(identifier), body); 1436 return new Catch(new Identifier(identifier), body);
1437 } 1437 }
1438 1438
1439 ClassExpression parseClass() { 1439 ClassExpression parseClass() {
1440 VariableDeclaration name; 1440 Identifier name;
1441 if (acceptCategory(HASH)) { 1441 if (acceptCategory(HASH)) {
1442 var interpolatedName = new InterpolatedVariableDeclaration(parseHash()); 1442 var interpolatedName = new InterpolatedIdentifier(parseHash());
1443 interpolatedValues.add(interpolatedName); 1443 interpolatedValues.add(interpolatedName);
1444 name = interpolatedName; 1444 name = interpolatedName;
1445 } else { 1445 } else {
1446 name = new VariableDeclaration(lastToken); 1446 name = new Identifier(lastToken);
1447 expectCategory(ALPHA); 1447 expectCategory(ALPHA);
1448 } 1448 }
1449 Expression heritage = null; 1449 Expression heritage = null;
1450 if (acceptString('extends')) { 1450 if (acceptString('extends')) {
1451 heritage = parseLeftHandSide(); 1451 heritage = parseLeftHandSide();
1452 } 1452 }
1453 expectCategory(LBRACE); 1453 expectCategory(LBRACE);
1454 var methods = new List<Method>(); 1454 var methods = new List<Method>();
1455 while (lastCategory != RBRACE) { 1455 while (lastCategory != RBRACE) {
1456 methods.add(parseMethodOrProperty(onlyMethods: true)); 1456 methods.add(parseMethodOrProperty(onlyMethods: true));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1522 expectCategory(RSQUARE); 1522 expectCategory(RSQUARE);
1523 return expr; 1523 return expr;
1524 } else if (acceptCategory(HASH)) { 1524 } else if (acceptCategory(HASH)) {
1525 return parseInterpolatedExpression(); 1525 return parseInterpolatedExpression();
1526 } else { 1526 } else {
1527 error('Expected property name'); 1527 error('Expected property name');
1528 return null; 1528 return null;
1529 } 1529 }
1530 } 1530 }
1531 } 1531 }
OLDNEW
« no previous file with comments | « lib/src/codegen/js_codegen.dart ('k') | lib/src/js/nodes.dart » ('j') | lib/src/js/printer.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698