Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 /** | 5 /** |
| 6 * Represents a meta-value for code generation. | 6 * Represents a meta-value for code generation. |
| 7 */ | 7 */ |
| 8 class Value { | 8 class Value { |
| 9 Type _type; | 9 Type _type; |
| 10 | 10 |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 499 names.add('"${args.getName(i)}", ${args.values[i].code}'); | 499 names.add('"${args.getName(i)}", ${args.values[i].code}'); |
| 500 } | 500 } |
| 501 noSuchArgs.add(new Value(world.gen.useMapFactory(), | 501 noSuchArgs.add(new Value(world.gen.useMapFactory(), |
| 502 '\$map(${Strings.join(names, ", ")})')); | 502 '\$map(${Strings.join(names, ", ")})')); |
| 503 }*/ | 503 }*/ |
| 504 | 504 |
| 505 // Finally, invoke noSuchMethod | 505 // Finally, invoke noSuchMethod |
| 506 return _resolveMember(context, 'noSuchMethod', node).invoke( | 506 return _resolveMember(context, 'noSuchMethod', node).invoke( |
| 507 context, node, this, new Arguments(null, noSuchArgs)); | 507 context, node, this, new Arguments(null, noSuchArgs)); |
| 508 } | 508 } |
| 509 | |
| 510 | |
| 511 static Value fromBool(bool value, SourceSpan span) { | |
| 512 return new EvaluatedValue(world.nonNullBool, value, value.toString(), | |
| 513 span); | |
| 514 } | |
| 515 | |
| 516 static Value fromInt(int value, SourceSpan span) { | |
| 517 final strValue = value.toString(); | |
| 518 assert(strValue.indexOf('.') == -1); | |
| 519 return new EvaluatedValue(world.numType, value, strValue, span); | |
| 520 } | |
| 521 | |
| 522 static Value fromDouble(double value, SourceSpan span) { | |
| 523 var strValue = value.toString(); | |
| 524 // Ensure that string version looks different from int | |
| 525 if (strValue.indexOf('.') == -1 && strValue.indexOf('e') == -1) { | |
| 526 strValue = strValue + '.0'; | |
| 527 } | |
| 528 return new EvaluatedValue(world.numType, value, strValue, span); | |
| 529 } | |
| 530 | |
| 531 static Value fromString(String value, SourceSpan span) { | |
| 532 // TODO(jimhug): This could be much more efficient | |
|
Jennifer Messerly
2012/01/09 20:16:26
one thing that might help: we could change StringB
jimhug
2012/01/09 21:19:05
Good thought. Let me know what you learn!
On 2012
| |
| 533 StringBuffer buf = new StringBuffer(); | |
| 534 buf.add('"'); | |
| 535 for (int i=0; i < value.length; i++) { | |
| 536 var ch = value.charCodeAt(i); | |
| 537 switch (ch) { | |
| 538 case 9/*'\t'*/: buf.add(@'\t'); break; | |
| 539 case 10/*'\n'*/: buf.add(@'\n'); break; | |
| 540 case 13/*'\r'*/: buf.add(@'\r'); break; | |
| 541 case 34/*"*/: buf.add(@'\"'); break; | |
| 542 case 92/*\*/: buf.add(@'\\'); break; | |
| 543 default: | |
| 544 if (ch >= 32 && ch <= 126) { | |
| 545 buf.add(value[i]); | |
| 546 } else { | |
| 547 final hex = ch.toRadixString(16); | |
| 548 switch (hex.length) { | |
| 549 case 1: buf.add(@'\x0'); buf.add(hex); break; | |
| 550 case 2: buf.add(@'\x'); buf.add(hex); break; | |
| 551 case 3: buf.add(@'\u0'); buf.add(hex); break; | |
| 552 case 4: buf.add(@'\u'); buf.add(hex); break; | |
| 553 default: | |
| 554 world.internalError( | |
| 555 'unicode values greater than 2 bytes not implemented'); | |
| 556 break; | |
| 557 } | |
| 558 } | |
| 559 break; | |
| 560 } | |
| 561 } | |
| 562 buf.add('"'); | |
| 563 | |
| 564 return new EvaluatedValue(world.stringType, value, buf.toString(), span); | |
| 565 } | |
| 566 | |
| 567 static Value fromNull(SourceSpan span) { | |
| 568 return new EvaluatedValue(world.varType, null, 'null', span); | |
| 569 } | |
| 509 } | 570 } |
| 510 | 571 |
| 572 | |
| 511 // TODO(jmesserly): the subtypes of Value require a lot of type checks and | 573 // TODO(jmesserly): the subtypes of Value require a lot of type checks and |
| 512 // downcasts to use; can we make that cleaner? (search for ".dynamic") | 574 // downcasts to use; can we make that cleaner? (search for ".dynamic") |
| 513 | 575 |
| 514 /** A value that can has been evaluated statically. */ | 576 /** A value that can has been evaluated statically. */ |
| 515 class EvaluatedValue extends Value { | 577 class EvaluatedValue extends Value { |
| 516 | 578 |
| 517 var actualValue; | 579 var actualValue; |
| 518 | 580 |
| 519 bool get isConst() => true; | 581 bool get isConst() => true; |
| 520 | 582 |
| 521 EvaluatedValue get constValue() => this; | 583 EvaluatedValue get constValue() => this; |
| 522 | 584 |
| 523 /** | 585 /** |
| 524 * A canonicalized form of the code. Two const expressions that result in the | 586 * A canonicalized form of the code. Two const expressions that result in the |
| 525 * same instance should have the same [canonicalCode]. | 587 * same instance should have the same [canonicalCode]. |
| 526 */ | 588 */ |
| 527 String canonicalCode; | 589 String canonicalCode; |
| 528 | 590 |
| 529 factory EvaluatedValue(Type type, actualValue, String canonicalCode, | 591 factory EvaluatedValue(Type type, actualValue, String canonicalCode, |
| 530 SourceSpan span) { | 592 SourceSpan span) { |
| 531 return new EvaluatedValue._internal(type, actualValue, | 593 return new EvaluatedValue._internal(type, actualValue, |
| 532 canonicalCode, span, codeWithComments(canonicalCode, span)); | 594 canonicalCode, span, codeWithComments(canonicalCode, span)); |
| 533 } | 595 } |
| 534 | 596 |
| 535 EvaluatedValue._internal(Type type, this.actualValue, this.canonicalCode, | 597 EvaluatedValue._internal(Type type, this.actualValue, this.canonicalCode, |
| 536 SourceSpan span, String code) | 598 SourceSpan span, String code) |
| 537 : super(type, code, span, false); | 599 : super(type, code, span, false); |
| 538 | 600 |
| 539 static String codeWithComments(String canonicalCode, SourceSpan span) { | 601 static String codeWithComments(String canonicalCode, SourceSpan span) { |
| 540 return (span != null && span.text != canonicalCode) | 602 return canonicalCode; |
|
Jennifer Messerly
2012/01/09 20:16:26
nice simplification
| |
| 541 ? '$canonicalCode/*${_escapeForComment(span.text)}*/' : canonicalCode; | |
| 542 } | 603 } |
| 543 } | 604 } |
| 544 | 605 |
| 545 /** An evaluated constant list expression. */ | 606 /** An evaluated constant list expression. */ |
| 546 class ConstListValue extends EvaluatedValue { | 607 class ConstListValue extends EvaluatedValue { |
| 547 List<EvaluatedValue> values; | 608 List<EvaluatedValue> values; |
| 548 | 609 |
| 549 factory ConstListValue(Type type, List<EvaluatedValue> values, | 610 factory ConstListValue(Type type, List<EvaluatedValue> values, |
| 550 String actualValue, String canonicalCode, SourceSpan span) { | 611 String actualValue, String canonicalCode, SourceSpan span) { |
| 551 return new ConstListValue._internal(type, values, actualValue, | 612 return new ConstListValue._internal(type, values, actualValue, |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 738 } | 799 } |
| 739 | 800 |
| 740 _ensureCode(); | 801 _ensureCode(); |
| 741 return null; | 802 return null; |
| 742 } | 803 } |
| 743 } | 804 } |
| 744 | 805 |
| 745 String _escapeForComment(String text) { | 806 String _escapeForComment(String text) { |
| 746 return text.replaceAll('/*', '/ *').replaceAll('*/', '* /'); | 807 return text.replaceAll('/*', '/ *').replaceAll('*/', '* /'); |
| 747 } | 808 } |
| OLD | NEW |