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 && |
| 143 (value.operator == '+' || value.operator == '-')) { |
| 144 return new Increment.prefix(target, value.operator + value.operator); |
| 145 } else { |
| 146 return new Assignment(target, value.operator + '=', rightOperand); |
| 147 } |
| 148 } |
| 149 } |
| 150 // Fall back to regular assignment |
| 151 return new Assignment(target, '=', value); |
| 152 } |
| 153 |
111 void visitExpressionStatement(tree.ExpressionStatement stmt) { | 154 void visitExpressionStatement(tree.ExpressionStatement stmt) { |
112 Expression e = visitExpression(stmt.expression); | 155 Expression e = visitExpression(stmt.expression); |
113 statementBuffer.add(new ExpressionStatement(e)); | 156 statementBuffer.add(new ExpressionStatement(e)); |
114 visitStatement(stmt.next); | 157 visitStatement(stmt.next); |
115 } | 158 } |
116 | 159 |
117 void visitLabeledStatement(tree.LabeledStatement stmt) { | 160 void visitLabeledStatement(tree.LabeledStatement stmt) { |
118 List<Statement> savedBuffer = statementBuffer; | 161 List<Statement> savedBuffer = statementBuffer; |
119 tree.Statement savedFallthrough = fallthrough; | 162 tree.Statement savedFallthrough = fallthrough; |
120 statementBuffer = <Statement>[]; | 163 statementBuffer = <Statement>[]; |
(...skipping 17 matching lines...) Expand all Loading... |
138 stmt.variable.name, | 181 stmt.variable.name, |
139 ElementKind.VARIABLE, | 182 ElementKind.VARIABLE, |
140 functionElement, | 183 functionElement, |
141 variableList, | 184 variableList, |
142 null); | 185 null); |
143 } | 186 } |
144 if (seenVariables.add(stmt.variable)) { | 187 if (seenVariables.add(stmt.variable)) { |
145 variables.add(new VariableDeclaration(stmt.variable.name) | 188 variables.add(new VariableDeclaration(stmt.variable.name) |
146 ..element = stmt.variable.element); | 189 ..element = stmt.variable.element); |
147 } | 190 } |
148 Expression def = visitExpression(stmt.definition); | 191 statementBuffer.add(new ExpressionStatement(makeAssignment( |
149 statementBuffer.add(new ExpressionStatement(new Assignment( | |
150 visitVariable(stmt.variable), | 192 visitVariable(stmt.variable), |
151 '=', | 193 visitExpression(stmt.definition)))); |
152 def))); | |
153 visitStatement(stmt.next); | 194 visitStatement(stmt.next); |
154 } | 195 } |
155 | 196 |
156 void visitReturn(tree.Return stmt) { | 197 void visitReturn(tree.Return stmt) { |
157 Expression inner = visitExpression(stmt.value); | 198 Expression inner = visitExpression(stmt.value); |
158 statementBuffer.add(new Return(inner)); | 199 statementBuffer.add(new Return(inner)); |
159 } | 200 } |
160 | 201 |
161 void visitBreak(tree.Break stmt) { | 202 void visitBreak(tree.Break stmt) { |
162 tree.Statement fall = fallthrough; | 203 tree.Statement fall = fallthrough; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 name = '-'; | 294 name = '-'; |
254 } | 295 } |
255 return new UnaryOperator(name, receiver); | 296 return new UnaryOperator(name, receiver); |
256 } | 297 } |
257 return new BinaryOperator(receiver, exp.selector.name, args[0]); | 298 return new BinaryOperator(receiver, exp.selector.name, args[0]); |
258 | 299 |
259 case SelectorKind.GETTER: | 300 case SelectorKind.GETTER: |
260 return new FieldExpression(receiver, exp.selector.name); | 301 return new FieldExpression(receiver, exp.selector.name); |
261 | 302 |
262 case SelectorKind.SETTER: | 303 case SelectorKind.SETTER: |
263 return new Assignment( | 304 return makeAssignment( |
264 new FieldExpression(receiver, exp.selector.name), | 305 new FieldExpression(receiver, exp.selector.name), |
265 '=', | |
266 args[0]); | 306 args[0]); |
267 | 307 |
268 case SelectorKind.INDEX: | 308 case SelectorKind.INDEX: |
269 Expression e = new IndexExpression(receiver, args[0]); | 309 Expression e = new IndexExpression(receiver, args[0]); |
270 if (args.length == 2) { | 310 if (args.length == 2) { |
271 e = new Assignment(e, '=', args[1]); | 311 e = makeAssignment(e, args[1]); |
272 } | 312 } |
273 return e; | 313 return e; |
274 | 314 |
275 default: | 315 default: |
276 throw "Unexpected selector in InvokeMethod: ${exp.selector.kind}"; | 316 throw "Unexpected selector in InvokeMethod: ${exp.selector.kind}"; |
277 } | 317 } |
278 } | 318 } |
279 | 319 |
280 Expression visitInvokeConstructor(tree.InvokeConstructor exp) { | 320 Expression visitInvokeConstructor(tree.InvokeConstructor exp) { |
281 List args = emitArguments(exp); | 321 List args = emitArguments(exp); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 emitConstant(constant.keys.entries[i]), | 394 emitConstant(constant.keys.entries[i]), |
355 emitConstant(constant.values[i]))); | 395 emitConstant(constant.values[i]))); |
356 } | 396 } |
357 return new LiteralMap(entries, isConst: true); | 397 return new LiteralMap(entries, isConst: true); |
358 } else { | 398 } else { |
359 throw "Unsupported constant: $constant"; | 399 throw "Unsupported constant: $constant"; |
360 } | 400 } |
361 } | 401 } |
362 } | 402 } |
363 | 403 |
OLD | NEW |