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

Side by Side Diff: pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library dart_tree_printer; 5 library dart_tree_printer;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../constants/values.dart' as values; 8 import '../constants/values.dart' as values;
9 import '../dart_types.dart' as types; 9 import '../dart_types.dart' as types;
10 import '../elements/elements.dart' as elements; 10 import '../elements/elements.dart' as elements;
11 import '../resolution/tree_elements.dart' show 11 import '../resolution/tree_elements.dart' show TreeElementMapping;
12 TreeElementMapping;
13 import '../tokens/token.dart'; 12 import '../tokens/token.dart';
14 import '../tokens/token_constants.dart'; 13 import '../tokens/token_constants.dart';
15 import '../tokens/precedence.dart'; 14 import '../tokens/precedence.dart';
16 import '../tokens/precedence_constants.dart'; 15 import '../tokens/precedence_constants.dart';
17 import '../tree/tree.dart' as tree; 16 import '../tree/tree.dart' as tree;
18 import '../util/util.dart'; 17 import '../util/util.dart';
19 import 'backend_ast_nodes.dart'; 18 import 'backend_ast_nodes.dart';
20 import 'backend_ast_emitter.dart' show TypeGenerator; 19 import 'backend_ast_emitter.dart' show TypeGenerator;
21 20
22 /// Translates the backend AST to Dart frontend AST. 21 /// Translates the backend AST to Dart frontend AST.
23 tree.Node emit(TreeElementMapping treeElements, 22 tree.Node emit(TreeElementMapping treeElements, RootNode root) {
24 RootNode root) {
25 return new TreePrinter(treeElements).makeDefinition(root); 23 return new TreePrinter(treeElements).makeDefinition(root);
26 } 24 }
27 25
28 /// If true, the unparser will insert a coment in front of every function 26 /// If true, the unparser will insert a coment in front of every function
29 /// it emits. This helps indicate which functions were translated by the new 27 /// it emits. This helps indicate which functions were translated by the new
30 /// backend. 28 /// backend.
31 bool INSERT_NEW_BACKEND_COMMENT = 29 bool INSERT_NEW_BACKEND_COMMENT =
32 const bool.fromEnvironment("INSERT_NEW_BACKEND_COMMENT"); 30 const bool.fromEnvironment("INSERT_NEW_BACKEND_COMMENT");
33 31
34 /// Converts backend ASTs to frontend ASTs. 32 /// Converts backend ASTs to frontend ASTs.
(...skipping 10 matching lines...) Expand all
45 } else { 43 } else {
46 definition = new tree.SendSet( 44 definition = new tree.SendSet(
47 null, 45 null,
48 makeIdentifier(node.element.name), 46 makeIdentifier(node.element.name),
49 new tree.Operator(assignmentToken("=")), 47 new tree.Operator(assignmentToken("=")),
50 singleton(makeExpression(node.initializer))); 48 singleton(makeExpression(node.initializer)));
51 } 49 }
52 setElement(definition, node.element, node); 50 setElement(definition, node.element, node);
53 return new tree.VariableDefinitions( 51 return new tree.VariableDefinitions(
54 null, // TODO(sigurdm): Type 52 null, // TODO(sigurdm): Type
55 makeVarModifiers(useVar: true, 53 makeVarModifiers(
56 isFinal: node.element.isFinal, 54 useVar: true,
57 isStatic: node.element.isStatic, 55 isFinal: node.element.isFinal,
58 isConst: node.element.isConst), 56 isStatic: node.element.isStatic,
57 isConst: node.element.isConst),
59 makeList(null, [definition], close: semicolon)); 58 makeList(null, [definition], close: semicolon));
60 } else if (node is FunctionExpression) { 59 } else if (node is FunctionExpression) {
61 return makeExpression(node); 60 return makeExpression(node);
62 } else { 61 } else {
63 assert(false); 62 assert(false);
64 return null; 63 return null;
65 } 64 }
66 } 65 }
67 66
68 void setElement(tree.Node node, elements.Element element, source) { 67 void setElement(tree.Node node, elements.Element element, source) {
(...skipping 14 matching lines...) Expand all
83 } 82 }
84 } 83 }
85 84
86 // Group tokens: () [] {} <> 85 // Group tokens: () [] {} <>
87 static BeginGroupToken makeGroup(PrecedenceInfo open, PrecedenceInfo close) { 86 static BeginGroupToken makeGroup(PrecedenceInfo open, PrecedenceInfo close) {
88 BeginGroupToken openTok = new BeginGroupToken(open, -1); 87 BeginGroupToken openTok = new BeginGroupToken(open, -1);
89 openTok.endGroup = new SymbolToken(close, -1); 88 openTok.endGroup = new SymbolToken(close, -1);
90 return openTok; 89 return openTok;
91 } 90 }
92 91
93 final BeginGroupToken openParen = makeGroup(OPEN_PAREN_INFO, 92 final BeginGroupToken openParen =
94 CLOSE_PAREN_INFO); 93 makeGroup(OPEN_PAREN_INFO, CLOSE_PAREN_INFO);
95 final BeginGroupToken openBrace = makeGroup(OPEN_CURLY_BRACKET_INFO, 94 final BeginGroupToken openBrace =
96 CLOSE_CURLY_BRACKET_INFO); 95 makeGroup(OPEN_CURLY_BRACKET_INFO, CLOSE_CURLY_BRACKET_INFO);
97 final BeginGroupToken openBracket = makeGroup(OPEN_SQUARE_BRACKET_INFO, 96 final BeginGroupToken openBracket =
98 CLOSE_SQUARE_BRACKET_INFO); 97 makeGroup(OPEN_SQUARE_BRACKET_INFO, CLOSE_SQUARE_BRACKET_INFO);
99 final BeginGroupToken lt = makeGroup(LT_INFO, GT_INFO); 98 final BeginGroupToken lt = makeGroup(LT_INFO, GT_INFO);
100 99
101 Token get closeParen => openParen.endGroup; 100 Token get closeParen => openParen.endGroup;
102 Token get closeBrace => openBrace.endGroup; 101 Token get closeBrace => openBrace.endGroup;
103 Token get closeBracket => openBracket.endGroup; 102 Token get closeBracket => openBracket.endGroup;
104 Token get gt => lt.endGroup; 103 Token get gt => lt.endGroup;
105 104
106 // Symbol tokens 105 // Symbol tokens
107 final Token semicolon = new SymbolToken(SEMICOLON_INFO, -1); 106 final Token semicolon = new SymbolToken(SEMICOLON_INFO, -1);
108 final Token indexToken = new SymbolToken(INDEX_INFO, -1); // "[]" 107 final Token indexToken = new SymbolToken(INDEX_INFO, -1); // "[]"
109 final Token question = new SymbolToken(QUESTION_INFO, -1); 108 final Token question = new SymbolToken(QUESTION_INFO, -1);
110 final Token colon = new SymbolToken(COLON_INFO, -1); 109 final Token colon = new SymbolToken(COLON_INFO, -1);
111 final Token hash = new SymbolToken(HASH_INFO, -1); 110 final Token hash = new SymbolToken(HASH_INFO, -1);
112 final Token bang = new SymbolToken(BANG_INFO, -1); 111 final Token bang = new SymbolToken(BANG_INFO, -1);
113 final Token eq = new SymbolToken(EQ_INFO, -1); 112 final Token eq = new SymbolToken(EQ_INFO, -1);
114 113
115 // Keyword tokens 114 // Keyword tokens
116 static Token makeIdToken(String text) { 115 static Token makeIdToken(String text) {
117 return new StringToken.fromString(IDENTIFIER_INFO, text, -1); 116 return new StringToken.fromString(IDENTIFIER_INFO, text, -1);
118 } 117 }
118
119 final Token newToken = makeIdToken('new'); 119 final Token newToken = makeIdToken('new');
120 final Token constToken = makeIdToken('const'); 120 final Token constToken = makeIdToken('const');
121 final Token throwToken = makeIdToken('throw'); 121 final Token throwToken = makeIdToken('throw');
122 final Token rethrowToken = makeIdToken('rethrow'); 122 final Token rethrowToken = makeIdToken('rethrow');
123 final Token breakToken = makeIdToken('break'); 123 final Token breakToken = makeIdToken('break');
124 final Token continueToken = makeIdToken('continue'); 124 final Token continueToken = makeIdToken('continue');
125 final Token doToken = makeIdToken('do'); 125 final Token doToken = makeIdToken('do');
126 final Token whileToken = makeIdToken('while'); 126 final Token whileToken = makeIdToken('while');
127 final Token ifToken = makeIdToken('if'); 127 final Token ifToken = makeIdToken('if');
128 final Token elseToken = makeIdToken('else'); 128 final Token elseToken = makeIdToken('else');
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 LinkBuilder builder = new LinkBuilder(); 161 LinkBuilder builder = new LinkBuilder();
162 for (tree.Node node in nodes) { 162 for (tree.Node node in nodes) {
163 builder.addLast(node); 163 builder.addLast(node);
164 } 164 }
165 return builder.toLink(); 165 return builder.toLink();
166 } 166 }
167 167
168 tree.NodeList blankList() { 168 tree.NodeList blankList() {
169 return new tree.NodeList(null, makeLink([]), null, ''); 169 return new tree.NodeList(null, makeLink([]), null, '');
170 } 170 }
171
171 tree.NodeList singleton(tree.Node node) { 172 tree.NodeList singleton(tree.Node node) {
172 return new tree.NodeList(null, makeLink([node]), null, ''); 173 return new tree.NodeList(null, makeLink([node]), null, '');
173 } 174 }
174 tree.NodeList makeList(String delimiter, 175
175 Iterable<tree.Node> nodes, 176 tree.NodeList makeList(String delimiter, Iterable<tree.Node> nodes,
176 { Token open, 177 {Token open, Token close}) {
177 Token close }) {
178 return new tree.NodeList(open, makeLink(nodes), close, delimiter); 178 return new tree.NodeList(open, makeLink(nodes), close, delimiter);
179 } 179 }
180
180 tree.NodeList parenList(String delimiter, Iterable<tree.Node> nodes) { 181 tree.NodeList parenList(String delimiter, Iterable<tree.Node> nodes) {
181 return makeList(delimiter, nodes, open: openParen, close: closeParen); 182 return makeList(delimiter, nodes, open: openParen, close: closeParen);
182 } 183 }
184
183 tree.NodeList bracketList(String delimiter, Iterable<tree.Node> nodes) { 185 tree.NodeList bracketList(String delimiter, Iterable<tree.Node> nodes) {
184 return makeList(delimiter, nodes, open: openBracket, close: closeBracket); 186 return makeList(delimiter, nodes, open: openBracket, close: closeBracket);
185 } 187 }
188
186 tree.NodeList braceList(String delimiter, Iterable<tree.Node> nodes) { 189 tree.NodeList braceList(String delimiter, Iterable<tree.Node> nodes) {
187 return makeList(delimiter, nodes, open: openBrace, close: closeBrace); 190 return makeList(delimiter, nodes, open: openBrace, close: closeBrace);
188 } 191 }
192
189 tree.NodeList argList(Iterable<tree.Node> nodes) { 193 tree.NodeList argList(Iterable<tree.Node> nodes) {
190 return parenList(',', nodes); 194 return parenList(',', nodes);
191 } 195 }
196
192 tree.NodeList typeArgList(Iterable<tree.Node> nodes) { 197 tree.NodeList typeArgList(Iterable<tree.Node> nodes) {
193 return makeList(',', nodes, open: lt, close: gt); 198 return makeList(',', nodes, open: lt, close: gt);
194 } 199 }
195 200
196 /// Converts a qualified name into nested Sends. 201 /// Converts a qualified name into nested Sends.
197 tree.Node makeName(String name) { 202 tree.Node makeName(String name) {
198 if (name == null) { 203 if (name == null) {
199 return null; 204 return null;
200 } 205 }
201 List<String> names = name.split('.').toList(growable:false); 206 List<String> names = name.split('.').toList(growable: false);
202 tree.Node node = makeIdentifier(names[0]); 207 tree.Node node = makeIdentifier(names[0]);
203 for (int i = 1; i < names.length; i++) { 208 for (int i = 1; i < names.length; i++) {
204 node = new tree.Send(node, makeIdentifier(names[i])); 209 node = new tree.Send(node, makeIdentifier(names[i]));
205 } 210 }
206 return node; 211 return node;
207 } 212 }
208 213
209 static Token assignmentToken(String operatorName) { 214 static Token assignmentToken(String operatorName) {
210 switch (operatorName) { 215 switch (operatorName) {
211 case '=': return new SymbolToken(EQ_INFO, -1); 216 case '=':
212 case '+=': return new SymbolToken(PLUS_EQ_INFO, -1); 217 return new SymbolToken(EQ_INFO, -1);
213 case '-=': return new SymbolToken(MINUS_EQ_INFO, -1); 218 case '+=':
214 case '*=': return new SymbolToken(STAR_EQ_INFO, -1); 219 return new SymbolToken(PLUS_EQ_INFO, -1);
215 case '/=': return new SymbolToken(SLASH_EQ_INFO, -1); 220 case '-=':
216 case '~/=': return new SymbolToken(TILDE_SLASH_EQ_INFO, -1); 221 return new SymbolToken(MINUS_EQ_INFO, -1);
217 case '%=': return new SymbolToken(PERCENT_EQ_INFO, -1); 222 case '*=':
218 case '&=': return new SymbolToken(AMPERSAND_EQ_INFO, -1); 223 return new SymbolToken(STAR_EQ_INFO, -1);
219 case '^=': return new SymbolToken(CARET_EQ_INFO, -1); 224 case '/=':
220 case '|=': return new SymbolToken(BAR_EQ_INFO, -1); 225 return new SymbolToken(SLASH_EQ_INFO, -1);
221 case '>>=': return new SymbolToken(GT_GT_EQ_INFO, -1); 226 case '~/=':
222 case '<<=': return new SymbolToken(LT_LT_EQ_INFO, -1); 227 return new SymbolToken(TILDE_SLASH_EQ_INFO, -1);
228 case '%=':
229 return new SymbolToken(PERCENT_EQ_INFO, -1);
230 case '&=':
231 return new SymbolToken(AMPERSAND_EQ_INFO, -1);
232 case '^=':
233 return new SymbolToken(CARET_EQ_INFO, -1);
234 case '|=':
235 return new SymbolToken(BAR_EQ_INFO, -1);
236 case '>>=':
237 return new SymbolToken(GT_GT_EQ_INFO, -1);
238 case '<<=':
239 return new SymbolToken(LT_LT_EQ_INFO, -1);
223 default: 240 default:
224 throw "Unrecognized assignment operator: $operatorName"; 241 throw "Unrecognized assignment operator: $operatorName";
225 } 242 }
226 } 243 }
227 244
228 static Token binopToken(String operatorName) { 245 static Token binopToken(String operatorName) {
229 switch (operatorName) { 246 switch (operatorName) {
230 case '+': return new SymbolToken(PLUS_INFO, -1); 247 case '+':
231 case '-': return new SymbolToken(MINUS_INFO, -1); 248 return new SymbolToken(PLUS_INFO, -1);
232 case '*': return new SymbolToken(STAR_INFO, -1); 249 case '-':
233 case '/': return new SymbolToken(SLASH_INFO, -1); 250 return new SymbolToken(MINUS_INFO, -1);
234 case '~/': return new SymbolToken(TILDE_SLASH_INFO, -1); 251 case '*':
235 case '%': return new SymbolToken(PERCENT_INFO, -1); 252 return new SymbolToken(STAR_INFO, -1);
236 case '&': return new SymbolToken(AMPERSAND_INFO, -1); 253 case '/':
237 case '^': return new SymbolToken(CARET_INFO, -1); 254 return new SymbolToken(SLASH_INFO, -1);
238 case '|': return new SymbolToken(BAR_INFO, -1); 255 case '~/':
239 case '>>': return new SymbolToken(GT_GT_INFO, -1); 256 return new SymbolToken(TILDE_SLASH_INFO, -1);
240 case '<<': return new SymbolToken(LT_LT_INFO, -1); 257 case '%':
241 case '==': return new SymbolToken(EQ_EQ_INFO, -1); 258 return new SymbolToken(PERCENT_INFO, -1);
242 case '!=': return new SymbolToken(BANG_EQ_INFO, -1); 259 case '&':
243 case '>': return new SymbolToken(GT_INFO, -1); 260 return new SymbolToken(AMPERSAND_INFO, -1);
244 case '>=': return new SymbolToken(GT_EQ_INFO, -1); 261 case '^':
245 case '<': return new SymbolToken(LT_INFO, -1); 262 return new SymbolToken(CARET_INFO, -1);
246 case '<=': return new SymbolToken(LT_EQ_INFO, -1); 263 case '|':
247 case '&&': return new SymbolToken(AMPERSAND_AMPERSAND_INFO, -1); 264 return new SymbolToken(BAR_INFO, -1);
248 case '||': return new SymbolToken(BAR_BAR_INFO, -1); 265 case '>>':
266 return new SymbolToken(GT_GT_INFO, -1);
267 case '<<':
268 return new SymbolToken(LT_LT_INFO, -1);
269 case '==':
270 return new SymbolToken(EQ_EQ_INFO, -1);
271 case '!=':
272 return new SymbolToken(BANG_EQ_INFO, -1);
273 case '>':
274 return new SymbolToken(GT_INFO, -1);
275 case '>=':
276 return new SymbolToken(GT_EQ_INFO, -1);
277 case '<':
278 return new SymbolToken(LT_INFO, -1);
279 case '<=':
280 return new SymbolToken(LT_EQ_INFO, -1);
281 case '&&':
282 return new SymbolToken(AMPERSAND_AMPERSAND_INFO, -1);
283 case '||':
284 return new SymbolToken(BAR_BAR_INFO, -1);
249 default: 285 default:
250 throw "Unrecognized binary operator: $operatorName"; 286 throw "Unrecognized binary operator: $operatorName";
251 } 287 }
252 } 288 }
253 289
254 static Token incrementToken(String operatorName) { 290 static Token incrementToken(String operatorName) {
255 switch (operatorName) { 291 switch (operatorName) {
256 case '++': return new SymbolToken(PLUS_PLUS_INFO, -1); 292 case '++':
257 case '--': return new SymbolToken(MINUS_MINUS_INFO, -1); 293 return new SymbolToken(PLUS_PLUS_INFO, -1);
294 case '--':
295 return new SymbolToken(MINUS_MINUS_INFO, -1);
258 default: 296 default:
259 throw "Unrecognized increment operator: $operatorName"; 297 throw "Unrecognized increment operator: $operatorName";
260 } 298 }
261 } 299 }
262 300
263 static Token typeOpToken(String operatorName) { 301 static Token typeOpToken(String operatorName) {
264 switch (operatorName) { // "is!" is not an operator in the frontend AST. 302 switch (operatorName) {
265 case 'is': return new SymbolToken(IS_INFO, -1); 303 // "is!" is not an operator in the frontend AST.
266 case 'as': return new SymbolToken(AS_INFO, -1); 304 case 'is':
305 return new SymbolToken(IS_INFO, -1);
306 case 'as':
307 return new SymbolToken(AS_INFO, -1);
267 default: 308 default:
268 throw 'Unrecognized type operator: $operatorName'; 309 throw 'Unrecognized type operator: $operatorName';
269 } 310 }
270 } 311 }
271 312
272 Token unopToken(String operatorName) { 313 Token unopToken(String operatorName) {
273 switch (operatorName) { 314 switch (operatorName) {
274 case '-': return new SymbolToken(MINUS_INFO, -1); 315 case '-':
275 case '~': return new SymbolToken(TILDE_INFO, -1); 316 return new SymbolToken(MINUS_INFO, -1);
276 case '!': return bang; 317 case '~':
318 return new SymbolToken(TILDE_INFO, -1);
319 case '!':
320 return bang;
277 default: 321 default:
278 throw "Unrecognized unary operator: $operatorName"; 322 throw "Unrecognized unary operator: $operatorName";
279 } 323 }
280 } 324 }
281 325
282 tree.Node makeStaticReceiver(elements.Element element) { 326 tree.Node makeStaticReceiver(elements.Element element) {
283 if (treeElements == null) return null; 327 if (treeElements == null) return null;
284 if (element.isStatic) { 328 if (element.isStatic) {
285 elements.ClassElement enclosingClass = element.enclosingClass; 329 elements.ClassElement enclosingClass = element.enclosingClass;
286 tree.Send send = new tree.Send( 330 tree.Send send = new tree.Send(null, makeIdentifier(enclosingClass.name));
287 null,
288 makeIdentifier(enclosingClass.name));
289 treeElements[send] = enclosingClass; 331 treeElements[send] = enclosingClass;
290 return send; 332 return send;
291 } else { 333 } else {
292 return null; 334 return null;
293 } 335 }
294 } 336 }
295 337
296 tree.Node makeArgument(Argument arg) { 338 tree.Node makeArgument(Argument arg) {
297 if (arg is Expression) { 339 if (arg is Expression) {
298 return makeExpression(arg); 340 return makeExpression(arg);
299 } else if (arg is NamedArgument) { 341 } else if (arg is NamedArgument) {
300 return new tree.NamedArgument( 342 return new tree.NamedArgument(
301 makeIdentifier(arg.name), 343 makeIdentifier(arg.name), colon, makeExpression(arg.expression));
302 colon,
303 makeExpression(arg.expression));
304 } else { 344 } else {
305 throw "Unrecognized argument type: ${arg}"; 345 throw "Unrecognized argument type: ${arg}";
306 } 346 }
307 } 347 }
308 348
309 tree.Node makeExpression(Expression exp) { 349 tree.Node makeExpression(Expression exp) {
310 return makeExp(exp, EXPRESSION); 350 return makeExp(exp, EXPRESSION);
311 } 351 }
312 352
313 /// Converts [exp] to a [tree.Node] that unparses to an expression with 353 /// Converts [exp] to a [tree.Node] that unparses to an expression with
(...skipping 17 matching lines...) Expand all
331 selector = makeIdentifier(left.name); 371 selector = makeIdentifier(left.name);
332 arguments = singleton(makeExpression(exp.right)); 372 arguments = singleton(makeExpression(exp.right));
333 element = left.element; 373 element = left.element;
334 } else if (left is FieldExpression) { 374 } else if (left is FieldExpression) {
335 receiver = makeExp(left.object, PRIMARY, beginStmt: beginStmt); 375 receiver = makeExp(left.object, PRIMARY, beginStmt: beginStmt);
336 selector = makeIdentifier(left.fieldName); 376 selector = makeIdentifier(left.fieldName);
337 arguments = singleton(makeExpression(exp.right)); 377 arguments = singleton(makeExpression(exp.right));
338 } else if (left is IndexExpression) { 378 } else if (left is IndexExpression) {
339 receiver = makeExp(left.object, PRIMARY, beginStmt: beginStmt); 379 receiver = makeExp(left.object, PRIMARY, beginStmt: beginStmt);
340 selector = new tree.Operator(indexToken); 380 selector = new tree.Operator(indexToken);
341 arguments = bracketList(',', 381 arguments = bracketList(
342 [makeExpression(left.index), makeExpression(exp.right)]); 382 ',', [makeExpression(left.index), makeExpression(exp.right)]);
343 } else { 383 } else {
344 throw "Unexpected left-hand side of assignment: ${left}"; 384 throw "Unexpected left-hand side of assignment: ${left}";
345 } 385 }
346 tree.Operator op = new tree.Operator(assignmentToken(exp.operator)); 386 tree.Operator op = new tree.Operator(assignmentToken(exp.operator));
347 result = new tree.SendSet(receiver, selector, op, arguments); 387 result = new tree.SendSet(receiver, selector, op, arguments);
348 if (left is Identifier) { 388 if (left is Identifier) {
349 setElement(result, element, exp); 389 setElement(result, element, exp);
350 } 390 }
351 precedence = EXPRESSION; 391 precedence = EXPRESSION;
352 } else if (exp is FieldInitializer) { 392 } else if (exp is FieldInitializer) {
353 precedence = EXPRESSION; 393 precedence = EXPRESSION;
354 tree.Node receiver = makeIdentifier('this'); 394 tree.Node receiver = makeIdentifier('this');
355 tree.Node selector = makeIdentifier(exp.element.name); 395 tree.Node selector = makeIdentifier(exp.element.name);
356 tree.Operator op = new tree.Operator(assignmentToken("=")); 396 tree.Operator op = new tree.Operator(assignmentToken("="));
357 // We pass CALLEE to ensure we write eg.: 397 // We pass CALLEE to ensure we write eg.:
358 // class B { var x; B() : x = (() {return a;}) {}} 398 // class B { var x; B() : x = (() {return a;}) {}}
359 // Not the invalid: 399 // Not the invalid:
360 // class B { var x; B() : x = () {return a;} {}} 400 // class B { var x; B() : x = () {return a;} {}}
361 result = new tree.SendSet(receiver, selector, op, 401 result = new tree.SendSet(
362 singleton(makeExp(exp.body, CALLEE))); 402 receiver, selector, op, singleton(makeExp(exp.body, CALLEE)));
363 setElement(result, exp.element, exp); 403 setElement(result, exp.element, exp);
364 } else if (exp is SuperInitializer) { 404 } else if (exp is SuperInitializer) {
365 precedence = EXPRESSION; 405 precedence = EXPRESSION;
366 tree.Node receiver = makeIdentifier('super'); 406 tree.Node receiver = makeIdentifier('super');
367 tree.NodeList arguments = 407 tree.NodeList arguments =
368 argList(exp.arguments.map(makeArgument).toList()); 408 argList(exp.arguments.map(makeArgument).toList());
369 if (exp.target.name == "") { 409 if (exp.target.name == "") {
370 result = new tree.Send(null, receiver, arguments); 410 result = new tree.Send(null, receiver, arguments);
371 } else { 411 } else {
372 result = new tree.Send(receiver, 412 result =
373 makeIdentifier(exp.target.name), 413 new tree.Send(receiver, makeIdentifier(exp.target.name), arguments);
374 arguments);
375 } 414 }
376 setElement(result, exp.target, exp); 415 setElement(result, exp.target, exp);
377 } else if (exp is BinaryOperator) { 416 } else if (exp is BinaryOperator) {
378 precedence = BINARY_PRECEDENCE[exp.operator]; 417 precedence = BINARY_PRECEDENCE[exp.operator];
379 int deltaLeft = isAssociativeBinaryOperator(precedence) ? 0 : 1; 418 int deltaLeft = isAssociativeBinaryOperator(precedence) ? 0 : 1;
380 result = new tree.Send( 419 result = new tree.Send(
381 makeExp(exp.left, precedence + deltaLeft, beginStmt: beginStmt), 420 makeExp(exp.left, precedence + deltaLeft, beginStmt: beginStmt),
382 new tree.Operator(binopToken(exp.operator)), 421 new tree.Operator(binopToken(exp.operator)),
383 singleton(makeExp(exp.right, precedence + 1))); 422 singleton(makeExp(exp.right, precedence + 1)));
384 } else if (exp is CallFunction) { 423 } else if (exp is CallFunction) {
385 precedence = CALLEE; 424 precedence = CALLEE;
386 tree.Node selector; 425 tree.Node selector;
387 Expression callee = exp.callee; 426 Expression callee = exp.callee;
388 elements.Element element; 427 elements.Element element;
389 tree.Node receiver; 428 tree.Node receiver;
390 if (callee is Identifier) { 429 if (callee is Identifier) {
391 receiver = makeStaticReceiver(callee.element); 430 receiver = makeStaticReceiver(callee.element);
392 selector = makeIdentifier(callee.name); 431 selector = makeIdentifier(callee.name);
393 element = callee.element; 432 element = callee.element;
394 } else { 433 } else {
395 selector = makeExp(callee, CALLEE, beginStmt: beginStmt); 434 selector = makeExp(callee, CALLEE, beginStmt: beginStmt);
396 } 435 }
397 result = new tree.Send( 436 result = new tree.Send(
398 receiver, 437 receiver, selector, argList(exp.arguments.map(makeArgument)));
399 selector,
400 argList(exp.arguments.map(makeArgument)));
401 if (callee is Identifier) { 438 if (callee is Identifier) {
402 setElement(result, element, exp); 439 setElement(result, element, exp);
403 } 440 }
404 } else if (exp is CallMethod) { 441 } else if (exp is CallMethod) {
405 precedence = CALLEE; 442 precedence = CALLEE;
406 // TODO(sra): Elide receiver when This, but only if not in a scope that 443 // TODO(sra): Elide receiver when This, but only if not in a scope that
407 // shadows the method (e.g. constructor body). 444 // shadows the method (e.g. constructor body).
408 tree.Node receiver = makeExp(exp.object, PRIMARY, beginStmt: beginStmt); 445 tree.Node receiver = makeExp(exp.object, PRIMARY, beginStmt: beginStmt);
409 result = new tree.Send( 446 result = new tree.Send(receiver, makeIdentifier(exp.methodName),
410 receiver,
411 makeIdentifier(exp.methodName),
412 argList(exp.arguments.map(makeArgument))); 447 argList(exp.arguments.map(makeArgument)));
413 } else if (exp is CallNew) { 448 } else if (exp is CallNew) {
414 precedence = CALLEE; 449 precedence = CALLEE;
415 tree.Node selector = makeName(exp.type.name); 450 tree.Node selector = makeName(exp.type.name);
416 if (exp.type.typeArguments.length > 0) { 451 if (exp.type.typeArguments.length > 0) {
417 selector = new tree.TypeAnnotation( 452 selector = new tree.TypeAnnotation(
418 selector, 453 selector, typeArgList(exp.type.typeArguments.map(makeType)));
419 typeArgList(exp.type.typeArguments.map(makeType)));
420 setType(selector, exp.dartType, exp); 454 setType(selector, exp.dartType, exp);
421 } 455 }
422 if (exp.constructorName != null) { 456 if (exp.constructorName != null) {
423 selector = new tree.Send( 457 selector = new tree.Send(selector, makeIdentifier(exp.constructorName));
424 selector,
425 makeIdentifier(exp.constructorName));
426 } 458 }
427 tree.Send send = new tree.Send( 459 tree.Send send = new tree.Send(
428 null, 460 null, selector, argList(exp.arguments.map(makeArgument)));
429 selector, 461 result =
430 argList(exp.arguments.map(makeArgument))); 462 new tree.NewExpression(exp.isConst ? constToken : newToken, send);
431 result = new tree.NewExpression(
432 exp.isConst ? constToken : newToken,
433 send);
434 setType(result, exp.dartType, exp); 463 setType(result, exp.dartType, exp);
435 setElement(send, exp.constructor, exp); 464 setElement(send, exp.constructor, exp);
436 } else if (exp is CallStatic) { 465 } else if (exp is CallStatic) {
437 precedence = CALLEE; 466 precedence = CALLEE;
438 result = new tree.Send( 467 result = new tree.Send(
439 makeStaticReceiver(exp.element), 468 makeStaticReceiver(exp.element),
440 makeIdentifier(exp.methodName), 469 makeIdentifier(exp.methodName),
441 argList(exp.arguments.map(makeArgument))); 470 argList(exp.arguments.map(makeArgument)));
442 setElement(result, exp.element, exp); 471 setElement(result, exp.element, exp);
443 } else if (exp is Conditional) { 472 } else if (exp is Conditional) {
444 precedence = CONDITIONAL; 473 precedence = CONDITIONAL;
445 result = new tree.Conditional( 474 result = new tree.Conditional(
446 makeExp(exp.condition, LOGICAL_OR, beginStmt: beginStmt), 475 makeExp(exp.condition, LOGICAL_OR, beginStmt: beginStmt),
447 makeExp(exp.thenExpression, EXPRESSION), 476 makeExp(exp.thenExpression, EXPRESSION),
448 makeExp(exp.elseExpression, EXPRESSION), 477 makeExp(exp.elseExpression, EXPRESSION),
449 question, 478 question,
450 colon); 479 colon);
451 } else if (exp is FieldExpression) { 480 } else if (exp is FieldExpression) {
452 precedence = PRIMARY; 481 precedence = PRIMARY;
453 // TODO(sra): Elide receiver when This, but only if not in a scope that 482 // TODO(sra): Elide receiver when This, but only if not in a scope that
454 // shadows the method (e.g. constructor body). 483 // shadows the method (e.g. constructor body).
455 tree.Node receiver = makeExp(exp.object, PRIMARY, beginStmt: beginStmt); 484 tree.Node receiver = makeExp(exp.object, PRIMARY, beginStmt: beginStmt);
456 result = new tree.Send(receiver, makeIdentifier(exp.fieldName)); 485 result = new tree.Send(receiver, makeIdentifier(exp.fieldName));
457 } else if (exp is ConstructorDefinition) { 486 } else if (exp is ConstructorDefinition) {
458 precedence = EXPRESSION; 487 precedence = EXPRESSION;
459 tree.NodeList parameters = makeParameters(exp.parameters); 488 tree.NodeList parameters = makeParameters(exp.parameters);
460 tree.NodeList initializers = 489 tree.NodeList initializers =
461 exp.initializers == null || exp.initializers.isEmpty 490 exp.initializers == null || exp.initializers.isEmpty
462 ? null 491 ? null
463 : makeList(",", exp.initializers.map(makeExpression).toList()); 492 : makeList(",", exp.initializers.map(makeExpression).toList());
464 tree.Node body = exp.isConst || exp.body == null 493 tree.Node body = exp.isConst || exp.body == null
465 ? new tree.EmptyStatement(semicolon) 494 ? new tree.EmptyStatement(semicolon)
466 : makeFunctionBody(exp.body); 495 : makeFunctionBody(exp.body);
467 result = new tree.FunctionExpression(constructorName(exp), 496 result = new tree.FunctionExpression(
497 constructorName(exp),
468 parameters, 498 parameters,
469 body, 499 body,
470 null, // return type 500 null, // return type
471 makeFunctionModifiers(exp), 501 makeFunctionModifiers(exp),
472 initializers, 502 initializers,
473 null, // get/set 503 null, // get/set
474 null); // async modifier 504 null); // async modifier
475 setElement(result, exp.element, exp); 505 setElement(result, exp.element, exp);
476 } else if (exp is FunctionExpression) { 506 } else if (exp is FunctionExpression) {
477 precedence = PRIMARY; 507 precedence = PRIMARY;
478 if (beginStmt && exp.name != null) { 508 if (beginStmt && exp.name != null) {
479 needParen = true; // Do not mistake for function declaration. 509 needParen = true; // Do not mistake for function declaration.
480 } 510 }
481 Token getOrSet = exp.isGetter 511 Token getOrSet = exp.isGetter ? getToken : exp.isSetter ? setToken : null;
482 ? getToken 512 tree.NodeList parameters =
483 : exp.isSetter 513 exp.isGetter ? makeList("", []) : makeParameters(exp.parameters);
484 ? setToken
485 : null;
486 tree.NodeList parameters = exp.isGetter
487 ? makeList("", [])
488 : makeParameters(exp.parameters);
489 tree.Node body = makeFunctionBody(exp.body); 514 tree.Node body = makeFunctionBody(exp.body);
490 result = new tree.FunctionExpression( 515 result = new tree.FunctionExpression(
491 functionName(exp), 516 functionName(exp),
492 parameters, 517 parameters,
493 body, 518 body,
494 exp.returnType == null || exp.element.isConstructor 519 exp.returnType == null || exp.element.isConstructor
495 ? null 520 ? null
496 : makeType(exp.returnType), 521 : makeType(exp.returnType),
497 makeFunctionModifiers(exp), 522 makeFunctionModifiers(exp),
498 null, // initializers 523 null, // initializers
499 getOrSet, // get/set 524 getOrSet, // get/set
500 null); // async modifier 525 null); // async modifier
501 elements.Element element = exp.element; 526 elements.Element element = exp.element;
502 if (element != null) setElement(result, element, exp); 527 if (element != null) setElement(result, element, exp);
503 } else if (exp is Identifier) { 528 } else if (exp is Identifier) {
504 precedence = CALLEE; 529 precedence = CALLEE;
505 result = new tree.Send( 530 result = new tree.Send(
506 makeStaticReceiver(exp.element), 531 makeStaticReceiver(exp.element), makeIdentifier(exp.name));
507 makeIdentifier(exp.name));
508 setElement(result, exp.element, exp); 532 setElement(result, exp.element, exp);
509 } else if (exp is Increment) { 533 } else if (exp is Increment) {
510 Expression lvalue = exp.expression; 534 Expression lvalue = exp.expression;
511 tree.Node receiver; 535 tree.Node receiver;
512 tree.Node selector; 536 tree.Node selector;
513 tree.Node argument; 537 tree.Node argument;
514 bool innerBeginStmt = beginStmt && !exp.isPrefix; 538 bool innerBeginStmt = beginStmt && !exp.isPrefix;
515 if (lvalue is Identifier) { 539 if (lvalue is Identifier) {
516 receiver = makeStaticReceiver(lvalue.element); 540 receiver = makeStaticReceiver(lvalue.element);
517 selector = makeIdentifier(lvalue.name); 541 selector = makeIdentifier(lvalue.name);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 if (exp.typeArguments != null && exp.typeArguments.length > 0) { 614 if (exp.typeArguments != null && exp.typeArguments.length > 0) {
591 typeArgs = typeArgList(exp.typeArguments.map(makeType)); 615 typeArgs = typeArgList(exp.typeArguments.map(makeType));
592 } 616 }
593 result = new tree.LiteralMap( 617 result = new tree.LiteralMap(
594 typeArgs, 618 typeArgs,
595 braceList(',', exp.entries.map(makeLiteralMapEntry)), 619 braceList(',', exp.entries.map(makeLiteralMapEntry)),
596 exp.isConst ? constToken : null); 620 exp.isConst ? constToken : null);
597 } else if (exp is LiteralSymbol) { 621 } else if (exp is LiteralSymbol) {
598 precedence = PRIMARY; 622 precedence = PRIMARY;
599 result = new tree.LiteralSymbol( 623 result = new tree.LiteralSymbol(
600 hash, 624 hash, makeList('.', exp.id.split('.').map(makeIdentifier)));
601 makeList('.', exp.id.split('.').map(makeIdentifier)));
602 } else if (exp is LiteralType) { 625 } else if (exp is LiteralType) {
603 precedence = TYPE_LITERAL; 626 precedence = TYPE_LITERAL;
604 elements.Element optionalElement = exp.type.element; 627 elements.Element optionalElement = exp.type.element;
605 result = new tree.Send( 628 result = new tree.Send(
606 optionalElement == null ? null : makeStaticReceiver(optionalElement), 629 optionalElement == null ? null : makeStaticReceiver(optionalElement),
607 makeIdentifier(exp.name)); 630 makeIdentifier(exp.name));
608 treeElements.setType(result, exp.type); 631 treeElements.setType(result, exp.type);
609 if (optionalElement != null) { // dynamic does not have an element 632 if (optionalElement != null) {
633 // dynamic does not have an element
610 setElement(result, optionalElement, exp); 634 setElement(result, optionalElement, exp);
611 } 635 }
612 } else if (exp is ReifyTypeVar) { 636 } else if (exp is ReifyTypeVar) {
613 precedence = PRIMARY; 637 precedence = PRIMARY;
614 result = new tree.Send( 638 result = new tree.Send(null, makeIdentifier(exp.name));
615 null,
616 makeIdentifier(exp.name));
617 setElement(result, exp.element, exp); 639 setElement(result, exp.element, exp);
618 setType(result, exp.element.type, exp); 640 setType(result, exp.element.type, exp);
619 } else if (exp is StringConcat) { 641 } else if (exp is StringConcat) {
620 precedence = PRIMARY; 642 precedence = PRIMARY;
621 result = unparseStringLiteral(exp); 643 result = unparseStringLiteral(exp);
622 } else if (exp is This) { 644 } else if (exp is This) {
623 precedence = CALLEE; 645 precedence = CALLEE;
624 result = makeIdentifier('this'); 646 result = makeIdentifier('this');
625 } else if (exp is Throw) { 647 } else if (exp is Throw) {
626 precedence = EXPRESSION; // ??? 648 precedence = EXPRESSION; // ???
627 result = new tree.Throw( 649 result = new tree.Throw(makeExpression(exp.expression), throwToken,
628 makeExpression(exp.expression),
629 throwToken,
630 throwToken); // endToken not used by unparser 650 throwToken); // endToken not used by unparser
631 } else if (exp is TypeOperator) { 651 } else if (exp is TypeOperator) {
632 precedence = RELATIONAL; 652 precedence = RELATIONAL;
633 tree.Operator operator; 653 tree.Operator operator;
634 tree.Node rightOperand = makeType(exp.type); 654 tree.Node rightOperand = makeType(exp.type);
635 if (exp.operator == 'is!') { 655 if (exp.operator == 'is!') {
636 operator = new tree.Operator(typeOpToken('is')); 656 operator = new tree.Operator(typeOpToken('is'));
637 rightOperand = new tree.Send( 657 rightOperand =
638 rightOperand, 658 new tree.Send(rightOperand, new tree.Operator(bang), blankList());
639 new tree.Operator(bang),
640 blankList());
641 } else { 659 } else {
642 operator = new tree.Operator(typeOpToken(exp.operator)); 660 operator = new tree.Operator(typeOpToken(exp.operator));
643 } 661 }
644 result = new tree.Send( 662 result = new tree.Send(
645 makeExp(exp.expression, BITWISE_OR, beginStmt: beginStmt), 663 makeExp(exp.expression, BITWISE_OR, beginStmt: beginStmt),
646 operator, 664 operator,
647 singleton(rightOperand)); 665 singleton(rightOperand));
648 } else if (exp is UnaryOperator) { 666 } else if (exp is UnaryOperator) {
649 precedence = UNARY; 667 precedence = UNARY;
650 result = new tree.Send.prefix( 668 result = new tree.Send.prefix(makeExp(exp.operand, UNARY),
651 makeExp(exp.operand, UNARY),
652 new tree.Operator(unopToken(exp.operatorName))); 669 new tree.Operator(unopToken(exp.operatorName)));
653 } else { 670 } else {
654 throw "Unknown expression type: ${exp}"; 671 throw "Unknown expression type: ${exp}";
655 } 672 }
656 673
657 needParen = needParen || precedence < minPrecedence; 674 needParen = needParen || precedence < minPrecedence;
658 if (needParen) { 675 if (needParen) {
659 result = parenthesize(result); 676 result = parenthesize(result);
660 } 677 }
661 return result; 678 return result;
662 } 679 }
663 680
664 /// Creates a LiteralString with [verbatim] as the value. 681 /// Creates a LiteralString with [verbatim] as the value.
665 /// No (un)quoting or (un)escaping will be performed by this method. 682 /// No (un)quoting or (un)escaping will be performed by this method.
666 /// The [DartString] inside the literal will be set to null because the 683 /// The [DartString] inside the literal will be set to null because the
667 /// code emitter does not use it. 684 /// code emitter does not use it.
668 tree.LiteralString makeVerbatimStringLiteral(String verbatim) { 685 tree.LiteralString makeVerbatimStringLiteral(String verbatim) {
669 Token tok = new StringToken.fromString(STRING_INFO, verbatim, -1); 686 Token tok = new StringToken.fromString(STRING_INFO, verbatim, -1);
670 return new tree.LiteralString(tok, null); 687 return new tree.LiteralString(tok, null);
671 } 688 }
672 689
673 tree.LiteralMapEntry makeLiteralMapEntry(LiteralMapEntry en) { 690 tree.LiteralMapEntry makeLiteralMapEntry(LiteralMapEntry en) {
674 return new tree.LiteralMapEntry( 691 return new tree.LiteralMapEntry(
675 makeExpression(en.key), 692 makeExpression(en.key), colon, makeExpression(en.value));
676 colon,
677 makeExpression(en.value));
678 } 693 }
679 694
680 /// A comment token to be inserted when [INSERT_NEW_BACKEND_COMMENT] is true. 695 /// A comment token to be inserted when [INSERT_NEW_BACKEND_COMMENT] is true.
681 final SymbolToken newBackendComment = new SymbolToken( 696 final SymbolToken newBackendComment = new SymbolToken(
682 const PrecedenceInfo('/* new backend */ ', 0, OPEN_CURLY_BRACKET_TOKEN), 697 const PrecedenceInfo('/* new backend */ ', 0, OPEN_CURLY_BRACKET_TOKEN),
683 -1); 698 -1);
684 699
685 tree.Node makeFunctionBody(Statement stmt) { 700 tree.Node makeFunctionBody(Statement stmt) {
686 if (INSERT_NEW_BACKEND_COMMENT) { 701 if (INSERT_NEW_BACKEND_COMMENT) {
687 return new tree.Block(makeList('', [makeBlock(stmt)], 702 return new tree.Block(
688 open: newBackendComment)); 703 makeList('', [makeBlock(stmt)], open: newBackendComment));
689 } else { 704 } else {
690 return makeBlock(stmt); 705 return makeBlock(stmt);
691 } 706 }
692 } 707 }
693 708
694 /// Produces a statement in a context where only blocks are allowed. 709 /// Produces a statement in a context where only blocks are allowed.
695 tree.Node makeBlock(Statement stmt) { 710 tree.Node makeBlock(Statement stmt) {
696 if (stmt is Block || stmt is EmptyStatement) { 711 if (stmt is Block || stmt is EmptyStatement) {
697 return makeStatement(stmt); 712 return makeStatement(stmt);
698 } else { 713 } else {
(...skipping 11 matching lines...) Expand all
710 } else if (stmt is EmptyStatement) { 725 } else if (stmt is EmptyStatement) {
711 // No need to include empty statements inside blocks 726 // No need to include empty statements inside blocks
712 } else { 727 } else {
713 accumulator.add(makeStatement(stmt)); 728 accumulator.add(makeStatement(stmt));
714 } 729 }
715 } 730 }
716 731
717 /// True if [stmt] is equivalent to an empty statement. 732 /// True if [stmt] is equivalent to an empty statement.
718 bool isEmptyStatement(Statement stmt) { 733 bool isEmptyStatement(Statement stmt) {
719 return stmt is EmptyStatement || 734 return stmt is EmptyStatement ||
720 (stmt is Block && stmt.statements.every(isEmptyStatement)); 735 (stmt is Block && stmt.statements.every(isEmptyStatement));
721 } 736 }
722 737
723 tree.Node makeStatement(Statement stmt, {bool shortIf: true}) { 738 tree.Node makeStatement(Statement stmt, {bool shortIf: true}) {
724 if (stmt is Block) { 739 if (stmt is Block) {
725 List<tree.Node> body = <tree.Node>[]; 740 List<tree.Node> body = <tree.Node>[];
726 for (Statement innerStmt in stmt.statements) { 741 for (Statement innerStmt in stmt.statements) {
727 addBlockMember(innerStmt, body); 742 addBlockMember(innerStmt, body);
728 } 743 }
729 return new tree.Block(braceList('', body)); 744 return new tree.Block(braceList('', body));
730 } else if (stmt is Break) { 745 } else if (stmt is Break) {
(...skipping 10 matching lines...) Expand all
741 return new tree.DoWhile( 756 return new tree.DoWhile(
742 makeStatement(stmt.body, shortIf: shortIf), 757 makeStatement(stmt.body, shortIf: shortIf),
743 parenthesize(makeExpression(stmt.condition)), 758 parenthesize(makeExpression(stmt.condition)),
744 doToken, 759 doToken,
745 whileToken, 760 whileToken,
746 semicolon); 761 semicolon);
747 } else if (stmt is EmptyStatement) { 762 } else if (stmt is EmptyStatement) {
748 return new tree.EmptyStatement(semicolon); 763 return new tree.EmptyStatement(semicolon);
749 } else if (stmt is ExpressionStatement) { 764 } else if (stmt is ExpressionStatement) {
750 return new tree.ExpressionStatement( 765 return new tree.ExpressionStatement(
751 makeExp(stmt.expression, EXPRESSION, beginStmt: true), 766 makeExp(stmt.expression, EXPRESSION, beginStmt: true), semicolon);
752 semicolon);
753 } else if (stmt is For) { 767 } else if (stmt is For) {
754 tree.Node initializer; 768 tree.Node initializer;
755 if (stmt.initializer is VariableDeclarations) { 769 if (stmt.initializer is VariableDeclarations) {
756 initializer = makeVariableDeclarations(stmt.initializer); 770 initializer = makeVariableDeclarations(stmt.initializer);
757 } else if (stmt.initializer is Expression) { 771 } else if (stmt.initializer is Expression) {
758 initializer = makeExpression(stmt.initializer); 772 initializer = makeExpression(stmt.initializer);
759 } else { 773 } else {
760 initializer = null; 774 initializer = null;
761 } 775 }
762 tree.Node condition; 776 tree.Node condition;
763 if (stmt.condition != null) { 777 if (stmt.condition != null) {
764 condition = new tree.ExpressionStatement( 778 condition = new tree.ExpressionStatement(
765 makeExpression(stmt.condition), 779 makeExpression(stmt.condition), semicolon);
766 semicolon);
767 } else { 780 } else {
768 condition = new tree.EmptyStatement(semicolon); 781 condition = new tree.EmptyStatement(semicolon);
769 } 782 }
770 return new tree.For( 783 return new tree.For(
771 initializer, 784 initializer,
772 condition, 785 condition,
773 makeList(',', stmt.updates.map(makeExpression)), 786 makeList(',', stmt.updates.map(makeExpression)),
774 makeStatement(stmt.body, shortIf: shortIf), 787 makeStatement(stmt.body, shortIf: shortIf),
775 forToken); 788 forToken);
776 } else if (stmt is ForIn) { 789 } else if (stmt is ForIn) {
777 tree.Node left; 790 tree.Node left;
778 if (stmt.leftHandValue is Identifier) { 791 if (stmt.leftHandValue is Identifier) {
779 left = makeExpression(stmt.leftHandValue); 792 left = makeExpression(stmt.leftHandValue);
780 } else { 793 } else {
781 left = makeVariableDeclarations(stmt.leftHandValue); 794 left = makeVariableDeclarations(stmt.leftHandValue);
782 } 795 }
783 return new tree.SyncForIn( 796 return new tree.SyncForIn(left, makeExpression(stmt.expression),
784 left, 797 makeStatement(stmt.body, shortIf: shortIf), forToken, inToken);
785 makeExpression(stmt.expression),
786 makeStatement(stmt.body, shortIf: shortIf),
787 forToken,
788 inToken);
789 } else if (stmt is FunctionDeclaration) { 798 } else if (stmt is FunctionDeclaration) {
790 tree.FunctionExpression function = new tree.FunctionExpression( 799 tree.FunctionExpression function = new tree.FunctionExpression(
791 stmt.name != null ? makeIdentifier(stmt.name) : null, 800 stmt.name != null ? makeIdentifier(stmt.name) : null,
792 makeParameters(stmt.parameters), 801 makeParameters(stmt.parameters),
793 makeFunctionBody(stmt.body), 802 makeFunctionBody(stmt.body),
794 stmt.returnType != null ? makeType(stmt.returnType) : null, 803 stmt.returnType != null ? makeType(stmt.returnType) : null,
795 makeEmptyModifiers(), 804 makeEmptyModifiers(),
796 null, // initializers 805 null, // initializers
797 null, // get/set 806 null, // get/set
798 null); // async modifier 807 null); // async modifier
799 setElement(function, stmt.function.element, stmt); 808 setElement(function, stmt.function.element, stmt);
800 return new tree.FunctionDeclaration(function); 809 return new tree.FunctionDeclaration(function);
801 } else if (stmt is If) { 810 } else if (stmt is If) {
802 if (stmt.elseStatement == null || isEmptyStatement(stmt.elseStatement)) { 811 if (stmt.elseStatement == null || isEmptyStatement(stmt.elseStatement)) {
803 tree.Node node = new tree.If( 812 tree.Node node = new tree.If(
804 parenthesize(makeExpression(stmt.condition)), 813 parenthesize(makeExpression(stmt.condition)),
805 makeStatement(stmt.thenStatement), 814 makeStatement(stmt.thenStatement),
806 null, // else statement 815 null, // else statement
807 ifToken, 816 ifToken,
(...skipping 12 matching lines...) Expand all
820 } 829 }
821 } else if (stmt is LabeledStatement) { 830 } else if (stmt is LabeledStatement) {
822 List<tree.Label> labels = []; 831 List<tree.Label> labels = [];
823 Statement inner = stmt; 832 Statement inner = stmt;
824 while (inner is LabeledStatement) { 833 while (inner is LabeledStatement) {
825 LabeledStatement lbl = inner as LabeledStatement; 834 LabeledStatement lbl = inner as LabeledStatement;
826 labels.add(new tree.Label(makeIdentifier(lbl.label), colon)); 835 labels.add(new tree.Label(makeIdentifier(lbl.label), colon));
827 inner = lbl.statement; 836 inner = lbl.statement;
828 } 837 }
829 return new tree.LabeledStatement( 838 return new tree.LabeledStatement(
830 makeList('', labels), 839 makeList('', labels), makeStatement(inner, shortIf: shortIf));
831 makeStatement(inner, shortIf: shortIf));
832 } else if (stmt is Rethrow) { 840 } else if (stmt is Rethrow) {
833 return new tree.Rethrow(rethrowToken, semicolon); 841 return new tree.Rethrow(rethrowToken, semicolon);
834 } else if (stmt is Return) { 842 } else if (stmt is Return) {
835 return new tree.Return( 843 return new tree.Return(returnToken, semicolon,
836 returnToken,
837 semicolon,
838 stmt.expression == null ? null : makeExpression(stmt.expression)); 844 stmt.expression == null ? null : makeExpression(stmt.expression));
839 } else if (stmt is Switch) { 845 } else if (stmt is Switch) {
840 return new tree.SwitchStatement( 846 return new tree.SwitchStatement(
841 parenthesize(makeExpression(stmt.expression)), 847 parenthesize(makeExpression(stmt.expression)),
842 braceList('', stmt.cases.map(makeSwitchCase)), 848 braceList('', stmt.cases.map(makeSwitchCase)),
843 switchToken); 849 switchToken);
844 } else if (stmt is Try) { 850 } else if (stmt is Try) {
845 return new tree.TryStatement( 851 return new tree.TryStatement(
846 makeBlock(stmt.tryBlock), 852 makeBlock(stmt.tryBlock),
847 makeList(null, stmt.catchBlocks.map(makeCatchBlock)), 853 makeList(null, stmt.catchBlocks.map(makeCatchBlock)),
848 stmt.finallyBlock == null ? null : makeBlock(stmt.finallyBlock), 854 stmt.finallyBlock == null ? null : makeBlock(stmt.finallyBlock),
849 tryToken, 855 tryToken,
850 stmt.finallyBlock == null ? null : finallyToken); 856 stmt.finallyBlock == null ? null : finallyToken);
851 } else if (stmt is VariableDeclarations) { 857 } else if (stmt is VariableDeclarations) {
852 return makeVariableDeclarations(stmt, useVar: true, endToken: semicolon); 858 return makeVariableDeclarations(stmt, useVar: true, endToken: semicolon);
853 } else if (stmt is While) { 859 } else if (stmt is While) {
854 return new tree.While( 860 return new tree.While(parenthesize(makeExpression(stmt.condition)),
855 parenthesize(makeExpression(stmt.condition)), 861 makeStatement(stmt.body, shortIf: shortIf), whileToken);
856 makeStatement(stmt.body, shortIf: shortIf),
857 whileToken);
858 } else { 862 } else {
859 throw "Unrecognized statement: ${stmt}"; 863 throw "Unrecognized statement: ${stmt}";
860 } 864 }
861 } 865 }
862 866
863 tree.Node makeVariableDeclaration(VariableDeclaration vd) { 867 tree.Node makeVariableDeclaration(VariableDeclaration vd) {
864 tree.Node id = makeIdentifier(vd.name); 868 tree.Node id = makeIdentifier(vd.name);
865 setElement(id, vd.element, vd); 869 setElement(id, vd.element, vd);
866 if (vd.initializer == null) { 870 if (vd.initializer == null) {
867 return id; 871 return id;
868 } 872 }
869 tree.Node send = new tree.SendSet( 873 tree.Node send = new tree.SendSet(null, id, new tree.Operator(eq),
870 null, 874 singleton(makeExpression(vd.initializer)));
871 id,
872 new tree.Operator(eq),
873 singleton(makeExpression(vd.initializer)));
874 setElement(send, vd.element, vd); 875 setElement(send, vd.element, vd);
875 return send; 876 return send;
876 } 877 }
877 878
878 /// If [useVar] is true, the variable definition will use `var` as modifier 879 /// If [useVar] is true, the variable definition will use `var` as modifier
879 /// if no other modifiers are present. 880 /// if no other modifiers are present.
880 /// [endToken] will be used to terminate the declaration list. 881 /// [endToken] will be used to terminate the declaration list.
881 tree.Node makeVariableDeclarations(VariableDeclarations decl, 882 tree.Node makeVariableDeclarations(VariableDeclarations decl,
882 { bool useVar: false, 883 {bool useVar: false, Token endToken: null}) {
883 Token endToken: null }) {
884 return new tree.VariableDefinitions( 884 return new tree.VariableDefinitions(
885 decl.type == null ? null : makeType(decl.type), 885 decl.type == null ? null : makeType(decl.type),
886 makeVarModifiers(isConst: decl.isConst, 886 makeVarModifiers(
887 isFinal: decl.isFinal, 887 isConst: decl.isConst,
888 useVar: useVar && decl.type == null), 888 isFinal: decl.isFinal,
889 makeList(',', 889 useVar: useVar && decl.type == null),
890 decl.declarations.map(makeVariableDeclaration), 890 makeList(',', decl.declarations.map(makeVariableDeclaration),
891 close: endToken)); 891 close: endToken));
892 } 892 }
893 893
894 tree.CatchBlock makeCatchBlock(CatchBlock block) { 894 tree.CatchBlock makeCatchBlock(CatchBlock block) {
895 List<tree.VariableDefinitions> formals = []; 895 List<tree.VariableDefinitions> formals = [];
896 if (block.exceptionVar != null) { 896 if (block.exceptionVar != null) {
897 tree.Node exceptionName = makeIdentifier(block.exceptionVar.name); 897 tree.Node exceptionName = makeIdentifier(block.exceptionVar.name);
898 setElement(exceptionName, block.exceptionVar.element, block.exceptionVar); 898 setElement(exceptionName, block.exceptionVar.element, block.exceptionVar);
899 formals.add(new tree.VariableDefinitions( 899 formals.add(new tree.VariableDefinitions(
900 null, 900 null, makeEmptyModifiers(), singleton(exceptionName)));
901 makeEmptyModifiers(),
902 singleton(exceptionName)));
903 } 901 }
904 if (block.stackVar != null) { 902 if (block.stackVar != null) {
905 tree.Node stackTraceName = makeIdentifier(block.stackVar.name); 903 tree.Node stackTraceName = makeIdentifier(block.stackVar.name);
906 setElement(stackTraceName, block.stackVar.element, block.stackVar); 904 setElement(stackTraceName, block.stackVar.element, block.stackVar);
907 formals.add(new tree.VariableDefinitions( 905 formals.add(new tree.VariableDefinitions(
908 null, 906 null, makeEmptyModifiers(), singleton(stackTraceName)));
909 makeEmptyModifiers(),
910 singleton(stackTraceName)));
911 } 907 }
912 return new tree.CatchBlock( 908 return new tree.CatchBlock(
913 block.onType == null ? null : makeType(block.onType), 909 block.onType == null ? null : makeType(block.onType),
914 block.exceptionVar == null ? null : argList(formals), 910 block.exceptionVar == null ? null : argList(formals),
915 makeBlock(block.body), 911 makeBlock(block.body),
916 block.onType == null ? null : onToken, 912 block.onType == null ? null : onToken,
917 block.exceptionVar == null ? null : catchToken); 913 block.exceptionVar == null ? null : catchToken);
918 } 914 }
919 915
920 tree.SwitchCase makeSwitchCase(SwitchCase caze) { 916 tree.SwitchCase makeSwitchCase(SwitchCase caze) {
(...skipping 30 matching lines...) Expand all
951 } 947 }
952 948
953 tree.NodeList makeParameters(Parameters params) { 949 tree.NodeList makeParameters(Parameters params) {
954 List<tree.Node> nodes = 950 List<tree.Node> nodes =
955 params.requiredParameters.map(makeParameter).toList(); 951 params.requiredParameters.map(makeParameter).toList();
956 if (params.hasOptionalParameters) { 952 if (params.hasOptionalParameters) {
957 Token assign = params.hasNamedParameters ? colon : eq; 953 Token assign = params.hasNamedParameters ? colon : eq;
958 Token open = params.hasNamedParameters ? openBrace : openBracket; 954 Token open = params.hasNamedParameters ? openBrace : openBracket;
959 Token close = params.hasNamedParameters ? closeBrace : closeBracket; 955 Token close = params.hasNamedParameters ? closeBrace : closeBracket;
960 Iterable<tree.Node> opt = 956 Iterable<tree.Node> opt =
961 params.optionalParameters.map((p) => makeParameter(p,assign)); 957 params.optionalParameters.map((p) => makeParameter(p, assign));
962 nodes.add(new tree.NodeList(open, makeLink(opt), close, ',')); 958 nodes.add(new tree.NodeList(open, makeLink(opt), close, ','));
963 } 959 }
964 return argList(nodes); 960 return argList(nodes);
965 } 961 }
966 962
967 /// [assignOperator] is used for writing the default value. 963 /// [assignOperator] is used for writing the default value.
968 tree.Node makeParameter(Parameter param, [Token assignOperator]) { 964 tree.Node makeParameter(Parameter param, [Token assignOperator]) {
969 if (param.isFunction) { 965 if (param.isFunction) {
970 tree.Node definition = new tree.FunctionExpression( 966 tree.Node definition = new tree.FunctionExpression(
971 makeIdentifier(param.name), 967 makeIdentifier(param.name),
972 makeParameters(param.parameters), 968 makeParameters(param.parameters),
973 null, // body 969 null, // body
974 param.type == null ? null : makeType(param.type), 970 param.type == null ? null : makeType(param.type),
975 makeEmptyModifiers(), // TODO: Function parameter modifiers? 971 makeEmptyModifiers(), // TODO: Function parameter modifiers?
976 null, // initializers 972 null, // initializers
977 null, // get/set 973 null, // get/set
978 null); // async modifier 974 null); // async modifier
979 if (param.element != null) { 975 if (param.element != null) {
980 setElement(definition, param.element, param); 976 setElement(definition, param.element, param);
981 } 977 }
982 if (param.defaultValue != null) { 978 if (param.defaultValue != null) {
983 definition = new tree.SendSet( 979 definition = new tree.SendSet(
984 null, 980 null,
985 definition, 981 definition,
986 new tree.Operator(assignOperator), 982 new tree.Operator(assignOperator),
987 singleton(makeExpression(param.defaultValue))); 983 singleton(makeExpression(param.defaultValue)));
988 } 984 }
989 return new tree.VariableDefinitions( 985 return new tree.VariableDefinitions(
990 null, 986 null, makeEmptyModifiers(), singleton(definition));
991 makeEmptyModifiers(),
992 singleton(definition));
993 } else { 987 } else {
994 tree.Node definition; 988 tree.Node definition;
995 if (param.defaultValue != null) { 989 if (param.defaultValue != null) {
996 definition = new tree.SendSet( 990 definition = new tree.SendSet(
997 null, 991 null,
998 makeIdentifier(param.name), 992 makeIdentifier(param.name),
999 new tree.Operator(assignOperator), 993 new tree.Operator(assignOperator),
1000 singleton(makeExpression(param.defaultValue))); 994 singleton(makeExpression(param.defaultValue)));
1001 } else { 995 } else {
1002 definition = makeIdentifier(param.name); 996 definition = makeIdentifier(param.name);
1003 } 997 }
1004 if (param.element != null) { 998 if (param.element != null) {
1005 setElement(definition, param.element, param); 999 setElement(definition, param.element, param);
1006 } 1000 }
1007 return new tree.VariableDefinitions( 1001 return new tree.VariableDefinitions(
1008 param.type == null ? null : makeType(param.type), 1002 param.type == null ? null : makeType(param.type),
1009 makeEmptyModifiers(), // TODO: Parameter modifiers? 1003 makeEmptyModifiers(), // TODO: Parameter modifiers?
1010 singleton(definition)); 1004 singleton(definition));
1011 } 1005 }
1012 } 1006 }
1013 1007
1014 tree.Modifiers makeEmptyModifiers() { 1008 tree.Modifiers makeEmptyModifiers() {
1015 return new tree.Modifiers(blankList()); 1009 return new tree.Modifiers(blankList());
1016 } 1010 }
1017 1011
1018 tree.Modifiers makeModifiers({bool isExternal: false, 1012 tree.Modifiers makeModifiers(
1019 bool isStatic: false, 1013 {bool isExternal: false,
1020 bool isAbstract: false, 1014 bool isStatic: false,
1021 bool isFactory: false, 1015 bool isAbstract: false,
1022 bool isConst: false, 1016 bool isFactory: false,
1023 bool isFinal: false, 1017 bool isConst: false,
1024 bool isVar: false}) { 1018 bool isFinal: false,
1019 bool isVar: false}) {
1025 List<tree.Node> nodes = []; 1020 List<tree.Node> nodes = [];
1026 if (isExternal) { 1021 if (isExternal) {
1027 nodes.add(makeIdentifier('external')); 1022 nodes.add(makeIdentifier('external'));
1028 } 1023 }
1029 if (isStatic) { 1024 if (isStatic) {
1030 nodes.add(makeIdentifier('static')); 1025 nodes.add(makeIdentifier('static'));
1031 } 1026 }
1032 if (isAbstract) { 1027 if (isAbstract) {
1033 nodes.add(makeIdentifier('abstract')); 1028 nodes.add(makeIdentifier('abstract'));
1034 } 1029 }
1035 if (isFactory) { 1030 if (isFactory) {
1036 nodes.add(makeIdentifier('factory')); 1031 nodes.add(makeIdentifier('factory'));
1037 } 1032 }
1038 if (isConst) { 1033 if (isConst) {
1039 nodes.add(makeIdentifier('const')); 1034 nodes.add(makeIdentifier('const'));
1040 } 1035 }
1041 if (isFinal) { 1036 if (isFinal) {
1042 nodes.add(makeIdentifier('final')); 1037 nodes.add(makeIdentifier('final'));
1043 } 1038 }
1044 if (isVar) { 1039 if (isVar) {
1045 nodes.add(makeIdentifier('var')); 1040 nodes.add(makeIdentifier('var'));
1046 } 1041 }
1047 return new tree.Modifiers(makeList(' ', nodes)); 1042 return new tree.Modifiers(makeList(' ', nodes));
1048 } 1043 }
1049 1044
1050 tree.Modifiers makeVarModifiers({bool isConst: false, 1045 tree.Modifiers makeVarModifiers(
1051 bool isFinal: false, 1046 {bool isConst: false,
1052 bool useVar: false, 1047 bool isFinal: false,
1053 bool isStatic: false}) { 1048 bool useVar: false,
1054 return makeModifiers(isStatic: isStatic, 1049 bool isStatic: false}) {
1055 isConst: isConst, 1050 return makeModifiers(
1056 isFinal: isFinal, 1051 isStatic: isStatic,
1057 isVar: useVar && !(isConst || isFinal)); 1052 isConst: isConst,
1053 isFinal: isFinal,
1054 isVar: useVar && !(isConst || isFinal));
1058 } 1055 }
1059 1056
1060 tree.Modifiers makeFunctionModifiers(FunctionExpression exp) { 1057 tree.Modifiers makeFunctionModifiers(FunctionExpression exp) {
1061 if (exp.element == null) return makeEmptyModifiers(); 1058 if (exp.element == null) return makeEmptyModifiers();
1062 return makeModifiers(isExternal: exp.element.isExternal, 1059 return makeModifiers(
1063 isStatic: exp.element.isStatic, 1060 isExternal: exp.element.isExternal,
1064 isFactory: exp.element.isFactoryConstructor, 1061 isStatic: exp.element.isStatic,
1065 isConst: exp.element.isConst); 1062 isFactory: exp.element.isFactoryConstructor,
1063 isConst: exp.element.isConst);
1066 } 1064 }
1067 1065
1068 tree.Node makeNodeForClassElement(elements.ClassElement cls) { 1066 tree.Node makeNodeForClassElement(elements.ClassElement cls) {
1069 if (cls.isMixinApplication) { 1067 if (cls.isMixinApplication) {
1070 return makeNamedMixinApplication(cls); 1068 return makeNamedMixinApplication(cls);
1071 } else if (cls.isEnumClass) { 1069 } else if (cls.isEnumClass) {
1072 return makeEnum(cls); 1070 return makeEnum(cls);
1073 } else { 1071 } else {
1074 return makeClassNode(cls); 1072 return makeClassNode(cls);
1075 } 1073 }
1076 } 1074 }
1077 1075
1078 tree.Typedef makeTypedef(elements.TypedefElement typdef) { 1076 tree.Typedef makeTypedef(elements.TypedefElement typdef) {
1079 types.FunctionType functionType = typdef.alias; 1077 types.FunctionType functionType = typdef.alias;
1080 final tree.TypeAnnotation returnType = 1078 final tree.TypeAnnotation returnType =
1081 makeType(TypeGenerator.createType(functionType.returnType)); 1079 makeType(TypeGenerator.createType(functionType.returnType));
1082 1080
1083 final tree.Identifier name = makeIdentifier(typdef.name); 1081 final tree.Identifier name = makeIdentifier(typdef.name);
1084 final tree.NodeList typeParameters = 1082 final tree.NodeList typeParameters =
1085 makeTypeParameters(typdef.typeVariables); 1083 makeTypeParameters(typdef.typeVariables);
1086 final tree.NodeList formals = 1084 final tree.NodeList formals =
1087 makeParameters(TypeGenerator.createParametersFromType(functionType)); 1085 makeParameters(TypeGenerator.createParametersFromType(functionType));
1088 1086
1089 final Token typedefKeyword = typedefToken; 1087 final Token typedefKeyword = typedefToken;
1090 final Token endToken = semicolon; 1088 final Token endToken = semicolon;
1091 1089
1092 return new tree.Typedef(returnType, name, typeParameters, formals, 1090 return new tree.Typedef(
1093 typedefKeyword, endToken); 1091 returnType, name, typeParameters, formals, typedefKeyword, endToken);
1094 } 1092 }
1095 1093
1096 /// Create a [tree.NodeList] containing the type variable declarations in 1094 /// Create a [tree.NodeList] containing the type variable declarations in
1097 /// [typeVaraiables. 1095 /// [typeVaraiables.
1098 tree.NodeList makeTypeParameters(List<types.DartType> typeVariables) { 1096 tree.NodeList makeTypeParameters(List<types.DartType> typeVariables) {
1099 if (typeVariables.isEmpty) { 1097 if (typeVariables.isEmpty) {
1100 return new tree.NodeList.empty(); 1098 return new tree.NodeList.empty();
1101 } else { 1099 } else {
1102 List<tree.Node> typeVariableList = <tree.Node>[]; 1100 List<tree.Node> typeVariableList = <tree.Node>[];
1103 for (types.TypeVariableType typeVariable in typeVariables) { 1101 for (types.TypeVariableType typeVariable in typeVariables) {
(...skipping 15 matching lines...) Expand all
1119 /// Create a [tree.NodeList] containing the declared interfaces. 1117 /// Create a [tree.NodeList] containing the declared interfaces.
1120 /// 1118 ///
1121 /// [interfaces] is from [elements.ClassElement] in reverse declaration order 1119 /// [interfaces] is from [elements.ClassElement] in reverse declaration order
1122 /// and it contains mixins. To produce a list of the declared interfaces only, 1120 /// and it contains mixins. To produce a list of the declared interfaces only,
1123 /// interfaces in [mixinTypes] are omitted. 1121 /// interfaces in [mixinTypes] are omitted.
1124 /// 1122 ///
1125 /// [forNamedMixinApplication] is because the structure of the [tree.NodeList] 1123 /// [forNamedMixinApplication] is because the structure of the [tree.NodeList]
1126 /// differs between [tree.NamedMixinApplication] and [tree.ClassNode]. 1124 /// differs between [tree.NamedMixinApplication] and [tree.ClassNode].
1127 // TODO(johnniwinther): Normalize interfaces on[tree.NamedMixinApplication] 1125 // TODO(johnniwinther): Normalize interfaces on[tree.NamedMixinApplication]
1128 // and [tree.ClassNode]. 1126 // and [tree.ClassNode].
1129 tree.NodeList makeInterfaces(Link<types.DartType> interfaces, 1127 tree.NodeList makeInterfaces(
1130 Set<types.DartType> mixinTypes, 1128 Link<types.DartType> interfaces, Set<types.DartType> mixinTypes,
1131 {bool forNamedMixinApplication: false}) { 1129 {bool forNamedMixinApplication: false}) {
1132 Link<tree.Node> typeAnnotations = const Link<tree.Node>(); 1130 Link<tree.Node> typeAnnotations = const Link<tree.Node>();
1133 for (Link<types.DartType> link = interfaces; 1131 for (Link<types.DartType> link = interfaces;
1134 !link.isEmpty; 1132 !link.isEmpty;
1135 link = link.tail) { 1133 link = link.tail) {
1136 types.DartType interface = link.head; 1134 types.DartType interface = link.head;
1137 if (!mixinTypes.contains(interface)) { 1135 if (!mixinTypes.contains(interface)) {
1138 typeAnnotations = typeAnnotations.prepend( 1136 typeAnnotations = typeAnnotations
1139 makeType(TypeGenerator.createType(interface))); 1137 .prepend(makeType(TypeGenerator.createType(interface)));
1140 } 1138 }
1141 } 1139 }
1142 if (typeAnnotations.isEmpty) { 1140 if (typeAnnotations.isEmpty) {
1143 return forNamedMixinApplication ? null : new tree.NodeList.empty(); 1141 return forNamedMixinApplication ? null : new tree.NodeList.empty();
1144 } else { 1142 } else {
1145 return new tree.NodeList( 1143 return new tree.NodeList(
1146 forNamedMixinApplication ? null : implementsToken, 1144 forNamedMixinApplication ? null : implementsToken,
1147 typeAnnotations, null, ','); 1145 typeAnnotations,
1146 null,
1147 ',');
1148 } 1148 }
1149 } 1149 }
1150 1150
1151 /// Creates a [tree.NamedMixinApplication] node for [cls]. 1151 /// Creates a [tree.NamedMixinApplication] node for [cls].
1152 // TODO(johnniwinther): Unify creation of mixin lists between 1152 // TODO(johnniwinther): Unify creation of mixin lists between
1153 // [NamedMixinApplicationElement] and [ClassElement]. 1153 // [NamedMixinApplicationElement] and [ClassElement].
1154 tree.NamedMixinApplication makeNamedMixinApplication( 1154 tree.NamedMixinApplication makeNamedMixinApplication(
1155 elements.MixinApplicationElement cls) { 1155 elements.MixinApplicationElement cls) {
1156
1157 assert(invariant(cls, !cls.isUnnamedMixinApplication, 1156 assert(invariant(cls, !cls.isUnnamedMixinApplication,
1158 message: "Cannot create ClassNode for unnamed mixin application " 1157 message: "Cannot create ClassNode for unnamed mixin application "
1159 "$cls.")); 1158 "$cls."));
1160 tree.Modifiers modifiers = makeModifiers(isAbstract: cls.isAbstract); 1159 tree.Modifiers modifiers = makeModifiers(isAbstract: cls.isAbstract);
1161 tree.Identifier name = makeIdentifier(cls.name); 1160 tree.Identifier name = makeIdentifier(cls.name);
1162 tree.NodeList typeParameters = makeTypeParameters(cls.typeVariables); 1161 tree.NodeList typeParameters = makeTypeParameters(cls.typeVariables);
1163 1162
1164 Set<types.DartType> mixinTypes = new Set<types.DartType>(); 1163 Set<types.DartType> mixinTypes = new Set<types.DartType>();
1165 Link<tree.Node> mixins = const Link<tree.Node>(); 1164 Link<tree.Node> mixins = const Link<tree.Node>();
1166 1165
1167 void addMixin(types.DartType mixinType) { 1166 void addMixin(types.DartType mixinType) {
1168 mixinTypes.add(mixinType); 1167 mixinTypes.add(mixinType);
1169 mixins = mixins.prepend(makeType(TypeGenerator.createType(mixinType))); 1168 mixins = mixins.prepend(makeType(TypeGenerator.createType(mixinType)));
1170 } 1169 }
1171 1170
1172 addMixin(cls.mixinType); 1171 addMixin(cls.mixinType);
1173 1172
1174 tree.Node superclass; 1173 tree.Node superclass;
1175 types.InterfaceType supertype = cls.supertype; 1174 types.InterfaceType supertype = cls.supertype;
1176 while (supertype.element.isUnnamedMixinApplication) { 1175 while (supertype.element.isUnnamedMixinApplication) {
1177 elements.MixinApplicationElement mixinApplication = supertype.element; 1176 elements.MixinApplicationElement mixinApplication = supertype.element;
1178 addMixin(cls.asInstanceOf(mixinApplication.mixin)); 1177 addMixin(cls.asInstanceOf(mixinApplication.mixin));
1179 supertype = mixinApplication.supertype; 1178 supertype = mixinApplication.supertype;
1180 } 1179 }
1181 superclass = 1180 superclass =
1182 makeType(TypeGenerator.createType(cls.asInstanceOf(supertype.element))); 1181 makeType(TypeGenerator.createType(cls.asInstanceOf(supertype.element)));
1183 tree.Node supernode = new tree.MixinApplication( 1182 tree.Node supernode = new tree.MixinApplication(
1184 superclass, new tree.NodeList(null, mixins, null, ',')); 1183 superclass, new tree.NodeList(null, mixins, null, ','));
1185 1184
1186 tree.NodeList interfaces = makeInterfaces( 1185 tree.NodeList interfaces = makeInterfaces(cls.interfaces, mixinTypes,
1187 cls.interfaces, mixinTypes, forNamedMixinApplication: true); 1186 forNamedMixinApplication: true);
1188 1187
1189 return new tree.NamedMixinApplication( 1188 return new tree.NamedMixinApplication(name, typeParameters, modifiers,
1190 name, typeParameters, modifiers, supernode, 1189 supernode, interfaces, classToken, semicolon);
1191 interfaces, classToken, semicolon);
1192 } 1190 }
1193 1191
1194 tree.Enum makeEnum(elements.EnumClassElement cls) { 1192 tree.Enum makeEnum(elements.EnumClassElement cls) {
1195 return new tree.Enum( 1193 return new tree.Enum(
1196 enumToken, 1194 enumToken,
1197 makeIdentifier(cls.name), 1195 makeIdentifier(cls.name),
1198 makeList(',', cls.enumValues.map((e) => makeIdentifier(e.name)), 1196 makeList(',', cls.enumValues.map((e) => makeIdentifier(e.name)),
1199 open: openBrace, close: closeBrace)); 1197 open: openBrace, close: closeBrace));
1200 } 1198 }
1201 1199
1202 /// Creates a [tree.ClassNode] node for [cls]. 1200 /// Creates a [tree.ClassNode] node for [cls].
1203 tree.ClassNode makeClassNode(elements.ClassElement cls) { 1201 tree.ClassNode makeClassNode(elements.ClassElement cls) {
1204 assert(invariant(cls, !cls.isUnnamedMixinApplication, 1202 assert(invariant(cls, !cls.isUnnamedMixinApplication,
1205 message: "Cannot create ClassNode for unnamed mixin application " 1203 message: "Cannot create ClassNode for unnamed mixin application "
1206 "$cls.")); 1204 "$cls."));
1207 tree.Modifiers modifiers = makeModifiers(isAbstract: cls.isAbstract); 1205 tree.Modifiers modifiers = makeModifiers(isAbstract: cls.isAbstract);
1208 tree.Identifier name = makeIdentifier(cls.name); 1206 tree.Identifier name = makeIdentifier(cls.name);
1209 tree.NodeList typeParameters = makeTypeParameters(cls.typeVariables); 1207 tree.NodeList typeParameters = makeTypeParameters(cls.typeVariables);
1210 tree.Node supernode; 1208 tree.Node supernode;
1211 types.InterfaceType supertype = cls.supertype; 1209 types.InterfaceType supertype = cls.supertype;
1212 Set<types.DartType> mixinTypes = new Set<types.DartType>(); 1210 Set<types.DartType> mixinTypes = new Set<types.DartType>();
1213 Link<tree.Node> mixins = const Link<tree.Node>(); 1211 Link<tree.Node> mixins = const Link<tree.Node>();
1214 1212
1215 void addMixin(types.DartType mixinType) { 1213 void addMixin(types.DartType mixinType) {
1216 mixinTypes.add(mixinType); 1214 mixinTypes.add(mixinType);
1217 mixins = mixins.prepend(makeType(TypeGenerator.createType(mixinType))); 1215 mixins = mixins.prepend(makeType(TypeGenerator.createType(mixinType)));
1218 } 1216 }
1219 1217
1220 if (supertype != null) { 1218 if (supertype != null) {
1221 if (supertype.element.isUnnamedMixinApplication) { 1219 if (supertype.element.isUnnamedMixinApplication) {
1222 while (supertype.element.isUnnamedMixinApplication) { 1220 while (supertype.element.isUnnamedMixinApplication) {
1223 elements.MixinApplicationElement mixinApplication = supertype.element; 1221 elements.MixinApplicationElement mixinApplication = supertype.element;
1224 addMixin(cls.asInstanceOf(mixinApplication.mixin)); 1222 addMixin(cls.asInstanceOf(mixinApplication.mixin));
1225 supertype = mixinApplication.supertype; 1223 supertype = mixinApplication.supertype;
1226 } 1224 }
1227 tree.Node superclass = makeType( 1225 tree.Node superclass = makeType(
1228 TypeGenerator.createType(cls.asInstanceOf(supertype.element))); 1226 TypeGenerator.createType(cls.asInstanceOf(supertype.element)));
1229 supernode = new tree.MixinApplication( 1227 supernode = new tree.MixinApplication(
1230 superclass, new tree.NodeList(null, mixins, null, ',')); 1228 superclass, new tree.NodeList(null, mixins, null, ','));
1231 } else if (!supertype.isObject) { 1229 } else if (!supertype.isObject) {
1232 supernode = makeType(TypeGenerator.createType(supertype)); 1230 supernode = makeType(TypeGenerator.createType(supertype));
1233 } 1231 }
1234 } 1232 }
1235 tree.NodeList interfaces = makeInterfaces( 1233 tree.NodeList interfaces = makeInterfaces(cls.interfaces, mixinTypes);
1236 cls.interfaces, mixinTypes);
1237 1234
1238 Token extendsKeyword = supernode != null ? extendsToken : null; 1235 Token extendsKeyword = supernode != null ? extendsToken : null;
1239 return new tree.ClassNode( 1236 return new tree.ClassNode(
1240 modifiers, name, typeParameters, supernode, 1237 modifiers,
1241 interfaces, openBrace, extendsKeyword, 1238 name,
1239 typeParameters,
1240 supernode,
1241 interfaces,
1242 openBrace,
1243 extendsKeyword,
1242 null, // No body. 1244 null, // No body.
1243 closeBrace); 1245 closeBrace);
1244 } 1246 }
1245 1247
1246 tree.Node constructorName(ConstructorDefinition exp) { 1248 tree.Node constructorName(ConstructorDefinition exp) {
1247 String name = exp.name; 1249 String name = exp.name;
1248 tree.Identifier className = makeIdentifier(exp.element.enclosingClass.name); 1250 tree.Identifier className = makeIdentifier(exp.element.enclosingClass.name);
1249 tree.Node result = name == "" 1251 tree.Node result =
1250 ? className 1252 name == "" ? className : new tree.Send(className, makeIdentifier(name));
1251 : new tree.Send(className, makeIdentifier(name));
1252 setElement(result, exp.element, exp); 1253 setElement(result, exp.element, exp);
1253 return result; 1254 return result;
1254 } 1255 }
1255 1256
1256 tree.Node functionName(FunctionExpression exp) { 1257 tree.Node functionName(FunctionExpression exp) {
1257 String name = exp.name; 1258 String name = exp.name;
1258 if (name == null) return null; 1259 if (name == null) return null;
1259 if (isUserDefinableOperator(name)) { 1260 if (isUserDefinableOperator(name)) {
1260 return makeOperator("operator$name"); 1261 return makeOperator("operator$name");
1261 } else if (name == "unary-") { 1262 } else if (name == "unary-") {
(...skipping 27 matching lines...) Expand all
1289 } 1290 }
1290 1291
1291 // Print every character and string interpolation 1292 // Print every character and string interpolation
1292 int startIndex = chunk.previous != null ? chunk.previous.endIndex : 0; 1293 int startIndex = chunk.previous != null ? chunk.previous.endIndex : 0;
1293 for (int i = startIndex; i < chunk.endIndex; i++) { 1294 for (int i = startIndex; i < chunk.endIndex; i++) {
1294 var part = parts[i]; 1295 var part = parts[i];
1295 if (part is Expression) { 1296 if (part is Expression) {
1296 // Finish the previous string interpolation, if there is one. 1297 // Finish the previous string interpolation, if there is one.
1297 tree.LiteralString lit = makeVerbatimStringLiteral(sb.toString()); 1298 tree.LiteralString lit = makeVerbatimStringLiteral(sb.toString());
1298 if (currentInterpolation != null) { 1299 if (currentInterpolation != null) {
1299 literalParts.add(new tree.StringInterpolationPart( 1300 literalParts.add(
1300 currentInterpolation, 1301 new tree.StringInterpolationPart(currentInterpolation, lit));
1301 lit));
1302 } else { 1302 } else {
1303 firstLiteral = lit; 1303 firstLiteral = lit;
1304 } 1304 }
1305 sb.clear(); 1305 sb.clear();
1306 currentInterpolation = makeExpression(part); 1306 currentInterpolation = makeExpression(part);
1307 } else { 1307 } else {
1308 int char = part; 1308 int char = part;
1309 sb.write(Unparser.getEscapedCharacter(char, quoteCode, raw)); 1309 sb.write(Unparser.getEscapedCharacter(char, quoteCode, raw));
1310 } 1310 }
1311 } 1311 }
1312 1312
1313 // Print ending quotes 1313 // Print ending quotes
1314 for (int i = 0; i < chunk.quoting.rightQuoteLength; i++) { 1314 for (int i = 0; i < chunk.quoting.rightQuoteLength; i++) {
1315 sb.write(chunk.quoting.quoteChar); 1315 sb.write(chunk.quoting.quoteChar);
1316 } 1316 }
1317 1317
1318 // Finish the previous string interpolation, if there is one. 1318 // Finish the previous string interpolation, if there is one.
1319 // Then wrap everything in a StringInterpolation, if relevant. 1319 // Then wrap everything in a StringInterpolation, if relevant.
1320 tree.LiteralString lit = makeVerbatimStringLiteral(sb.toString()); 1320 tree.LiteralString lit = makeVerbatimStringLiteral(sb.toString());
1321 tree.Node node; 1321 tree.Node node;
1322 if (firstLiteral == null) { 1322 if (firstLiteral == null) {
1323 node = lit; 1323 node = lit;
1324 } else { 1324 } else {
1325 literalParts.add(new tree.StringInterpolationPart( 1325 literalParts
1326 currentInterpolation, 1326 .add(new tree.StringInterpolationPart(currentInterpolation, lit));
1327 lit));
1328 node = new tree.StringInterpolation( 1327 node = new tree.StringInterpolation(
1329 firstLiteral, 1328 firstLiteral, makeList('', literalParts));
1330 makeList('', literalParts));
1331 } 1329 }
1332 1330
1333 // Juxtapose with the previous string chunks, if any. 1331 // Juxtapose with the previous string chunks, if any.
1334 if (chunk.previous != null) { 1332 if (chunk.previous != null) {
1335 return new tree.StringJuxtaposition( 1333 return new tree.StringJuxtaposition(
1336 printStringChunk(chunk.previous), 1334 printStringChunk(chunk.previous), node);
1337 node);
1338 } else { 1335 } else {
1339 return node; 1336 return node;
1340 } 1337 }
1341 } 1338 }
1342 return printStringChunk(output.chunk); 1339 return printStringChunk(output.chunk);
1343 } 1340 }
1344
1345 } 1341 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart ('k') | pkg/compiler/lib/src/dart_backend/dart_backend.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698