OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |