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 dart2js.ir_nodes_sexpr; | 5 library dart2js.ir_nodes_sexpr; |
6 | 6 |
7 import '../constants/values.dart'; | 7 import '../constants/values.dart'; |
8 import '../util/util.dart'; | 8 import '../util/util.dart'; |
9 import 'cps_ir_nodes.dart'; | 9 import 'cps_ir_nodes.dart'; |
| 10 import '../universe/universe.dart' show Selector, CallStructure; |
10 | 11 |
11 /// A [Decorator] is a function used by [SExpressionStringifier] to augment the | 12 /// A [Decorator] is a function used by [SExpressionStringifier] to augment the |
12 /// output produced for a node or reference. It can be provided to the | 13 /// output produced for a node or reference. It can be provided to the |
13 /// constructor. | 14 /// constructor. |
14 typedef String Decorator(node, String s); | 15 typedef String Decorator(node, String s); |
15 | 16 |
16 /// Generate a Lisp-like S-expression representation of an IR node as a string. | 17 /// Generate a Lisp-like S-expression representation of an IR node as a string. |
17 class SExpressionStringifier extends Indentation implements Visitor<String> { | 18 class SExpressionStringifier extends Indentation implements Visitor<String> { |
18 final _Namer namer = new _Namer(); | 19 final _Namer namer = new _Namer(); |
19 | 20 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 return '$indentation(LetHandler (($parameters)\n$handlerBody)\n$body)'; | 109 return '$indentation(LetHandler (($parameters)\n$handlerBody)\n$body)'; |
109 } | 110 } |
110 | 111 |
111 String visitLetMutable(LetMutable node) { | 112 String visitLetMutable(LetMutable node) { |
112 String name = visit(node.variable); | 113 String name = visit(node.variable); |
113 String value = access(node.value); | 114 String value = access(node.value); |
114 String body = indentBlock(() => visit(node.body)); | 115 String body = indentBlock(() => visit(node.body)); |
115 return '$indentation(LetMutable ($name $value)\n$body)'; | 116 return '$indentation(LetMutable ($name $value)\n$body)'; |
116 } | 117 } |
117 | 118 |
118 String formatArguments(Invoke node) { | 119 String formatArguments(CallStructure call, |
119 int positionalArgumentCount = node.selector.positionalArgumentCount; | 120 List<Reference<Primitive>> arguments) { |
| 121 int positionalArgumentCount = call.positionalArgumentCount; |
120 List<String> args = new List<String>(); | 122 List<String> args = new List<String>(); |
121 args.addAll( | 123 args.addAll(arguments.getRange(0, positionalArgumentCount).map(access)); |
122 node.arguments.getRange(0, positionalArgumentCount).map(access)); | 124 List<String> argumentNames = call.getOrderedNamedArguments(); |
123 for (int i = 0; i < node.selector.namedArgumentCount; ++i) { | 125 for (int i = 0; i < argumentNames.length; ++i) { |
124 String name = node.selector.namedArguments[i]; | 126 String name = argumentNames[i]; |
125 String arg = access(node.arguments[positionalArgumentCount + i]); | 127 String arg = access(arguments[positionalArgumentCount + i]); |
126 args.add("($name: $arg)"); | 128 args.add("($name: $arg)"); |
127 } | 129 } |
128 return '(${args.join(' ')})'; | 130 return '(${args.join(' ')})'; |
129 } | 131 } |
130 | 132 |
131 String visitInvokeStatic(InvokeStatic node) { | 133 String visitInvokeStatic(InvokeStatic node) { |
132 String name = node.target.name; | 134 String name = node.target.name; |
133 String cont = access(node.continuation); | 135 String cont = access(node.continuation); |
134 String args = formatArguments(node); | 136 String args = formatArguments(node.selector.callStructure, node.arguments); |
135 return '$indentation(InvokeStatic $name $args $cont)'; | 137 return '$indentation(InvokeStatic $name $args $cont)'; |
136 } | 138 } |
137 | 139 |
138 String visitInvokeMethod(InvokeMethod node) { | 140 String visitInvokeMethod(InvokeMethod node) { |
139 String name = node.selector.name; | 141 String name = node.selector.name; |
140 String rcv = access(node.receiver); | 142 String rcv = access(node.receiver); |
141 String cont = access(node.continuation); | 143 String cont = access(node.continuation); |
142 String args = formatArguments(node); | 144 String args = formatArguments(node.selector.callStructure, node.arguments); |
143 return '$indentation(InvokeMethod $rcv $name $args $cont)'; | 145 return '$indentation(InvokeMethod $rcv $name $args $cont)'; |
144 } | 146 } |
145 | 147 |
146 String visitInvokeMethodDirectly(InvokeMethodDirectly node) { | 148 String visitInvokeMethodDirectly(InvokeMethodDirectly node) { |
147 String receiver = access(node.receiver); | 149 String receiver = access(node.receiver); |
148 String name = node.selector.name; | 150 String name = node.selector.name; |
149 String cont = access(node.continuation); | 151 String cont = access(node.continuation); |
150 String args = formatArguments(node); | 152 String args = formatArguments(node.selector.callStructure, node.arguments); |
151 return '$indentation(InvokeMethodDirectly $receiver $name $args $cont)'; | 153 return '$indentation(InvokeMethodDirectly $receiver $name $args $cont)'; |
152 } | 154 } |
153 | 155 |
154 String visitInvokeConstructor(InvokeConstructor node) { | 156 String visitInvokeConstructor(InvokeConstructor node) { |
155 String className; | 157 String className; |
156 // TODO(karlklose): for illegal nodes constructed for tests or unresolved | 158 // TODO(karlklose): for illegal nodes constructed for tests or unresolved |
157 // constructor calls in the DartBackend, we get an element with no enclosing | 159 // constructor calls in the DartBackend, we get an element with no enclosing |
158 // class. Clean this up by introducing a name field to the node and | 160 // class. Clean this up by introducing a name field to the node and |
159 // removing [ErroneousElement]s from the IR. | 161 // removing [ErroneousElement]s from the IR. |
160 if (node.type != null) { | 162 if (node.type != null) { |
161 className = node.type.toString(); | 163 className = node.type.toString(); |
162 } else { | 164 } else { |
163 className = node.target.enclosingClass.name; | 165 className = node.target.enclosingClass.name; |
164 } | 166 } |
165 String callName; | 167 String callName; |
166 if (node.target.name.isEmpty) { | 168 if (node.target.name.isEmpty) { |
167 callName = '${className}'; | 169 callName = '${className}'; |
168 } else { | 170 } else { |
169 callName = '${className}.${node.target.name}'; | 171 callName = '${className}.${node.target.name}'; |
170 } | 172 } |
171 String cont = access(node.continuation); | 173 String cont = access(node.continuation); |
172 String args = formatArguments(node); | 174 String args = formatArguments(node.selector.callStructure, node.arguments); |
173 return '$indentation(InvokeConstructor $callName $args $cont)'; | 175 return '$indentation(InvokeConstructor $callName $args $cont)'; |
174 } | 176 } |
175 | 177 |
176 String visitInvokeContinuation(InvokeContinuation node) { | 178 String visitInvokeContinuation(InvokeContinuation node) { |
177 String name = access(node.continuation); | 179 String name = access(node.continuation); |
178 if (node.isRecursive) name = 'rec $name'; | 180 if (node.isRecursive) name = 'rec $name'; |
179 String args = node.arguments.map(access).join(' '); | 181 String args = node.arguments.map(access).join(' '); |
180 return '$indentation(InvokeContinuation $name ($args))'; | 182 return '$indentation(InvokeContinuation $name ($args))'; |
181 } | 183 } |
182 | 184 |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 void setReturnContinuation(Continuation node) { | 470 void setReturnContinuation(Continuation node) { |
469 assert(!_names.containsKey(node) || _names[node] == 'return'); | 471 assert(!_names.containsKey(node) || _names[node] == 'return'); |
470 _names[node] = 'return'; | 472 _names[node] = 'return'; |
471 } | 473 } |
472 | 474 |
473 String getName(Node node) { | 475 String getName(Node node) { |
474 if (!_names.containsKey(node)) return 'MISSING_NAME'; | 476 if (!_names.containsKey(node)) return 'MISSING_NAME'; |
475 return _names[node]; | 477 return _names[node]; |
476 } | 478 } |
477 } | 479 } |
OLD | NEW |