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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 47 | 47 |
| 48 /// Labels that could not be eliminated using fallthrough. | 48 /// Labels that could not be eliminated using fallthrough. |
| 49 Set<tree.Label> usedLabels; | 49 Set<tree.Label> usedLabels; |
| 50 | 50 |
| 51 FunctionExpression emit(FunctionElement element, | 51 FunctionExpression emit(FunctionElement element, |
| 52 tree.FunctionDefinition definition) { | 52 tree.FunctionDefinition definition) { |
| 53 functionElement = element; | 53 functionElement = element; |
| 54 variables = <VariableDeclaration>[]; | 54 variables = <VariableDeclaration>[]; |
| 55 statementBuffer = <Statement>[]; | 55 statementBuffer = <Statement>[]; |
| 56 seenVariables = new Set<tree.Variable>(); | 56 seenVariables = new Set<tree.Variable>(); |
| 57 tree.Variable.counter = 0; | |
| 58 variableList = new modelx.VariableList(tree.Modifiers.EMPTY); | 57 variableList = new modelx.VariableList(tree.Modifiers.EMPTY); |
| 59 fallthrough = null; | 58 fallthrough = null; |
| 60 usedLabels = new Set<tree.Label>(); | 59 usedLabels = new Set<tree.Label>(); |
| 61 | 60 |
| 62 Parameters parameters = emitParameters(definition.parameters); | 61 Parameters parameters = emitParameters(definition.parameters); |
| 63 visitStatement(definition.body); | 62 visitStatement(definition.body); |
| 64 removeTrailingReturn(); | 63 removeTrailingReturn(); |
| 65 Statement body = new Block(statementBuffer); | 64 Statement body = new Block(statementBuffer); |
| 66 if (variables.length > 0) { | 65 if (variables.length > 0) { |
| 67 Statement head = new VariableDeclarations(variables); | 66 Statement head = new VariableDeclarations(variables); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 167 savedBuffer.add(new LabeledStatement(stmt.label.name, | 166 savedBuffer.add(new LabeledStatement(stmt.label.name, |
| 168 new Block(statementBuffer))); | 167 new Block(statementBuffer))); |
| 169 } else { | 168 } else { |
| 170 savedBuffer.add(new Block(statementBuffer)); | 169 savedBuffer.add(new Block(statementBuffer)); |
| 171 } | 170 } |
| 172 fallthrough = savedFallthrough; | 171 fallthrough = savedFallthrough; |
| 173 statementBuffer = savedBuffer; | 172 statementBuffer = savedBuffer; |
| 174 visitStatement(stmt.next); | 173 visitStatement(stmt.next); |
| 175 } | 174 } |
| 176 | 175 |
| 176 String getVariableName(tree.Variable variable) { | |
|
sigurdm
2014/06/04 07:51:56
Maybe move this to a getter, so the .name field is
asgerf
2014/06/04 09:40:51
Not so easy since it depends on this.variableList
sigurdm
2014/06/04 10:29:39
True - my mistake
| |
| 177 if (variable.element != null && variable.index == 0) { | |
| 178 return variable.element.name; | |
| 179 } | |
| 180 // FIXME(asgerf): prevent name clashes | |
| 181 String name; | |
| 182 if (variable.element != null) { | |
| 183 name = '${variable.element.name}${variable.index}'; | |
| 184 } else { | |
| 185 name = 'v${variable.index}'; | |
| 186 } | |
| 187 // Synthesize an element for the variable | |
| 188 variable.element = new modelx.VariableElementX( | |
| 189 name, | |
| 190 ElementKind.VARIABLE, | |
| 191 functionElement, | |
| 192 variableList, | |
| 193 null); | |
| 194 variable.index = 0; // Index is relative to the new synthesized element. | |
| 195 return name; | |
| 196 } | |
| 197 | |
| 177 void visitAssign(tree.Assign stmt) { | 198 void visitAssign(tree.Assign stmt) { |
| 178 // Synthesize an element for the variable, if necessary. | 199 String name = getVariableName(stmt.variable); |
| 179 if (stmt.variable.element == null) { | |
| 180 stmt.variable.element = new modelx.VariableElementX( | |
| 181 stmt.variable.name, | |
| 182 ElementKind.VARIABLE, | |
| 183 functionElement, | |
| 184 variableList, | |
| 185 null); | |
| 186 } | |
| 187 if (seenVariables.add(stmt.variable)) { | 200 if (seenVariables.add(stmt.variable)) { |
| 188 variables.add(new VariableDeclaration(stmt.variable.name) | 201 variables.add(new VariableDeclaration(name) |
| 189 ..element = stmt.variable.element); | 202 ..element = stmt.variable.element); |
| 190 } | 203 } |
| 191 statementBuffer.add(new ExpressionStatement(makeAssignment( | 204 statementBuffer.add(new ExpressionStatement(makeAssignment( |
| 192 visitVariable(stmt.variable), | 205 visitVariable(stmt.variable), |
| 193 visitExpression(stmt.definition)))); | 206 visitExpression(stmt.definition)))); |
| 194 visitStatement(stmt.next); | 207 visitStatement(stmt.next); |
| 195 } | 208 } |
| 196 | 209 |
| 197 void visitReturn(tree.Return stmt) { | 210 void visitReturn(tree.Return stmt) { |
| 198 Expression inner = visitExpression(stmt.value); | 211 Expression inner = visitExpression(stmt.value); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 342 return new BinaryOperator(visitExpression(exp.left), | 355 return new BinaryOperator(visitExpression(exp.left), |
| 343 exp.operator, | 356 exp.operator, |
| 344 visitExpression(exp.right)); | 357 visitExpression(exp.right)); |
| 345 } | 358 } |
| 346 | 359 |
| 347 Expression visitNot(tree.Not exp) { | 360 Expression visitNot(tree.Not exp) { |
| 348 return new UnaryOperator('!', visitExpression(exp.operand)); | 361 return new UnaryOperator('!', visitExpression(exp.operand)); |
| 349 } | 362 } |
| 350 | 363 |
| 351 Expression visitVariable(tree.Variable exp) { | 364 Expression visitVariable(tree.Variable exp) { |
| 352 return new Identifier(exp.name) | 365 return new Identifier(getVariableName(exp)) |
| 353 ..element = exp.element; | 366 ..element = exp.element; |
| 354 } | 367 } |
| 355 | 368 |
| 356 TypeAnnotation emitType(DartType type) { | 369 TypeAnnotation emitType(DartType type) { |
| 357 if (type is GenericType) { // TODO(asgerf): faster Link.map | 370 if (type is GenericType) { // TODO(asgerf): faster Link.map |
| 358 return new TypeAnnotation( | 371 return new TypeAnnotation( |
| 359 type.element.name, | 372 type.element.name, |
| 360 type.typeArguments.toList(growable:false) | 373 type.typeArguments.toList(growable:false) |
| 361 .map(emitType).toList(growable:false)) | 374 .map(emitType).toList(growable:false)) |
| 362 ..dartType = type; | 375 ..dartType = type; |
| 363 } else if (type is VoidType) { | 376 } else if (type is VoidType) { |
| 364 return new TypeAnnotation('void') | 377 return new TypeAnnotation('void') |
| 365 ..dartType = type; | 378 ..dartType = type; |
| 366 } else if (type is TypeVariableType) { | 379 } else if (type is TypeVariableType) { |
| 367 return new TypeAnnotation(type.name) | 380 return new TypeAnnotation(type.name) |
| 368 ..dartType = type; | 381 ..dartType = type; |
| 382 } else if (type is DynamicType) { | |
| 383 return new TypeAnnotation("dynamic") | |
| 384 ..dartType = type; | |
| 369 } else { | 385 } else { |
| 370 throw "Unsupported type annotation: $type"; | 386 throw "Unsupported type annotation: $type"; |
| 371 } | 387 } |
| 372 } | 388 } |
| 373 | 389 |
| 374 /// Like [emitType] except the dynamic type is converted to null. | 390 /// Like [emitType] except the dynamic type is converted to null. |
| 375 TypeAnnotation emitOptionalType(DartType type) { | 391 TypeAnnotation emitOptionalType(DartType type) { |
| 376 if (type.isDynamic) { | 392 if (type.isDynamic) { |
| 377 return null; | 393 return null; |
| 378 } else { | 394 } else { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 394 emitConstant(constant.keys.entries[i]), | 410 emitConstant(constant.keys.entries[i]), |
| 395 emitConstant(constant.values[i]))); | 411 emitConstant(constant.values[i]))); |
| 396 } | 412 } |
| 397 return new LiteralMap(entries, isConst: true); | 413 return new LiteralMap(entries, isConst: true); |
| 398 } else { | 414 } else { |
| 399 throw "Unsupported constant: $constant"; | 415 throw "Unsupported constant: $constant"; |
| 400 } | 416 } |
| 401 } | 417 } |
| 402 } | 418 } |
| 403 | 419 |
| OLD | NEW |