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

Side by Side Diff: frog/leg/ssa/nodes.dart

Issue 9190038: Handle escapes in string literals. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 11 months 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) 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 interface HVisitor<R> { 5 interface HVisitor<R> {
6 R visitAdd(HAdd node); 6 R visitAdd(HAdd node);
7 R visitBitAnd(HBitAnd node); 7 R visitBitAnd(HBitAnd node);
8 R visitBitNot(HBitNot node); 8 R visitBitNot(HBitNot node);
9 R visitBitOr(HBitOr node); 9 R visitBitOr(HBitOr node);
10 R visitBitXor(HBitXor node); 10 R visitBitXor(HBitXor node);
(...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 } 1057 }
1058 return HType.UNKNOWN; 1058 return HType.UNKNOWN;
1059 } 1059 }
1060 1060
1061 bool hasExpectedType() => builtinJsName != null; 1061 bool hasExpectedType() => builtinJsName != null;
1062 1062
1063 HInstruction fold() { 1063 HInstruction fold() {
1064 if (name == 'length' && inputs[1].isLiteralString()) { 1064 if (name == 'length' && inputs[1].isLiteralString()) {
1065 // TODO(lrn): Account for escapes in string. Currently we count characters 1065 // TODO(lrn): Account for escapes in string. Currently we count characters
1066 // in the uninterpreted (but unquoted) string. 1066 // in the uninterpreted (but unquoted) string.
1067 QuotedString string = inputs[1].value;
1068 int contentLength = string.contentEnd - string.contentStart;
1069 return new HLiteral(contentLength, HType.INTEGER);
1070 } 1067 }
1071 return this; 1068 return this;
1072 } 1069 }
1073 1070
1074 void prepareGvn() { 1071 void prepareGvn() {
1075 if (builtinJsName == 'length') { 1072 if (builtinJsName == 'length') {
1076 assert(!hasSideEffects()); 1073 assert(!hasSideEffects());
1077 } else { 1074 } else {
1078 setAllSideEffects(); 1075 setAllSideEffects();
1079 } 1076 }
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 bool get isRaw() => (flags & RAW) != 0; 1546 bool get isRaw() => (flags & RAW) != 0;
1550 String get quoteChar() => ((flags & SINGLE_QUOTED) != 0) ? "'" : '"'; 1547 String get quoteChar() => ((flags & SINGLE_QUOTED) != 0) ? "'" : '"';
1551 1548
1552 int get contentStart() => 1549 int get contentStart() =>
1553 hasLeftQuote ? (isRaw ? 1 : 0) + (isMultiLine ? 3 : 1) : 0; 1550 hasLeftQuote ? (isRaw ? 1 : 0) + (isMultiLine ? 3 : 1) : 0;
1554 int get contentEnd() => 1551 int get contentEnd() =>
1555 wrappedString.length - (hasRightQuote ? (isMultiLine ? 3 : 1) : 0); 1552 wrappedString.length - (hasRightQuote ? (isMultiLine ? 3 : 1) : 0);
1556 1553
1557 bool isEmpty() => contentStart == contentEnd; 1554 bool isEmpty() => contentStart == contentEnd;
1558 1555
1556 static int hexValue(int hexDigit) {
1557 // hexDigit is one of '0'..'9', 'A'..'F' and 'a'..'f'.
1558 if (hexDigit <= 0x39) {
1559 return hexDigit - 0x30;
floitsch 2012/01/12 12:30:28 Don't use random constants. I would prefer not to
Lasse Reichstein Nielsen 2012/01/16 13:30:23 Now uses $9, etc.
1560 }
1561 // Make letters lowercase.
1562 hexDigit |= 0x20;
1563 hexDigit -= 0x61 - 10;
1564 assert(0 <= hexDigit && hexDigit <= 15);
1565 return hexDigit;
1566 }
1567
1568 /* Write the contents of the quoted string to a [StringBuffer] in
floitsch 2012/01/12 12:30:28 /**
Lasse Reichstein Nielsen 2012/01/16 13:30:23 Done.
1569 * a form that is valid as JavaScript string literal content.
1570 * The string is assumed quoted by [quote] characters.
1571 * This method doesn't try to make the shortest string, but rather
1572 * to be as close to the original string as possible.
1573 */
1574 void writeEscaped(StringBuffer buffer, String quote) {
1575 bool raw = this.isRaw;
1576 int from = contentStart;
1577 int end = contentEnd;
1578 for (int i = from; i < end; i++) {
1579 String character = wrappedString[i];
1580 if (character == quote) {
1581 // Insert backslash before unquoted quote character.
1582 wrappedString.printSubstringOn(buffer, from, i);
1583 buffer.add(@'\');
1584 from = i;
1585 } else if (character == @'\') {
1586 if (raw) {
1587 wrappedString.printSubstringOn(buffer, from, i);
1588 buffer.add(@'\');
floitsch 2012/01/12 12:30:28 Don't you need to update from?
Lasse Reichstein Nielsen 2012/01/16 13:30:23 I did. It's now completely rewritten.
1589 } else {
1590 character = wrappedString[++i];
floitsch 2012/01/12 12:30:28 I find it easier to i++; first: i++; character = w
Lasse Reichstein Nielsen 2012/01/16 13:30:23 In many cases I'd agree. In this, I actually read
1591 if (character == 'u') {
1592 if (wrappedString[++i] == '{') {
floitsch 2012/01/12 12:30:28 ditto
floitsch 2012/01/12 12:30:28 Maybe move the \u{...} section into a (local/neste
Lasse Reichstein Nielsen 2012/01/16 13:30:23 Moved.
1593 // In Dart, \u{x+} is a valid escape, but not in
1594 // JS. Convert to a \uxxxx escape.
1595 wrappedString.printSubstringOn(buffer, from, i);
1596 int value = 0;
1597 int hexDigit = wrappedString.charCodeAt(++i);
floitsch 2012/01/12 12:30:28 ditto. (maybe also move i++ up, so that it is clea
Lasse Reichstein Nielsen 2012/01/16 13:30:23 gone.
1598 do {
1599 value = value * 16 + hexValue(hexDigit);
1600 hexDigit = wrappedString.charCodeAt(++i);
floitsch 2012/01/12 12:30:28 use i++
1601 } while (hexDigit !== 0x7d); // until '}'.
floitsch 2012/01/12 12:30:28 magic value.
1602 // JavaScript only supports characters in the BMP.
floitsch 2012/01/12 12:30:28 That's not true. It allows for the full UTF-16. We
1603 if (value > 0xffff) value = 0xfffd;
1604
1605 for (int j = 12; j >= 0; j -= 4) {
1606 int digit = (value >> j) & 0xf;
1607 buffer.add("0123456789abcdef"[digit]);
1608 }
1609 from = i + 1;
1610 }
1611 } else if ('0' == character ||
1612 '1' == character ||
1613 '2' == character ||
1614 '3' == character ||
1615 '4' == character ||
1616 '5' == character ||
1617 '6' == character ||
1618 '7' == character) {
1619 // In Dart "\[0-9]" are identity escapes. In JS,
1620 // they start an octal escape, so we need to remove the '\'.
1621 wrappedString.printSubstringOn(buffer, from, i - 1);
1622 from = i;
1623 }
1624 // All other valid Dart escapes are also valid JS escapes
1625 // with the same meaning, so we include them verbatim.
floitsch 2012/01/12 12:30:28 I would still prefer to have them explicitly handl
Lasse Reichstein Nielsen 2012/01/16 13:30:23 Done.
1626 }
1627 }
1628 }
1629 wrappedString.printSubstringOn(buffer, from, end);
1630 }
1631
1559 /** 1632 /**
1560 * Does a conservative test for equality between two quoted strings. 1633 * Does a conservative test for equality between two quoted strings.
1561 * Returns true if the two definitly have the same string. 1634 * Returns true if the two definitly have the same string.
1562 * Returns false if the strings are different, or if it's not possible 1635 * Returns false if the strings are different, or if it's not possible
1563 * to (quickly) determine whether they are equal. 1636 * to (quickly) determine whether they are equal.
1564 */ 1637 */
1565 bool definitlyEquals(QuotedString other) { 1638 bool definitlyEquals(QuotedString other) {
1566 return flags == other.flags && wrappedString == other.wrappedString; 1639 return flags == other.flags && wrappedString == other.wrappedString;
1567 } 1640 }
1568 1641
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
1993 HInstruction first, 2066 HInstruction first,
1994 HInstruction second) 2067 HInstruction second)
1995 : super(<HInstruction>[first, second]); 2068 : super(<HInstruction>[first, second]);
1996 toString() => operation; 2069 toString() => operation;
1997 accept(HVisitor visitor) => visitor.visitLogicalOperator(this); 2070 accept(HVisitor visitor) => visitor.visitLogicalOperator(this);
1998 HInstruction get left() => inputs[0]; 2071 HInstruction get left() => inputs[0];
1999 HInstruction get right() => inputs[1]; 2072 HInstruction get right() => inputs[1];
2000 HType computeType() => HType.BOOLEAN; 2073 HType computeType() => HType.BOOLEAN;
2001 bool hasExpectedType() => true; 2074 bool hasExpectedType() => true;
2002 } 2075 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698