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

Side by Side Diff: pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart

Issue 787603003: Generative constructors in the new dart backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years 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
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 backend_ast_emitter; 5 library backend_ast_emitter;
6 6
7 import '../tree_ir/tree_ir_nodes.dart' as tree; 7 import '../tree_ir/tree_ir_nodes.dart' as tree;
8 import 'backend_ast_nodes.dart'; 8 import 'backend_ast_nodes.dart';
9 import '../constants/expressions.dart'; 9 import '../constants/expressions.dart';
10 import '../constants/values.dart'; 10 import '../constants/values.dart';
(...skipping 11 matching lines...) Expand all
22 // TODO(johnniwinther): Split into function/block state. 22 // TODO(johnniwinther): Split into function/block state.
23 class BuilderContext<T> { 23 class BuilderContext<T> {
24 /// Builder context for the enclosing function, or null if the current 24 /// Builder context for the enclosing function, or null if the current
25 /// function is not a local function. 25 /// function is not a local function.
26 BuilderContext<T> _parent; 26 BuilderContext<T> _parent;
27 27
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 final List<VariableDeclaration> variables = <VariableDeclaration>[]; 29 final List<VariableDeclaration> variables = <VariableDeclaration>[];
30 30
31 /// Maps variables to their name. 31 /// Maps variables to their name.
32 final Map<tree.Variable, String> variableNames = <tree.Variable, String>{}; 32 final Map<tree.Variable, String> variableNames;
33 33
34 /// Maps local constants to their name. 34 /// Maps local constants to their name.
35 final Map<VariableElement, String> constantNames = 35 final Map<VariableElement, String> constantNames =
36 <VariableElement, String>{}; 36 <VariableElement, String>{};
37 37
38 /// Variables that have had their declaration created. 38 /// Variables that have had their declaration created.
39 final Set<tree.Variable> declaredVariables = new Set<tree.Variable>(); 39 final Set<tree.Variable> declaredVariables = new Set<tree.Variable>();
40 40
41 /// Variable names that have already been used. Used to avoid name clashes. 41 /// Variable names that have already been used. Used to avoid name clashes.
42 final Set<String> usedVariableNames; 42 final Set<String> usedVariableNames;
43 43
44 /// Statements emitted by the most recent call to [visitStatement]. 44 /// Statements emitted by the most recent call to [visitStatement].
45 List<T> _statementBuffer = <T>[]; 45 List<T> _statementBuffer = <T>[];
46 46
47 /// The element currently being emitted. 47 /// The element currently being emitted.
48 ExecutableElement currentElement; 48 ExecutableElement currentElement;
49 49
50 /// Bookkeeping object needed to synthesize a variable declaration. 50 /// Bookkeeping object needed to synthesize a variable declaration.
51 final modelx.VariableList variableList 51 final modelx.VariableList variableList
52 = new modelx.VariableList(tree.Modifiers.EMPTY); 52 = new modelx.VariableList(tree.Modifiers.EMPTY);
53 53
54 /// Input to [visitStatement]. Denotes the statement that will execute next 54 /// Input to [visitStatement]. Denotes the statement that will execute next
55 /// if the statements produced by [visitStatement] complete normally. 55 /// if the statements produced by [visitStatement] complete normally.
56 /// Set to null if control will fall over the end of the method. 56 /// Set to null if control will fall over the end of the method.
57 tree.Statement fallthrough = null; 57 tree.Statement fallthrough = null;
58 58
59 /// Labels that could not be eliminated using fallthrough. 59 /// Labels that could not be eliminated using fallthrough.
60 final Set<tree.Label> _usedLabels = new Set<tree.Label>(); 60 final Set<tree.Label> _usedLabels = new Set<tree.Label>();
61 61
62 final bool inInitializer;
63
62 /// The first dart_tree statement that is not converted to a variable 64 /// The first dart_tree statement that is not converted to a variable
63 /// initializer. 65 /// initializer.
64 tree.Statement firstStatement; 66 tree.Statement firstStatement;
65 67
66 BuilderContext() : usedVariableNames = new Set<String>(); 68 BuilderContext() : usedVariableNames = new Set<String>(),
69 inInitializer = false,
70 variableNames = <tree.Variable, String>{};
67 71
68 BuilderContext.inner(BuilderContext<T> parent) 72 BuilderContext.inner(BuilderContext<T> parent)
69 : this._parent = parent, 73 : this._parent = parent,
70 usedVariableNames = parent.usedVariableNames; 74 usedVariableNames = parent.usedVariableNames,
75 inInitializer = false,
76 variableNames = <tree.Variable, String>{};
77
78 BuilderContext.initializer(BuilderContext<T> parent)
79 : this._parent = parent,
80 usedVariableNames = parent.usedVariableNames,
81 inInitializer = true,
82 variableNames =
83 new Map<tree.Variable, String>.from(parent.variableNames);
71 84
72 // TODO(johnniwinther): Fully encapsulate handling of parameter, variable 85 // TODO(johnniwinther): Fully encapsulate handling of parameter, variable
73 // and local funciton declarations. 86 // and local funciton declarations.
74 void addDeclaration(tree.Variable variable, [Expression initializer]) { 87 void addDeclaration(tree.Variable variable, [Expression initializer]) {
75 assert(!declaredVariables.contains(variable)); 88 assert(!declaredVariables.contains(variable));
76 String name = getVariableName(variable); 89 String name = getVariableName(variable);
77 VariableDeclaration decl = new VariableDeclaration(name, initializer); 90 VariableDeclaration decl = new VariableDeclaration(name, initializer);
78 decl.element = variable.element; 91 decl.element = variable.element;
79 declaredVariables.add(variable); 92 declaredVariables.add(variable);
80 variables.add(decl); 93 variables.add(decl);
81 } 94 }
82 95
83 /// Generates a name for the given variable and synthesizes an element for it, 96 /// Generates a name for the given variable and synthesizes an element for it,
84 /// if necessary. 97 /// if necessary.
85 String getVariableName(tree.Variable variable) { 98 String getVariableName(tree.Variable variable) {
86 // If the variable belongs to an enclosing function, ask the parent emitter 99 // If the variable belongs to an enclosing function, ask the parent emitter
87 // for the variable name. 100 // for the variable name.
88 if (variable.host != currentElement) { 101 if (!inInitializer && variable.host != currentElement) {
89 return _parent.getVariableName(variable); 102 return _parent.getVariableName(variable);
90 } 103 }
91 104
92 // Get the name if we already have one. 105 // Get the name if we already have one.
93 String name = variableNames[variable]; 106 String name = variableNames[variable];
94 if (name != null) { 107 if (name != null) {
95 return name; 108 return name;
96 } 109 }
97 110
98 // Synthesize a variable name that isn't used elsewhere. 111 // Synthesize a variable name that isn't used elsewhere.
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 /// Translates the dart_tree IR to Dart backend AST. 198 /// Translates the dart_tree IR to Dart backend AST.
186 /// An instance of this class should only be used once; a fresh emitter 199 /// An instance of this class should only be used once; a fresh emitter
187 /// must be created for each function to be emitted. 200 /// must be created for each function to be emitted.
188 class ASTEmitter 201 class ASTEmitter
189 extends tree.Visitor1<dynamic, Expression, BuilderContext<Statement>> { 202 extends tree.Visitor1<dynamic, Expression, BuilderContext<Statement>> {
190 203
191 ExecutableDefinition emit(tree.ExecutableDefinition definition, 204 ExecutableDefinition emit(tree.ExecutableDefinition definition,
192 BuilderContext<Statement> context) { 205 BuilderContext<Statement> context) {
193 if (definition is tree.FieldDefinition) { 206 if (definition is tree.FieldDefinition) {
194 return emitField(definition, context); 207 return emitField(definition, context);
208 } else if (definition is tree.ConstructorDefinition) {
209 return emitConstructor(definition, context);
195 } 210 }
196 assert(definition is tree.FunctionDefinition); 211 assert(definition is tree.FunctionDefinition);
197 return emitFunction(definition, context); 212 return emitFunction(definition, context);
198 } 213 }
199 214
200 FieldDefinition emitField(tree.FieldDefinition definition, 215 FieldDefinition emitField(tree.FieldDefinition definition,
201 BuilderContext<Statement> context) { 216 BuilderContext<Statement> context) {
202 context.currentElement = definition.element; 217 context.currentElement = definition.element;
203 Expression initializer; 218 Expression initializer;
204 if (definition.hasInitializer) { 219 if (definition.hasInitializer) {
(...skipping 27 matching lines...) Expand all
232 return onlyStatement.expression; 247 return onlyStatement.expression;
233 } 248 }
234 } 249 }
235 Statement body = new Block(bodyParts); 250 Statement body = new Block(bodyParts);
236 FunctionExpression function = 251 FunctionExpression function =
237 new FunctionExpression(new Parameters([]), body); 252 new FunctionExpression(new Parameters([]), body);
238 function.element = null; 253 function.element = null;
239 return new CallFunction(function, []); 254 return new CallFunction(function, []);
240 } 255 }
241 256
257 FunctionExpression emitConstructor(tree.ConstructorDefinition definition,
258 BuilderContext<Statement> context) {
259 context.currentElement = definition.element;
260
261 Parameters parameters = emitRootParameters(definition, context);
262
263 // Declare parameters.
264 for (tree.Variable param in definition.parameters) {
265 context.variableNames[param] = param.element.name;
266 context.usedVariableNames.add(param.element.name);
267 context.declaredVariables.add(param);
268 }
269
270 List<Expression> initializers;
271 Statement body;
272
273 if (!definition.isAbstract) {
274 initializers =
275 definition.initializers.map((tree.Initializer initializer) {
276 return visitExpression(initializer, context);
277 }).toList();
278
279 context.firstStatement = definition.body;
280 visitStatement(definition.body, context);
281 context.removeTrailingReturn(_recognizeTrailingReturn);
282
283 // Some of the variable declarations have already been added
284 // if their first assignment could be pulled into the initializer.
285 // Add the remaining variable declarations now.
286 for (tree.Variable variable in context.variableNames.keys) {
287 if (!context.declaredVariables.contains(variable)) {
288 context.addDeclaration(variable);
289 }
290 }
291
292 // Add constant declarations.
293 List<VariableDeclaration> constants = <VariableDeclaration>[];
294 for (ConstDeclaration constDecl in definition.localConstants) {
295 if (!context.constantNames.containsKey(constDecl.element)) {
296 continue; // Discard unused constants declarations.
297 }
298 String name = context.getConstantName(constDecl.element);
299 Expression value = emitConstant(constDecl.expression, context);
300 VariableDeclaration decl = new VariableDeclaration(name, value);
301 decl.element = constDecl.element;
302 constants.add(decl);
303 }
304
305 List<Statement> bodyParts = [];
306 if (constants.length > 0) {
307 bodyParts.add(new VariableDeclarations(constants, isConst: true));
308 }
309 if (context.variables.length > 0) {
310 bodyParts.add(new VariableDeclarations(context.variables));
311 }
312 bodyParts.addAll(context.statements);
313
314 body = new Block(bodyParts);
315
316 }
317 FunctionType functionType = context.currentElement.type;
318
319 return new ConstructorDefinition(
320 parameters,
321 body,
322 initializers,
323 context.currentElement.name, definition.isConst)
324 ..element = context.currentElement;
325 }
326
242 FunctionExpression emitFunction(tree.FunctionDefinition definition, 327 FunctionExpression emitFunction(tree.FunctionDefinition definition,
243 BuilderContext<Statement> context) { 328 BuilderContext<Statement> context) {
244 context.currentElement = definition.element; 329 context.currentElement = definition.element;
245 330
246 Parameters parameters = emitRootParameters(definition, context); 331 Parameters parameters = emitRootParameters(definition, context);
247 332
248 // Declare parameters. 333 // Declare parameters.
249 for (tree.Variable param in definition.parameters) { 334 for (tree.Variable param in definition.parameters) {
250 context.variableNames[param] = param.element.name; 335 context.variableNames[param] = param.element.name;
251 context.usedVariableNames.add(param.element.name); 336 context.usedVariableNames.add(param.element.name);
252 context.declaredVariables.add(param); 337 context.declaredVariables.add(param);
253 } 338 }
254 339
255 Statement body; 340 Statement body;
256 if (definition.isAbstract) { 341 if (definition.isAbstract) {
257 body = new EmptyStatement(); 342 body = new EmptyStatement();
258 } else { 343 } else {
259 context.firstStatement = definition.body; 344 context.firstStatement = definition.body;
260 visitStatement(definition.body, context); 345 visitStatement(definition.body, context);
261 context.removeTrailingReturn((Statement statement) { 346 context.removeTrailingReturn(_recognizeTrailingReturn);
262 if (statement is Return) {
263 Expression expr = statement.expression;
264 if (expr is Literal && expr.value.isNull) {
265 return true;
266 }
267 }
268 return false;
269 });
270 347
271 // Some of the variable declarations have already been added 348 // Some of the variable declarations have already been added
272 // if their first assignment could be pulled into the initializer. 349 // if their first assignment could be pulled into the initializer.
273 // Add the remaining variable declarations now. 350 // Add the remaining variable declarations now.
274 for (tree.Variable variable in context.variableNames.keys) { 351 for (tree.Variable variable in context.variableNames.keys) {
275 if (!context.declaredVariables.contains(variable)) { 352 if (!context.declaredVariables.contains(variable)) {
276 context.addDeclaration(variable); 353 context.addDeclaration(variable);
277 } 354 }
278 } 355 }
279 356
(...skipping 26 matching lines...) Expand all
306 return new FunctionExpression( 383 return new FunctionExpression(
307 parameters, 384 parameters,
308 body, 385 body,
309 name: context.currentElement.name, 386 name: context.currentElement.name,
310 returnType: emitOptionalType(functionType.returnType), 387 returnType: emitOptionalType(functionType.returnType),
311 isGetter: context.currentElement.isGetter, 388 isGetter: context.currentElement.isGetter,
312 isSetter: context.currentElement.isSetter) 389 isSetter: context.currentElement.isSetter)
313 ..element = context.currentElement; 390 ..element = context.currentElement;
314 } 391 }
315 392
393 bool _recognizeTrailingReturn(Statement statement) {
394 if (statement is Return) {
395 Expression expr = statement.expression;
396 if (expr == null || expr is Literal && expr.value.isNull) {
397 return true;
398 }
399 }
400 return false;
401 }
402
316 /// TODO(johnniwinther): Remove this when issue 21283 has been resolved. 403 /// TODO(johnniwinther): Remove this when issue 21283 has been resolved.
317 int pseudoNameCounter = 0; 404 int pseudoNameCounter = 0;
318 405
319 Parameter emitParameter(DartType type, 406 Parameter emitParameter(DartType type,
320 BuilderContext<Statement> context, 407 BuilderContext<Statement> context,
321 {String name, 408 {String name,
322 Element element, 409 Element element,
323 ConstantExpression defaultValue}) { 410 ConstantExpression defaultValue}) {
324 if (name == null && element != null) { 411 if (name == null && element != null) {
325 name = element.name; 412 name = element.name;
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 616
530 context.addStatement(new ExpressionStatement(makeAssignment( 617 context.addStatement(new ExpressionStatement(makeAssignment(
531 visitVariable(stmt.variable, context), 618 visitVariable(stmt.variable, context),
532 definition))); 619 definition)));
533 visitStatement(stmt.next, context); 620 visitStatement(stmt.next, context);
534 } 621 }
535 622
536 @override 623 @override
537 void visitReturn(tree.Return stmt, 624 void visitReturn(tree.Return stmt,
538 BuilderContext<Statement> context) { 625 BuilderContext<Statement> context) {
539 Expression inner = visitExpression(stmt.value, context); 626 if (context.currentElement.isGenerativeConstructor &&
540 context.addStatement(new Return(inner)); 627 !context.inInitializer) {
628 assert(() {
629 tree.Expression value = stmt.value;
630 return value is tree.Constant && value.value.isNull;
631 });
632 context.addStatement(new Return(null));
633 } else {
634 Expression inner = visitExpression(stmt.value, context);
635 context.addStatement(new Return(inner));
636 }
541 } 637 }
542 638
543 @override 639 @override
544 void visitBreak(tree.Break stmt, 640 void visitBreak(tree.Break stmt,
545 BuilderContext<Statement> context) { 641 BuilderContext<Statement> context) {
546 tree.Statement fall = context.fallthrough; 642 tree.Statement fall = context.fallthrough;
547 if (stmt.target.binding.next == fall) { 643 if (stmt.target.binding.next == fall) {
548 // Fall through to break target 644 // Fall through to break target
549 } else if (fall is tree.Break && fall.target == stmt.target) { 645 } else if (fall is tree.Break && fall.target == stmt.target) {
550 // Fall through to equivalent break 646 // Fall through to equivalent break
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 } 740 }
645 741
646 @override 742 @override
647 Expression visitTypeOperator(tree.TypeOperator exp, 743 Expression visitTypeOperator(tree.TypeOperator exp,
648 BuilderContext<Statement> context) { 744 BuilderContext<Statement> context) {
649 return new TypeOperator(visitExpression(exp.receiver, context), 745 return new TypeOperator(visitExpression(exp.receiver, context),
650 exp.operator, 746 exp.operator,
651 createTypeAnnotation(exp.type)); 747 createTypeAnnotation(exp.type));
652 } 748 }
653 749
654 List<Argument> emitArguments(tree.Invoke exp, 750 List<Argument> emitArguments(List<Expression> arguments,
655 BuilderContext<Statement> context) { 751 Selector selector) {
656 List<tree.Expression> args = exp.arguments; 752 int positionalArgumentCount = selector.positionalArgumentCount;
657 int positionalArgumentCount = exp.selector.positionalArgumentCount;
658 List<Argument> result = new List<Argument>.generate(positionalArgumentCount, 753 List<Argument> result = new List<Argument>.generate(positionalArgumentCount,
659 (i) => visitExpression(exp.arguments[i], context)); 754 (i) => arguments[i]);
660 for (int i = 0; i < exp.selector.namedArgumentCount; ++i) { 755 for (int i = 0; i < selector.namedArgumentCount; ++i) {
661 result.add(new NamedArgument(exp.selector.namedArguments[i], 756 result.add(new NamedArgument(selector.namedArguments[i],
662 visitExpression(exp.arguments[positionalArgumentCount + i], context))) ; 757 arguments[positionalArgumentCount + i]));
663 } 758 }
664 return result; 759 return result;
665 } 760 }
666 761
762 List<Expression> visitArgumentList(List<tree.Expression> arguments,
763 BuilderContext context) {
764 return arguments
765 .map((tree.Expression argument) => visitExpression(argument, context))
766 .toList();
767 }
768
667 @override 769 @override
668 Expression visitInvokeStatic(tree.InvokeStatic exp, 770 Expression visitInvokeStatic(tree.InvokeStatic exp,
669 BuilderContext<Statement> context) { 771 BuilderContext<Statement> context) {
670 switch (exp.selector.kind) { 772 switch (exp.selector.kind) {
671 case SelectorKind.GETTER: 773 case SelectorKind.GETTER:
672 return new Identifier(exp.target.name)..element = exp.target; 774 return new Identifier(exp.target.name)..element = exp.target;
673 775
674 case SelectorKind.SETTER: 776 case SelectorKind.SETTER:
675 return new Assignment( 777 return new Assignment(
676 new Identifier(exp.target.name)..element = exp.target, 778 new Identifier(exp.target.name)..element = exp.target,
677 '=', 779 '=',
678 visitExpression(exp.arguments[0], context)); 780 visitExpression(exp.arguments[0], context));
679 781
680 case SelectorKind.CALL: 782 case SelectorKind.CALL:
681 return new CallStatic( 783 return new CallStatic(
682 null, exp.target.name, emitArguments(exp, context)) 784 null, exp.target.name,
683 ..element = exp.target; 785 emitArguments(visitArgumentList(exp.arguments, context),
786 exp.selector))
787 ..element = exp.target;
684 788
685 default: 789 default:
686 throw "Unexpected selector kind: ${exp.selector.kind}"; 790 throw "Unexpected selector kind: ${exp.selector.kind}";
687 } 791 }
688 } 792 }
689 793
690 Expression emitMethodCall(tree.Invoke exp, Receiver receiver, 794 Expression emitMethodCall(tree.Invoke exp, Receiver receiver,
691 BuilderContext<Statement> context) { 795 BuilderContext<Statement> context) {
692 List<Argument> args = emitArguments(exp, context); 796 List<Argument> args =
797 emitArguments(visitArgumentList(exp.arguments, context), exp.selector);
693 switch (exp.selector.kind) { 798 switch (exp.selector.kind) {
694 case SelectorKind.CALL: 799 case SelectorKind.CALL:
695 if (exp.selector.name == "call") { 800 if (exp.selector.name == "call") {
696 return new CallFunction(receiver, args); 801 return new CallFunction(receiver, args);
697 } 802 }
698 return new CallMethod(receiver, exp.selector.name, args); 803 return new CallMethod(receiver, exp.selector.name, args);
699 804
700 case SelectorKind.OPERATOR: 805 case SelectorKind.OPERATOR:
701 if (args.length == 0) { 806 if (args.length == 0) {
702 String name = exp.selector.name; 807 String name = exp.selector.name;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 841
737 @override 842 @override
738 Expression visitInvokeSuperMethod(tree.InvokeSuperMethod exp, 843 Expression visitInvokeSuperMethod(tree.InvokeSuperMethod exp,
739 BuilderContext<Statement> context) { 844 BuilderContext<Statement> context) {
740 return emitMethodCall(exp, new SuperReceiver(), context); 845 return emitMethodCall(exp, new SuperReceiver(), context);
741 } 846 }
742 847
743 @override 848 @override
744 Expression visitInvokeConstructor(tree.InvokeConstructor exp, 849 Expression visitInvokeConstructor(tree.InvokeConstructor exp,
745 BuilderContext<Statement> context) { 850 BuilderContext<Statement> context) {
746 List args = emitArguments(exp, context); 851 List<Argument> args =
852 emitArguments(visitArgumentList(exp.arguments, context), exp.selector);
747 FunctionElement constructor = exp.target; 853 FunctionElement constructor = exp.target;
748 String name = constructor.name.isEmpty ? null : constructor.name; 854 String name = constructor.name.isEmpty ? null : constructor.name;
749 return new CallNew(createTypeAnnotation(exp.type), 855 return new CallNew(createTypeAnnotation(exp.type),
750 args, 856 args,
751 constructorName: name, 857 constructorName: name,
752 isConst: exp.constant != null) 858 isConst: exp.constant != null)
753 ..constructor = constructor 859 ..constructor = constructor
754 ..dartType = exp.type; 860 ..dartType = exp.type;
755 } 861 }
756 862
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 FunctionDeclaration decl = new FunctionDeclaration(inner); 917 FunctionDeclaration decl = new FunctionDeclaration(inner);
812 context.declaredVariables.add(node.variable); 918 context.declaredVariables.add(node.variable);
813 context.addStatement(decl); 919 context.addStatement(decl);
814 visitStatement(node.next, context); 920 visitStatement(node.next, context);
815 } 921 }
816 922
817 Expression emitConstant(ConstantExpression exp, 923 Expression emitConstant(ConstantExpression exp,
818 BuilderContext<Statement> context) { 924 BuilderContext<Statement> context) {
819 return const ConstantEmitter().visit(exp, context); 925 return const ConstantEmitter().visit(exp, context);
820 } 926 }
927
928 List<Statement> buildInInitializerContext(tree.Statement root,
929 BuilderContext context) {
930 BuilderContext inner = new BuilderContext<Statement>.initializer(context);
931 inner.currentElement = context.currentElement;
932 visitStatement(root, inner);
933 List<Statement> bodyParts;
934 for (tree.Variable variable in inner.variableNames.keys) {
935 if (!context.declaredVariables.contains(variable)) {
936 inner.addDeclaration(variable);
937 }
938 }
939 if (inner.variables.length > 0) {
940 bodyParts = new List<Statement>();
941 bodyParts.add(new VariableDeclarations(inner.variables));
942 bodyParts.addAll(inner.statements);
943 } else {
944 bodyParts = inner.statements;
945 }
946 return bodyParts;
947 }
948
949 @override
950 Expression visitFieldInitializer(tree.FieldInitializer node,
951 BuilderContext<Statement> context) {
952 return new FieldInitializer(node.element,
953 ensureExpression(buildInInitializerContext(node.body, context)));
954 }
955
956 @override
957 Expression visitSuperInitializer(tree.SuperInitializer node,
958 BuilderContext<Statement> context) {
959 List<Argument> arguments = node.arguments.map((tree.Statement argument) {
960 return ensureExpression(buildInInitializerContext(argument, context));
961 }).toList();
962 return new SuperInitializer(node.target,
963 emitArguments(arguments, node.selector));
964 }
821 } 965 }
822 966
823 /// Like [createTypeAnnotation] except the dynamic type is converted to null. 967 /// Like [createTypeAnnotation] except the dynamic type is converted to null.
824 TypeAnnotation emitOptionalType(DartType type) { 968 TypeAnnotation emitOptionalType(DartType type) {
825 if (type.treatAsDynamic) { 969 if (type.treatAsDynamic) {
826 return null; 970 return null;
827 } else { 971 } else {
828 return createTypeAnnotation(type); 972 return createTypeAnnotation(type);
829 } 973 }
830 } 974 }
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1078 : super(name, ElementKind.VARIABLE, enclosingElement, variables, null); 1222 : super(name, ElementKind.VARIABLE, enclosingElement, variables, null);
1079 1223
1080 ExecutableElement get executableContext => enclosingElement; 1224 ExecutableElement get executableContext => enclosingElement;
1081 1225
1082 ExecutableElement get memberContext => executableContext.memberContext; 1226 ExecutableElement get memberContext => executableContext.memberContext;
1083 1227
1084 bool get isLocal => true; 1228 bool get isLocal => true;
1085 1229
1086 LibraryElement get implementationLibrary => enclosingElement.library; 1230 LibraryElement get implementationLibrary => enclosingElement.library;
1087 } 1231 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698