Chromium Code Reviews| 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_codegen; | 5 library dart_codegen; |
| 6 | 6 |
| 7 import 'dart_tree.dart' as tree; | 7 import 'dart_tree.dart' as tree; |
| 8 import 'dart_printer.dart'; | 8 import 'dart_printer.dart'; |
| 9 import 'dart_tree_printer.dart' show TreePrinter; | 9 import 'dart_tree_printer.dart' show TreePrinter; |
| 10 import '../tree/tree.dart' as frontend; | 10 import '../tree/tree.dart' as frontend; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 101 ParameterElement element = param.element; | 101 ParameterElement element = param.element; |
| 102 TypeAnnotation type = emitOptionalType(element.type); | 102 TypeAnnotation type = emitOptionalType(element.type); |
| 103 return new Parameter(element.name, type:type) | 103 return new Parameter(element.name, type:type) |
| 104 ..element = element; | 104 ..element = element; |
| 105 } | 105 } |
| 106 | 106 |
| 107 Parameters emitParameters(List<tree.Variable> params) { | 107 Parameters emitParameters(List<tree.Variable> params) { |
| 108 return new Parameters(params.map(emitParameter).toList(growable:false)); | 108 return new Parameters(params.map(emitParameter).toList(growable:false)); |
| 109 } | 109 } |
| 110 | 110 |
| 111 /// True if the two expressions are a reference to the same variable. | |
| 112 bool isSameVariable(Expression e1, Expression e2) { | |
| 113 // TODO(asgerf): Using the annotated element isn't the best way to do this | |
| 114 // since elements are supposed to go away from codegen when we discard the | |
| 115 // old backend. | |
| 116 return e1 is Identifier && | |
| 117 e2 is Identifier && | |
| 118 e1.element is VariableElement && | |
| 119 e1.element == e2.element; | |
| 120 } | |
| 121 | |
| 122 Expression makeAssignment(Expression target, Expression value) { | |
| 123 // Try to print as compound assignment or increment | |
| 124 if (value is BinaryOperator && isCompoundableOperator(value.operator)) { | |
| 125 Expression leftOperand = value.left; | |
| 126 Expression rightOperand = value.right; | |
| 127 bool valid = false; | |
| 128 if (isSameVariable(target, leftOperand)) { | |
| 129 valid = true; | |
| 130 } else if (target is FieldExpression && | |
| 131 leftOperand is FieldExpression && | |
| 132 isSameVariable(target.object, leftOperand.object) && | |
| 133 target.fieldName == leftOperand.fieldName) { | |
| 134 valid = true; | |
| 135 } else if (target is IndexExpression && | |
| 136 leftOperand is IndexExpression && | |
| 137 isSameVariable(target.object, leftOperand.object) && | |
| 138 isSameVariable(target.index, leftOperand.index)) { | |
| 139 valid = true; | |
| 140 } | |
| 141 if (valid) { | |
| 142 if (rightOperand is Literal && rightOperand.value.isOne) { | |
|
Kevin Millikin (Google)
2014/05/21 13:20:58
And operator is '+' or '-'.
asgerf
2014/05/21 13:25:07
Thanks
| |
| 143 return new Increment.prefix(target, value.operator + value.operator); | |
| 144 } else { | |
| 145 return new Assignment(target, value.operator + '=', rightOperand); | |
| 146 } | |
| 147 } | |
| 148 } | |
| 149 // Fall back to regular assignment | |
| 150 return new Assignment(target, '=', value); | |
| 151 } | |
| 152 | |
| 111 void visitExpressionStatement(tree.ExpressionStatement stmt) { | 153 void visitExpressionStatement(tree.ExpressionStatement stmt) { |
| 112 Expression e = visitExpression(stmt.expression); | 154 Expression e = visitExpression(stmt.expression); |
| 113 statementBuffer.add(new ExpressionStatement(e)); | 155 statementBuffer.add(new ExpressionStatement(e)); |
| 114 visitStatement(stmt.next); | 156 visitStatement(stmt.next); |
| 115 } | 157 } |
| 116 | 158 |
| 117 void visitLabeledStatement(tree.LabeledStatement stmt) { | 159 void visitLabeledStatement(tree.LabeledStatement stmt) { |
| 118 List<Statement> savedBuffer = statementBuffer; | 160 List<Statement> savedBuffer = statementBuffer; |
| 119 tree.Statement savedFallthrough = fallthrough; | 161 tree.Statement savedFallthrough = fallthrough; |
| 120 statementBuffer = <Statement>[]; | 162 statementBuffer = <Statement>[]; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 138 stmt.variable.name, | 180 stmt.variable.name, |
| 139 ElementKind.VARIABLE, | 181 ElementKind.VARIABLE, |
| 140 functionElement, | 182 functionElement, |
| 141 variableList, | 183 variableList, |
| 142 null); | 184 null); |
| 143 } | 185 } |
| 144 if (seenVariables.add(stmt.variable)) { | 186 if (seenVariables.add(stmt.variable)) { |
| 145 variables.add(new VariableDeclaration(stmt.variable.name) | 187 variables.add(new VariableDeclaration(stmt.variable.name) |
| 146 ..element = stmt.variable.element); | 188 ..element = stmt.variable.element); |
| 147 } | 189 } |
| 148 Expression def = visitExpression(stmt.definition); | 190 statementBuffer.add(new ExpressionStatement(makeAssignment( |
| 149 statementBuffer.add(new ExpressionStatement(new Assignment( | |
| 150 visitVariable(stmt.variable), | 191 visitVariable(stmt.variable), |
| 151 '=', | 192 visitExpression(stmt.definition)))); |
| 152 def))); | |
| 153 visitStatement(stmt.next); | 193 visitStatement(stmt.next); |
| 154 } | 194 } |
| 155 | 195 |
| 156 void visitReturn(tree.Return stmt) { | 196 void visitReturn(tree.Return stmt) { |
| 157 Expression inner = visitExpression(stmt.value); | 197 Expression inner = visitExpression(stmt.value); |
| 158 statementBuffer.add(new Return(inner)); | 198 statementBuffer.add(new Return(inner)); |
| 159 } | 199 } |
| 160 | 200 |
| 161 void visitBreak(tree.Break stmt) { | 201 void visitBreak(tree.Break stmt) { |
| 162 tree.Statement fall = fallthrough; | 202 tree.Statement fall = fallthrough; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 234 name = '-'; | 274 name = '-'; |
| 235 } | 275 } |
| 236 return new UnaryOperator(name, receiver); | 276 return new UnaryOperator(name, receiver); |
| 237 } | 277 } |
| 238 return new BinaryOperator(receiver, exp.selector.name, args[0]); | 278 return new BinaryOperator(receiver, exp.selector.name, args[0]); |
| 239 | 279 |
| 240 case SelectorKind.GETTER: | 280 case SelectorKind.GETTER: |
| 241 return new FieldExpression(receiver, exp.selector.name); | 281 return new FieldExpression(receiver, exp.selector.name); |
| 242 | 282 |
| 243 case SelectorKind.SETTER: | 283 case SelectorKind.SETTER: |
| 244 return new Assignment( | 284 return makeAssignment( |
| 245 new FieldExpression(receiver, exp.selector.name), | 285 new FieldExpression(receiver, exp.selector.name), |
| 246 '=', | |
| 247 args[0]); | 286 args[0]); |
| 248 | 287 |
| 249 case SelectorKind.INDEX: | 288 case SelectorKind.INDEX: |
| 250 Expression e = new IndexExpression(receiver, args[0]); | 289 Expression e = new IndexExpression(receiver, args[0]); |
| 251 if (args.length == 2) { | 290 if (args.length == 2) { |
| 252 e = new Assignment(e, '=', args[1]); | 291 e = makeAssignment(e, args[1]); |
| 253 } | 292 } |
| 254 return e; | 293 return e; |
| 255 | 294 |
| 256 default: | 295 default: |
| 257 throw "Unexpected selector in InvokeMethod: ${exp.selector.kind}"; | 296 throw "Unexpected selector in InvokeMethod: ${exp.selector.kind}"; |
| 258 } | 297 } |
| 259 } | 298 } |
| 260 | 299 |
| 261 Expression visitInvokeConstructor(tree.InvokeConstructor exp) { | 300 Expression visitInvokeConstructor(tree.InvokeConstructor exp) { |
| 262 List args = emitArguments(exp); | 301 List args = emitArguments(exp); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 333 emitConstant(constant.keys.entries[i]), | 372 emitConstant(constant.keys.entries[i]), |
| 334 emitConstant(constant.values[i]))); | 373 emitConstant(constant.values[i]))); |
| 335 } | 374 } |
| 336 return new LiteralMap(entries, isConst: true); | 375 return new LiteralMap(entries, isConst: true); |
| 337 } else { | 376 } else { |
| 338 throw "Unsupported constant: $constant"; | 377 throw "Unsupported constant: $constant"; |
| 339 } | 378 } |
| 340 } | 379 } |
| 341 } | 380 } |
| 342 | 381 |
| OLD | NEW |