| 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 |