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

Side by Side Diff: pkg/compiler/lib/src/constants/expressions.dart

Issue 716913005: Replace ResolvedNode by ConstantExpression. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add unittest Created 6 years, 1 month 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 dart2js.constants.expressions; 5 library dart2js.constants.expressions;
6 6
7 import '../dart2jslib.dart' show assertDebugMode; 7 import '../dart2jslib.dart' show assertDebugMode;
8 import '../dart_types.dart'; 8 import '../dart_types.dart';
9 import '../elements/elements.dart' show 9 import '../elements/elements.dart' show
10 Element, 10 Element,
(...skipping 12 matching lines...) Expand all
23 /// For instance, multiple `const` constructors may be used to create the same 23 /// For instance, multiple `const` constructors may be used to create the same
24 /// object, and different `const` variables may hold the same value. 24 /// object, and different `const` variables may hold the same value.
25 abstract class ConstantExpression { 25 abstract class ConstantExpression {
26 /// Returns the value of this constant expression. 26 /// Returns the value of this constant expression.
27 ConstantValue get value; 27 ConstantValue get value;
28 28
29 // TODO(johnniwinther): Unify precedence handled between constants, front-end 29 // TODO(johnniwinther): Unify precedence handled between constants, front-end
30 // and back-end. 30 // and back-end.
31 int get precedence => 16; 31 int get precedence => 16;
32 32
33 accept(ConstantExpressionVisitor visitor); 33 accept(ConstantExpressionVisitor visitor, [context]);
34 34
35 String getText() { 35 String getText() {
36 ConstExpPrinter printer = new ConstExpPrinter(); 36 ConstExpPrinter printer = new ConstExpPrinter();
37 accept(printer); 37 accept(printer);
38 return printer.toString(); 38 return printer.toString();
39 } 39 }
40 40
41 String toString() { 41 String toString() {
42 assertDebugMode('Use ConstantExpression.getText() instead of ' 42 assertDebugMode('Use ConstantExpression.getText() instead of '
43 'ConstantExpression.toString()'); 43 'ConstantExpression.toString()');
44 return getText(); 44 return getText();
45 } 45 }
46 } 46 }
47 47
48 /// Boolean, int, double, string, or null constant. 48 /// Boolean, int, double, string, or null constant.
49 class PrimitiveConstantExpression extends ConstantExpression { 49 class PrimitiveConstantExpression extends ConstantExpression {
50 final PrimitiveConstantValue value; 50 final PrimitiveConstantValue value;
51 51
52 PrimitiveConstantExpression(this.value) { 52 PrimitiveConstantExpression(this.value) {
53 assert(value != null); 53 assert(value != null);
54 } 54 }
55 55
56 accept(ConstantExpressionVisitor visitor) => visitor.visitPrimitive(this); 56 accept(ConstantExpressionVisitor visitor, [context]) {
57 return visitor.visitPrimitive(this, context);
58 }
57 } 59 }
58 60
59 /// Literal list constant. 61 /// Literal list constant.
60 class ListConstantExpression extends ConstantExpression { 62 class ListConstantExpression extends ConstantExpression {
61 final ListConstantValue value; 63 final ListConstantValue value;
62 final InterfaceType type; 64 final InterfaceType type;
63 final List<ConstantExpression> values; 65 final List<ConstantExpression> values;
64 66
65 ListConstantExpression(this.value, this.type, this.values); 67 ListConstantExpression(this.value, this.type, this.values);
66 68
67 accept(ConstantExpressionVisitor visitor) => visitor.visitList(this); 69 accept(ConstantExpressionVisitor visitor, [context]) {
70 return visitor.visitList(this, context);
71 }
68 } 72 }
69 73
70 /// Literal map constant. 74 /// Literal map constant.
71 class MapConstantExpression extends ConstantExpression { 75 class MapConstantExpression extends ConstantExpression {
72 final MapConstantValue value; 76 final MapConstantValue value;
73 final InterfaceType type; 77 final InterfaceType type;
74 final List<ConstantExpression> keys; 78 final List<ConstantExpression> keys;
75 final List<ConstantExpression> values; 79 final List<ConstantExpression> values;
76 80
77 MapConstantExpression(this.value, this.type, this.keys, this.values); 81 MapConstantExpression(this.value, this.type, this.keys, this.values);
78 82
79 accept(ConstantExpressionVisitor visitor) => visitor.visitMap(this); 83 accept(ConstantExpressionVisitor visitor, [context]) {
84 return visitor.visitMap(this, context);
85 }
80 } 86 }
81 87
82 /// Invocation of a const constructor. 88 /// Invocation of a const constructor.
83 class ConstructedConstantExpresssion extends ConstantExpression { 89 class ConstructedConstantExpresssion extends ConstantExpression {
84 final ConstantValue value; 90 final ConstantValue value;
85 final InterfaceType type; 91 final InterfaceType type;
86 final FunctionElement target; 92 final FunctionElement target;
87 final Selector selector; 93 final Selector selector;
88 final List<ConstantExpression> arguments; 94 final List<ConstantExpression> arguments;
89 95
90 ConstructedConstantExpresssion(this.value, 96 ConstructedConstantExpresssion(this.value,
91 this.type, 97 this.type,
92 this.target, 98 this.target,
93 this.selector, 99 this.selector,
94 this.arguments) { 100 this.arguments) {
95 assert(type.element == target.enclosingClass); 101 assert(type.element == target.enclosingClass);
96 } 102 }
97 103
98 accept(ConstantExpressionVisitor visitor) => visitor.visitConstructor(this); 104 accept(ConstantExpressionVisitor visitor, [context]) {
105 return visitor.visitConstructed(this, context);
106 }
99 } 107 }
100 108
101 /// String literal with juxtaposition and/or interpolations. 109 /// String literal with juxtaposition and/or interpolations.
102 // TODO(johnniwinther): Do we need this? 110 // TODO(johnniwinther): Do we need this?
103 class ConcatenateConstantExpression extends ConstantExpression { 111 class ConcatenateConstantExpression extends ConstantExpression {
104 final StringConstantValue value; 112 final StringConstantValue value;
105 final List<ConstantExpression> arguments; 113 final List<ConstantExpression> arguments;
106 114
107 ConcatenateConstantExpression(this.value, this.arguments); 115 ConcatenateConstantExpression(this.value, this.arguments);
108 116
109 accept(ConstantExpressionVisitor visitor) => visitor.visitConcatenate(this); 117 accept(ConstantExpressionVisitor visitor, [context]) {
118 return visitor.visitConcatenate(this, context);
119 }
110 } 120 }
111 121
112 /// Symbol literal. 122 /// Symbol literal.
113 class SymbolConstantExpression extends ConstantExpression { 123 class SymbolConstantExpression extends ConstantExpression {
114 final ConstructedConstantValue value; 124 final ConstructedConstantValue value;
115 final String name; 125 final String name;
116 126
117 SymbolConstantExpression(this.value, this.name); 127 SymbolConstantExpression(this.value, this.name);
118 128
119 accept(ConstantExpressionVisitor visitor) => visitor.visitSymbol(this); 129 accept(ConstantExpressionVisitor visitor, [context]) {
130 return visitor.visitSymbol(this, context);
131 }
120 } 132 }
121 133
122 /// Type literal. 134 /// Type literal.
123 class TypeConstantExpression extends ConstantExpression { 135 class TypeConstantExpression extends ConstantExpression {
124 final TypeConstantValue value; 136 final TypeConstantValue value;
125 /// Either [DynamicType] or a raw [GenericType]. 137 /// Either [DynamicType] or a raw [GenericType].
126 final DartType type; 138 final DartType type;
127 139
128 TypeConstantExpression(this.value, this.type) { 140 TypeConstantExpression(this.value, this.type) {
129 assert(type is GenericType || type is DynamicType); 141 assert(type is GenericType || type is DynamicType);
130 } 142 }
131 143
132 accept(ConstantExpressionVisitor visitor) => visitor.visitType(this); 144 accept(ConstantExpressionVisitor visitor, [context]) {
145 return visitor.visitType(this, context);
146 }
133 } 147 }
134 148
135 /// Reference to a constant local, top-level, or static variable. 149 /// Reference to a constant local, top-level, or static variable.
136 class VariableConstantExpression extends ConstantExpression { 150 class VariableConstantExpression extends ConstantExpression {
137 final ConstantValue value; 151 final ConstantValue value;
138 final VariableElement element; 152 final VariableElement element;
139 153
140 VariableConstantExpression(this.value, this.element); 154 VariableConstantExpression(this.value, this.element);
141 155
142 accept(ConstantExpressionVisitor visitor) => visitor.visitVariable(this); 156 accept(ConstantExpressionVisitor visitor, [context]) {
157 return visitor.visitVariable(this, context);
158 }
143 } 159 }
144 160
145 /// Reference to a top-level or static function. 161 /// Reference to a top-level or static function.
146 class FunctionConstantExpression extends ConstantExpression { 162 class FunctionConstantExpression extends ConstantExpression {
147 final FunctionConstantValue value; 163 final FunctionConstantValue value;
148 final FunctionElement element; 164 final FunctionElement element;
149 165
150 FunctionConstantExpression(this.value, this.element); 166 FunctionConstantExpression(this.value, this.element);
151 167
152 accept(ConstantExpressionVisitor visitor) => visitor.visitFunction(this); 168 accept(ConstantExpressionVisitor visitor, [context]) {
169 return visitor.visitFunction(this, context);
170 }
153 } 171 }
154 172
155 /// A constant binary expression like `a * b` or `identical(a, b)`. 173 /// A constant binary expression like `a * b` or `identical(a, b)`.
156 class BinaryConstantExpression extends ConstantExpression { 174 class BinaryConstantExpression extends ConstantExpression {
157 final ConstantValue value; 175 final ConstantValue value;
158 final ConstantExpression left; 176 final ConstantExpression left;
159 final String operator; 177 final String operator;
160 final ConstantExpression right; 178 final ConstantExpression right;
161 179
162 BinaryConstantExpression(this.value, this.left, this.operator, this.right) { 180 BinaryConstantExpression(this.value, this.left, this.operator, this.right) {
163 assert(PRECEDENCE_MAP[operator] != null); 181 assert(PRECEDENCE_MAP[operator] != null);
164 } 182 }
165 183
166 accept(ConstantExpressionVisitor visitor) => visitor.visitBinary(this); 184 accept(ConstantExpressionVisitor visitor, [context]) {
185 return visitor.visitBinary(this, context);
186 }
167 187
168 int get precedence => PRECEDENCE_MAP[operator]; 188 int get precedence => PRECEDENCE_MAP[operator];
169 189
170 static const Map<String, int> PRECEDENCE_MAP = const { 190 static const Map<String, int> PRECEDENCE_MAP = const {
171 'identical': 15, 191 'identical': 15,
172 '==': 6, 192 '==': 6,
173 '!=': 6, 193 '!=': 6,
174 '&&': 5, 194 '&&': 5,
175 '||': 4, 195 '||': 4,
176 '^': 9, 196 '^': 9,
(...skipping 17 matching lines...) Expand all
194 /// A unary constant expression like `-a`. 214 /// A unary constant expression like `-a`.
195 class UnaryConstantExpression extends ConstantExpression { 215 class UnaryConstantExpression extends ConstantExpression {
196 final ConstantValue value; 216 final ConstantValue value;
197 final String operator; 217 final String operator;
198 final ConstantExpression expression; 218 final ConstantExpression expression;
199 219
200 UnaryConstantExpression(this.value, this.operator, this.expression) { 220 UnaryConstantExpression(this.value, this.operator, this.expression) {
201 assert(PRECEDENCE_MAP[operator] != null); 221 assert(PRECEDENCE_MAP[operator] != null);
202 } 222 }
203 223
204 accept(ConstantExpressionVisitor visitor) => visitor.visitUnary(this); 224 accept(ConstantExpressionVisitor visitor, [context]) {
225 return visitor.visitUnary(this, context);
226 }
205 227
206 int get precedence => PRECEDENCE_MAP[operator]; 228 int get precedence => PRECEDENCE_MAP[operator];
207 229
208 static const Map<String, int> PRECEDENCE_MAP = const { 230 static const Map<String, int> PRECEDENCE_MAP = const {
209 '!': 14, 231 '!': 14,
210 '~': 14, 232 '~': 14,
211 '-': 14, 233 '-': 14,
212 }; 234 };
213 } 235 }
214 236
215 /// A constant conditional expression like `a ? b : c`. 237 /// A constant conditional expression like `a ? b : c`.
216 class ConditionalConstantExpression extends ConstantExpression { 238 class ConditionalConstantExpression extends ConstantExpression {
217 final ConstantValue value; 239 final ConstantValue value;
218 final ConstantExpression condition; 240 final ConstantExpression condition;
219 final ConstantExpression trueExp; 241 final ConstantExpression trueExp;
220 final ConstantExpression falseExp; 242 final ConstantExpression falseExp;
221 243
222 ConditionalConstantExpression(this.value, 244 ConditionalConstantExpression(this.value,
223 this.condition, 245 this.condition,
224 this.trueExp, 246 this.trueExp,
225 this.falseExp); 247 this.falseExp);
226 248
227 accept(ConstantExpressionVisitor visitor) => visitor.visitConditional(this); 249 accept(ConstantExpressionVisitor visitor, [context]) {
250 return visitor.visitConditional(this, context);
251 }
228 252
229 int get precedence => 3; 253 int get precedence => 3;
230 } 254 }
231 255
232 abstract class ConstantExpressionVisitor<T> { 256 abstract class ConstantExpressionVisitor<C, R> {
233 T visit(ConstantExpression constant) => constant.accept(this); 257 const ConstantExpressionVisitor();
234 258
235 T visitPrimitive(PrimitiveConstantExpression exp); 259 R visit(ConstantExpression constant, [C context]) {
236 T visitList(ListConstantExpression exp); 260 return constant.accept(this, context);
237 T visitMap(MapConstantExpression exp); 261 }
238 T visitConstructor(ConstructedConstantExpresssion exp); 262
239 T visitConcatenate(ConcatenateConstantExpression exp); 263 R visitPrimitive(PrimitiveConstantExpression exp, [C context]);
240 T visitSymbol(SymbolConstantExpression exp); 264 R visitList(ListConstantExpression exp, [C context]);
241 T visitType(TypeConstantExpression exp); 265 R visitMap(MapConstantExpression exp, [C context]);
242 T visitVariable(VariableConstantExpression exp); 266 R visitConstructed(ConstructedConstantExpresssion exp, [C context]);
243 T visitFunction(FunctionConstantExpression exp); 267 R visitConcatenate(ConcatenateConstantExpression exp, [C context]);
244 T visitBinary(BinaryConstantExpression exp); 268 R visitSymbol(SymbolConstantExpression exp, [C context]);
245 T visitUnary(UnaryConstantExpression exp); 269 R visitType(TypeConstantExpression exp, [C context]);
246 T visitConditional(ConditionalConstantExpression exp); 270 R visitVariable(VariableConstantExpression exp, [C context]);
271 R visitFunction(FunctionConstantExpression exp, [C context]);
272 R visitBinary(BinaryConstantExpression exp, [C context]);
273 R visitUnary(UnaryConstantExpression exp, [C context]);
274 R visitConditional(ConditionalConstantExpression exp, [C context]);
247 } 275 }
248 276
249 /// Represents the declaration of a constant [element] with value [expression]. 277 /// Represents the declaration of a constant [element] with value [expression].
250 // TODO(johnniwinther): Where does this class belong? 278 // TODO(johnniwinther): Where does this class belong?
251 class ConstDeclaration { 279 class ConstDeclaration {
252 final VariableElement element; 280 final VariableElement element;
253 final ConstantExpression expression; 281 final ConstantExpression expression;
254 282
255 ConstDeclaration(this.element, this.expression); 283 ConstDeclaration(this.element, this.expression);
256 } 284 }
257 285
258 class ConstExpPrinter extends ConstantExpressionVisitor { 286 class ConstExpPrinter extends ConstantExpressionVisitor {
sigurdm 2014/11/12 12:10:23 Shouldn't there be type arguments here also?
Johnni Winther 2014/11/13 10:16:42 I prefer not adding type arguments here. It should
259 final StringBuffer sb = new StringBuffer(); 287 final StringBuffer sb = new StringBuffer();
260 288
261 write(ConstantExpression parent, 289 write(ConstantExpression parent,
262 ConstantExpression child, 290 ConstantExpression child,
263 {bool leftAssociative: true}) { 291 {bool leftAssociative: true}) {
264 if (child.precedence < parent.precedence || 292 if (child.precedence < parent.precedence ||
265 !leftAssociative && child.precedence == parent.precedence) { 293 !leftAssociative && child.precedence == parent.precedence) {
266 sb.write('('); 294 sb.write('(');
267 child.accept(this); 295 child.accept(this);
268 sb.write(')'); 296 sb.write(')');
269 } else { 297 } else {
270 child.accept(this); 298 child.accept(this);
271 } 299 }
272 } 300 }
273 301
274 writeTypeArguments(InterfaceType type) { 302 writeTypeArguments(InterfaceType type) {
275 if (type.treatAsRaw) return; 303 if (type.treatAsRaw) return;
276 sb.write('<'); 304 sb.write('<');
277 bool needsComma = false; 305 bool needsComma = false;
278 for (DartType value in type.typeArguments) { 306 for (DartType value in type.typeArguments) {
279 if (needsComma) { 307 if (needsComma) {
280 sb.write(', '); 308 sb.write(', ');
281 } 309 }
282 sb.write(value); 310 sb.write(value);
283 needsComma = true; 311 needsComma = true;
284 } 312 }
285 sb.write('>'); 313 sb.write('>');
286 } 314 }
287 315
288 visitPrimitive(PrimitiveConstantExpression exp) { 316 visitPrimitive(PrimitiveConstantExpression exp, [_]) {
289 sb.write(exp.value.unparse()); 317 sb.write(exp.value.unparse());
290 } 318 }
291 319
292 visitList(ListConstantExpression exp) { 320 visitList(ListConstantExpression exp, [_]) {
293 sb.write('const '); 321 sb.write('const ');
294 writeTypeArguments(exp.type); 322 writeTypeArguments(exp.type);
295 sb.write('['); 323 sb.write('[');
296 bool needsComma = false; 324 bool needsComma = false;
297 for (ConstantExpression value in exp.values) { 325 for (ConstantExpression value in exp.values) {
298 if (needsComma) { 326 if (needsComma) {
299 sb.write(', '); 327 sb.write(', ');
300 } 328 }
301 visit(value); 329 visit(value);
302 needsComma = true; 330 needsComma = true;
303 } 331 }
304 sb.write(']'); 332 sb.write(']');
305 } 333 }
306 334
307 visitMap(MapConstantExpression exp) { 335 visitMap(MapConstantExpression exp, [_]) {
308 sb.write('const '); 336 sb.write('const ');
309 writeTypeArguments(exp.type); 337 writeTypeArguments(exp.type);
310 sb.write('{'); 338 sb.write('{');
311 for (int index = 0; index < exp.keys.length; index++) { 339 for (int index = 0; index < exp.keys.length; index++) {
312 if (index > 0) { 340 if (index > 0) {
313 sb.write(', '); 341 sb.write(', ');
314 } 342 }
315 visit(exp.keys[index]); 343 visit(exp.keys[index]);
316 sb.write(': '); 344 sb.write(': ');
317 visit(exp.values[index]); 345 visit(exp.values[index]);
318 } 346 }
319 sb.write('}'); 347 sb.write('}');
320 } 348 }
321 349
322 visitConstructor(ConstructedConstantExpresssion exp) { 350 visitConstructed(ConstructedConstantExpresssion exp, [_]) {
323 sb.write('const '); 351 sb.write('const ');
324 sb.write(exp.target.enclosingClass.name); 352 sb.write(exp.target.enclosingClass.name);
325 if (exp.target.name != '') { 353 if (exp.target.name != '') {
326 sb.write('.'); 354 sb.write('.');
327 sb.write(exp.target.name); 355 sb.write(exp.target.name);
328 } 356 }
329 writeTypeArguments(exp.type); 357 writeTypeArguments(exp.type);
330 sb.write('('); 358 sb.write('(');
331 bool needsComma = false; 359 bool needsComma = false;
332 360
(...skipping 10 matching lines...) Expand all
343 sb.write(', '); 371 sb.write(', ');
344 } 372 }
345 sb.write(exp.selector.namedArguments[index]); 373 sb.write(exp.selector.namedArguments[index]);
346 sb.write(': '); 374 sb.write(': ');
347 visit(exp.arguments[namedOffset + index]); 375 visit(exp.arguments[namedOffset + index]);
348 needsComma = true; 376 needsComma = true;
349 } 377 }
350 sb.write(')'); 378 sb.write(')');
351 } 379 }
352 380
353 visitConcatenate(ConcatenateConstantExpression exp) { 381 visitConcatenate(ConcatenateConstantExpression exp, [_]) {
354 sb.write(exp.value.unparse()); 382 sb.write(exp.value.unparse());
355 } 383 }
356 384
357 visitSymbol(SymbolConstantExpression exp) { 385 visitSymbol(SymbolConstantExpression exp, [_]) {
358 sb.write('#'); 386 sb.write('#');
359 sb.write(exp.name); 387 sb.write(exp.name);
360 } 388 }
361 389
362 visitType(TypeConstantExpression exp) { 390 visitType(TypeConstantExpression exp, [_]) {
363 sb.write(exp.type.name); 391 sb.write(exp.type.name);
364 } 392 }
365 393
366 visitVariable(VariableConstantExpression exp) { 394 visitVariable(VariableConstantExpression exp, [_]) {
367 if (exp.element.isStatic) { 395 if (exp.element.isStatic) {
368 sb.write(exp.element.enclosingClass.name); 396 sb.write(exp.element.enclosingClass.name);
369 sb.write('.'); 397 sb.write('.');
370 } 398 }
371 sb.write(exp.element.name); 399 sb.write(exp.element.name);
372 } 400 }
373 401
374 visitFunction(FunctionConstantExpression exp) { 402 visitFunction(FunctionConstantExpression exp, [_]) {
375 if (exp.element.isStatic) { 403 if (exp.element.isStatic) {
376 sb.write(exp.element.enclosingClass.name); 404 sb.write(exp.element.enclosingClass.name);
377 sb.write('.'); 405 sb.write('.');
378 } 406 }
379 sb.write(exp.element.name); 407 sb.write(exp.element.name);
380 } 408 }
381 409
382 visitBinary(BinaryConstantExpression exp) { 410 visitBinary(BinaryConstantExpression exp, [_]) {
383 if (exp.operator == 'identical') { 411 if (exp.operator == 'identical') {
384 sb.write('identical('); 412 sb.write('identical(');
385 visit(exp.left); 413 visit(exp.left);
386 sb.write(', '); 414 sb.write(', ');
387 visit(exp.right); 415 visit(exp.right);
388 sb.write(')'); 416 sb.write(')');
389 } else { 417 } else {
390 write(exp, exp.left); 418 write(exp, exp.left);
391 sb.write(' '); 419 sb.write(' ');
392 sb.write(exp.operator); 420 sb.write(exp.operator);
393 sb.write(' '); 421 sb.write(' ');
394 write(exp, exp.right); 422 write(exp, exp.right);
395 } 423 }
396 } 424 }
397 425
398 visitUnary(UnaryConstantExpression exp) { 426 visitUnary(UnaryConstantExpression exp, [_]) {
399 sb.write(exp.operator); 427 sb.write(exp.operator);
400 write(exp, exp.expression); 428 write(exp, exp.expression);
401 } 429 }
402 430
403 visitConditional(ConditionalConstantExpression exp) { 431 visitConditional(ConditionalConstantExpression exp, [_]) {
404 write(exp, exp.condition, leftAssociative: false); 432 write(exp, exp.condition, leftAssociative: false);
405 sb.write(' ? '); 433 sb.write(' ? ');
406 write(exp, exp.trueExp); 434 write(exp, exp.trueExp);
407 sb.write(' : '); 435 sb.write(' : ');
408 write(exp, exp.falseExp); 436 write(exp, exp.falseExp);
409 } 437 }
410 438
411 String toString() => sb.toString(); 439 String toString() => sb.toString();
412 } 440 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart » ('j') | pkg/docgen/test/metadata_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698