Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(530)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/dart_backend/dart_codegen.dart

Issue 312793002: dart2dart: Preserve variable names throughout the IR. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: SVN rebase Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 10 matching lines...) Expand all
21 tree.FunctionDefinition definition) { 21 tree.FunctionDefinition definition) {
22 FunctionExpression fn = new ASTEmitter().emit(element, definition); 22 FunctionExpression fn = new ASTEmitter().emit(element, definition);
23 return new TreePrinter(treeElements).makeExpression(fn); 23 return new TreePrinter(treeElements).makeExpression(fn);
24 } 24 }
25 25
26 /// Translates the dart_tree IR to Dart backend AST. 26 /// Translates the dart_tree IR to Dart backend AST.
27 class ASTEmitter extends tree.Visitor<dynamic, Expression> { 27 class ASTEmitter extends tree.Visitor<dynamic, Expression> {
28 /// Variables to be hoisted at the top of the current function. 28 /// Variables to be hoisted at the top of the current function.
29 List<VariableDeclaration> variables; 29 List<VariableDeclaration> variables;
30 30
31 /// Set of variables that have had their declaration inserted in [variables]. 31 /// Maps variables to their name.
32 Set<tree.Variable> seenVariables; 32 /// These variables have had their declaration inserted in [variables].
33 Map<tree.Variable, String> variableNames;
34
35 /// Variable names that have already been used. Used to avoid name clashes.
36 Set<String> usedVariableNames;
33 37
34 /// Statements emitted by the most recent call to [visitStatement]. 38 /// Statements emitted by the most recent call to [visitStatement].
35 List<Statement> statementBuffer; 39 List<Statement> statementBuffer;
36 40
37 /// The function currently being emitted. 41 /// The function currently being emitted.
38 FunctionElement functionElement; 42 FunctionElement functionElement;
39 43
40 /// Bookkeeping object needed to synthesize a variable declaration. 44 /// Bookkeeping object needed to synthesize a variable declaration.
41 modelx.VariableList variableList; 45 modelx.VariableList variableList;
42 46
43 /// Input to [visitStatement]. Denotes the statement that will execute next 47 /// Input to [visitStatement]. Denotes the statement that will execute next
44 /// if the statements produced by [visitStatement] complete normally. 48 /// if the statements produced by [visitStatement] complete normally.
45 /// Set to null if control will fall over the end of the method. 49 /// Set to null if control will fall over the end of the method.
46 tree.Statement fallthrough; 50 tree.Statement fallthrough;
47 51
48 /// Labels that could not be eliminated using fallthrough. 52 /// Labels that could not be eliminated using fallthrough.
49 Set<tree.Label> usedLabels; 53 Set<tree.Label> usedLabels;
50 54
51 FunctionExpression emit(FunctionElement element, 55 FunctionExpression emit(FunctionElement element,
52 tree.FunctionDefinition definition) { 56 tree.FunctionDefinition definition) {
53 functionElement = element; 57 functionElement = element;
54 variables = <VariableDeclaration>[]; 58 variables = <VariableDeclaration>[];
55 statementBuffer = <Statement>[]; 59 statementBuffer = <Statement>[];
56 seenVariables = new Set<tree.Variable>(); 60 variableNames = <tree.Variable, String>{};
57 tree.Variable.counter = 0; 61 usedVariableNames = new Set<String>();
58 variableList = new modelx.VariableList(tree.Modifiers.EMPTY); 62 variableList = new modelx.VariableList(tree.Modifiers.EMPTY);
59 fallthrough = null; 63 fallthrough = null;
60 usedLabels = new Set<tree.Label>(); 64 usedLabels = new Set<tree.Label>();
61 65
62 Parameters parameters = emitParameters(definition.parameters); 66 Parameters parameters = emitParameters(definition.parameters);
63 visitStatement(definition.body); 67 visitStatement(definition.body);
64 removeTrailingReturn(); 68 removeTrailingReturn();
65 Statement body = new Block(statementBuffer); 69 Statement body = new Block(statementBuffer);
66 if (variables.length > 0) { 70 if (variables.length > 0) {
67 Statement head = new VariableDeclarations(variables); 71 Statement head = new VariableDeclarations(variables);
68 body = new Block([head, body]); 72 body = new Block([head, body]);
69 } 73 }
70 74
71 FunctionType functionType = element.type; 75 FunctionType functionType = element.type;
72 76
73 variables = null; 77 variables = null;
74 statementBuffer = null; 78 statementBuffer = null;
75 functionElement = null; 79 functionElement = null;
76 variableList = null; 80 variableList = null;
77 seenVariables = null; 81 variableNames = null;
82 usedVariableNames = null;
78 usedLabels = null; 83 usedLabels = null;
79 84
80 return new FunctionExpression( 85 return new FunctionExpression(
81 parameters, 86 parameters,
82 body, 87 body,
83 name: element.name, 88 name: element.name,
84 returnType: emitOptionalType(functionType.returnType)) 89 returnType: emitOptionalType(functionType.returnType))
85 ..element = element; 90 ..element = element;
86 } 91 }
87 92
88 /// Removes a trailing "return null" from [statementBuffer]. 93 /// Removes a trailing "return null" from [statementBuffer].
89 void removeTrailingReturn() { 94 void removeTrailingReturn() {
90 if (statementBuffer.isEmpty) return; 95 if (statementBuffer.isEmpty) return;
91 if (statementBuffer.last is! Return) return; 96 if (statementBuffer.last is! Return) return;
92 Return ret = statementBuffer.last; 97 Return ret = statementBuffer.last;
93 Expression expr = ret.expression; 98 Expression expr = ret.expression;
94 if (expr is Literal && expr.value is dart2js.NullConstant) { 99 if (expr is Literal && expr.value is dart2js.NullConstant) {
95 statementBuffer.removeLast(); 100 statementBuffer.removeLast();
96 } 101 }
97 } 102 }
98 103
99 Parameter emitParameter(tree.Variable param) { 104 Parameter emitParameter(tree.Variable param) {
100 seenVariables.add(param); 105 String name = getVariableName(param);
101 ParameterElement element = param.element; 106 ParameterElement element = param.element;
102 TypeAnnotation type = emitOptionalType(element.type); 107 TypeAnnotation type = emitOptionalType(element.type);
103 return new Parameter(element.name, type:type) 108 return new Parameter(name, type:type)
104 ..element = element; 109 ..element = element;
105 } 110 }
106 111
107 Parameters emitParameters(List<tree.Variable> params) { 112 Parameters emitParameters(List<tree.Variable> params) {
108 return new Parameters(params.map(emitParameter).toList(growable:false)); 113 return new Parameters(params.map(emitParameter).toList(growable:false));
109 } 114 }
110 115
111 /// True if the two expressions are a reference to the same variable. 116 /// True if the two expressions are a reference to the same variable.
112 bool isSameVariable(Expression e1, Expression e2) { 117 bool isSameVariable(Expression e1, Expression e2) {
113 // TODO(asgerf): Using the annotated element isn't the best way to do this 118 // TODO(asgerf): Using the annotated element isn't the best way to do this
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 savedBuffer.add(new LabeledStatement(stmt.label.name, 172 savedBuffer.add(new LabeledStatement(stmt.label.name,
168 new Block(statementBuffer))); 173 new Block(statementBuffer)));
169 } else { 174 } else {
170 savedBuffer.add(new Block(statementBuffer)); 175 savedBuffer.add(new Block(statementBuffer));
171 } 176 }
172 fallthrough = savedFallthrough; 177 fallthrough = savedFallthrough;
173 statementBuffer = savedBuffer; 178 statementBuffer = savedBuffer;
174 visitStatement(stmt.next); 179 visitStatement(stmt.next);
175 } 180 }
176 181
177 void visitAssign(tree.Assign stmt) { 182 /// Generates a name for the given variable and synthesizes an element for it,
178 // Synthesize an element for the variable, if necessary. 183 /// if necessary.
179 if (stmt.variable.element == null) { 184 String getVariableName(tree.Variable variable) {
180 stmt.variable.element = new modelx.VariableElementX( 185 String name = variableNames[variable];
181 stmt.variable.name, 186 if (name != null) {
187 return name;
188 }
189 String prefix = variable.element == null ? 'v' : variable.element.name;
190 int counter = 0;
191 name = variable.element == null ? '$prefix$counter' : variable.element.name;
192 while (!usedVariableNames.add(name)) {
193 ++counter;
194 name = '$prefix$counter';
195 }
196 variableNames[variable] = name;
197
198 // Synthesize an element for the variable
199 if (variable.element == null || name != variable.element.name) {
200 variable.element = new modelx.VariableElementX(
201 name,
182 ElementKind.VARIABLE, 202 ElementKind.VARIABLE,
183 functionElement, 203 functionElement,
184 variableList, 204 variableList,
185 null); 205 null);
186 } 206 }
187 if (seenVariables.add(stmt.variable)) { 207 if (variable.element is! ParameterElement) {
188 variables.add(new VariableDeclaration(stmt.variable.name) 208 variables.add(new VariableDeclaration(name)
189 ..element = stmt.variable.element); 209 ..element = variable.element);
190 } 210 }
211 return name;
212 }
213
214 void visitAssign(tree.Assign stmt) {
215 String name = getVariableName(stmt.variable);
191 statementBuffer.add(new ExpressionStatement(makeAssignment( 216 statementBuffer.add(new ExpressionStatement(makeAssignment(
192 visitVariable(stmt.variable), 217 visitVariable(stmt.variable),
193 visitExpression(stmt.definition)))); 218 visitExpression(stmt.definition))));
194 visitStatement(stmt.next); 219 visitStatement(stmt.next);
195 } 220 }
196 221
197 void visitReturn(tree.Return stmt) { 222 void visitReturn(tree.Return stmt) {
198 Expression inner = visitExpression(stmt.value); 223 Expression inner = visitExpression(stmt.value);
199 statementBuffer.add(new Return(inner)); 224 statementBuffer.add(new Return(inner));
200 } 225 }
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 return new BinaryOperator(visitExpression(exp.left), 437 return new BinaryOperator(visitExpression(exp.left),
413 exp.operator, 438 exp.operator,
414 visitExpression(exp.right)); 439 visitExpression(exp.right));
415 } 440 }
416 441
417 Expression visitNot(tree.Not exp) { 442 Expression visitNot(tree.Not exp) {
418 return new UnaryOperator('!', visitExpression(exp.operand)); 443 return new UnaryOperator('!', visitExpression(exp.operand));
419 } 444 }
420 445
421 Expression visitVariable(tree.Variable exp) { 446 Expression visitVariable(tree.Variable exp) {
422 return new Identifier(exp.name) 447 return new Identifier(getVariableName(exp))
423 ..element = exp.element; 448 ..element = exp.element;
424 } 449 }
425 450
426 TypeAnnotation emitType(DartType type) { 451 TypeAnnotation emitType(DartType type) {
427 if (type is GenericType) { // TODO(asgerf): faster Link.map 452 if (type is GenericType) { // TODO(asgerf): faster Link.map
428 return new TypeAnnotation( 453 return new TypeAnnotation(
429 type.element.name, 454 type.element.name,
430 type.typeArguments.toList(growable:false) 455 type.typeArguments.toList(growable:false)
431 .map(emitType).toList(growable:false)) 456 .map(emitType).toList(growable:false))
432 ..dartType = type; 457 ..dartType = type;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 dart2js.StringConstant nameConstant = constant.fields[0]; 502 dart2js.StringConstant nameConstant = constant.fields[0];
478 String nameString = nameConstant.value.slowToString(); 503 String nameString = nameConstant.value.slowToString();
479 return new LiteralSymbol(nameString); 504 return new LiteralSymbol(nameString);
480 } else { 505 } else {
481 throw "Unsupported constant: $constant"; 506 throw "Unsupported constant: $constant";
482 } 507 }
483 } 508 }
484 } 509 }
485 } 510 }
486 511
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698