| 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 |