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 interface HVisitor<R> { | 5 interface HVisitor<R> { |
| 6 R visitAdd(HAdd node); | 6 R visitAdd(HAdd node); |
| 7 R visitBailoutTarget(HBailoutTarget node); | 7 R visitBailoutTarget(HBailoutTarget node); |
| 8 R visitBitAnd(HBitAnd node); | 8 R visitBitAnd(HBitAnd node); |
| 9 R visitBitNot(HBitNot node); | 9 R visitBitNot(HBitNot node); |
| 10 R visitBitOr(HBitOr node); | 10 R visitBitOr(HBitOr node); |
| (...skipping 1567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1578 /** | 1578 /** |
| 1579 * Finds the quote type for a string given a part of it containing the | 1579 * Finds the quote type for a string given a part of it containing the |
| 1580 * starting quote. Returns flags, but doesn't include HAS_LEFT_QUOTE | 1580 * starting quote. Returns flags, but doesn't include HAS_LEFT_QUOTE |
| 1581 * or HAS_RIGHT_QUOTE. | 1581 * or HAS_RIGHT_QUOTE. |
| 1582 */ | 1582 */ |
| 1583 static int flagsFromLeftQuote(SourceString sourceString) { | 1583 static int flagsFromLeftQuote(SourceString sourceString) { |
| 1584 Iterator<int> source = sourceString.iterator(); | 1584 Iterator<int> source = sourceString.iterator(); |
| 1585 int flags = 0; | 1585 int flags = 0; |
| 1586 int start = 0; | 1586 int start = 0; |
| 1587 int quoteChar = source.next(); | 1587 int quoteChar = source.next(); |
| 1588 if (quoteChar == '@'.charCodeAt(0)) { | 1588 if (quoteChar == $AT) { |
| 1589 flags |= RAW; | 1589 flags |= RAW; |
| 1590 start = 1; | 1590 start = 1; |
| 1591 quoteChar = source.next(); | 1591 quoteChar = source.next(); |
| 1592 } | 1592 } |
| 1593 if (quoteChar == '\''.charCodeAt(0)) { | 1593 if (quoteChar == $SQ) { |
| 1594 flags |= SINGLE_QUOTED; | 1594 flags |= SINGLE_QUOTED; |
| 1595 } else { | 1595 } else { |
| 1596 assert(quoteChar == '"'.charCodeAt(0)); | 1596 assert(quoteChar == $DQ); |
| 1597 } | 1597 } |
| 1598 // String has one quote. Check it if has three. | 1598 // String has one quote. Check it if has three. |
| 1599 // If it only have two, the string must be an empty string literal, | 1599 // If it only have two, the string must be an empty string literal, |
| 1600 // and end after the second quote. | 1600 // and end after the second quote. |
| 1601 if (source.hasNext() && source.next() == quoteChar && source.hasNext()) { | 1601 if (source.hasNext() && source.next() == quoteChar && source.hasNext()) { |
| 1602 assert(source.next() == quoteChar); | 1602 assert(source.next() == quoteChar); |
| 1603 flags |= MULTI_LINE; | 1603 flags |= MULTI_LINE; |
| 1604 } | 1604 } |
| 1605 return flags; | 1605 return flags; |
| 1606 } | 1606 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1627 if ((flags & HAS_BOTH_QUOTES) == 0) return wrappedString; | 1627 if ((flags & HAS_BOTH_QUOTES) == 0) return wrappedString; |
| 1628 return wrappedString.copyWithoutQuotes(leftQuoteLength, | 1628 return wrappedString.copyWithoutQuotes(leftQuoteLength, |
| 1629 rightQuoteLength); | 1629 rightQuoteLength); |
| 1630 } | 1630 } |
| 1631 | 1631 |
| 1632 bool get hasLeftQuote() => (flags & HAS_LEFT_QUOTE) != 0; | 1632 bool get hasLeftQuote() => (flags & HAS_LEFT_QUOTE) != 0; |
| 1633 bool get hasRightQuote() => (flags & HAS_RIGHT_QUOTE) != 0; | 1633 bool get hasRightQuote() => (flags & HAS_RIGHT_QUOTE) != 0; |
| 1634 bool get isMultiLine() => (flags & MULTI_LINE) != 0; | 1634 bool get isMultiLine() => (flags & MULTI_LINE) != 0; |
| 1635 bool get isRaw() => (flags & RAW) != 0; | 1635 bool get isRaw() => (flags & RAW) != 0; |
| 1636 String get quoteChar() => ((flags & SINGLE_QUOTED) != 0) ? "'" : '"'; | 1636 String get quoteChar() => ((flags & SINGLE_QUOTED) != 0) ? "'" : '"'; |
| 1637 int get quoteCharCode() => ((flags & SINGLE_QUOTED) != 0) ? $SQ : $DQ; | |
| 1637 | 1638 |
| 1638 int get leftQuoteLength() => | 1639 int get leftQuoteLength() => |
| 1639 hasLeftQuote ? (isRaw ? 1 : 0) + (isMultiLine ? 3 : 1) : 0; | 1640 hasLeftQuote ? (isRaw ? 1 : 0) + (isMultiLine ? 3 : 1) : 0; |
| 1640 int get rightQuoteLength() => | 1641 int get rightQuoteLength() => |
| 1641 hasRightQuote ? (isMultiLine ? 3 : 1) : 0; | 1642 hasRightQuote ? (isMultiLine ? 3 : 1) : 0; |
| 1642 static int leftQuoteLengthFromFlags(int flags) { | 1643 static int leftQuoteLengthFromFlags(int flags) { |
| 1643 if ((flags & HAS_LEFT_QUOTE) == 0) return 0; | 1644 if ((flags & HAS_LEFT_QUOTE) == 0) return 0; |
| 1644 return (flags & (RAW | MULTI_LINE)) + 1; | 1645 return (flags & (RAW | MULTI_LINE)) + 1; |
| 1645 } | 1646 } |
| 1646 static int rightQuoteLengthFromFlags(int flags) { | 1647 static int rightQuoteLengthFromFlags(int flags) { |
| 1647 if ((flags & HAS_RIGHT_QUOTE) == 0) return 0; | 1648 if ((flags & HAS_RIGHT_QUOTE) == 0) return 0; |
| 1648 return (flags & MULTI_LINE) + 1; | 1649 return (flags & MULTI_LINE) + 1; |
| 1649 } | 1650 } |
| 1650 | 1651 |
| 1651 bool isEmpty() => unquotedSource().isEmpty(); | 1652 bool isEmpty() => unquotedSource().isEmpty(); |
| 1652 | 1653 |
| 1654 static int hexValue(int hexDigit) { | |
| 1655 // hexDigit is one of '0'..'9', 'A'..'F' and 'a'..'f'. | |
| 1656 if (hexDigit <= $9) { | |
| 1657 return hexDigit - $0; | |
| 1658 } | |
| 1659 // Make letters lowercase. | |
| 1660 hexDigit |= $a - $A; | |
|
floitsch
2012/01/16 14:29:50
This "trick" depends on an ascii property where lo
Lasse Reichstein Nielsen
2012/01/17 08:50:51
I assume Unicode. There are no other encodings. FI
| |
| 1661 hexDigit -= $a - 10; | |
| 1662 assert(10 <= hexDigit && hexDigit <= 15); | |
| 1663 return hexDigit; | |
| 1664 } | |
| 1665 | |
| 1666 | |
| 1667 static void writeUnicodeEscape(Iterator<int> iter, StringBuffer buffer) { | |
| 1668 buffer.add(@'\u'); | |
| 1669 int code = iter.next(); | |
| 1670 if (code == $OPEN_CURLY_BRACKET) { | |
| 1671 // In Dart, '\u{'x{0..7}'}' is a valid escape, but not in | |
| 1672 // JS. Convert to a \uxxxx escape. | |
| 1673 int value = 0; | |
| 1674 int hexDigit = iter.next(); | |
| 1675 do { | |
| 1676 value = value * 16 + hexValue(hexDigit); | |
| 1677 hexDigit = iter.next(); | |
| 1678 } while (hexDigit !== $CLOSE_CURLY_BRACKET); // until '}'. | |
|
floitsch
2012/01/16 14:29:50
remove comment.
Lasse Reichstein Nielsen
2012/01/17 08:50:51
Done.
| |
| 1679 // JavaScript only supports characters in the BMP. | |
| 1680 // TODO(lrn): Handle characters outside the BMP, e.g., | |
| 1681 // by having a slow-case string class. | |
| 1682 if (value > 0xffff) value = 0xfffd; | |
|
floitsch
2012/01/16 14:29:50
I would prefer bailing out (compiler.cancel).
Lasse Reichstein Nielsen
2012/01/17 08:50:51
Done.
| |
| 1683 | |
| 1684 for (int j = 12; j >= 0; j -= 4) { | |
| 1685 int digit = (value >> j) & 0xf; | |
| 1686 buffer.add("0123456789abcdef"[digit]); | |
| 1687 } | |
| 1688 return; | |
| 1689 } | |
| 1690 for (int i = 0; i < 4; i++) { | |
| 1691 if (i > 0) code = iter.next(); | |
| 1692 buffer.add(new String.fromCharCodes([code])); | |
| 1693 } | |
| 1694 } | |
| 1695 | |
| 1696 /** | |
| 1697 * Write the contents of the quoted string to a [StringBuffer] in | |
| 1698 * a form that is valid as JavaScript string literal content. | |
| 1699 * The string is assumed quoted by [quote] characters. | |
| 1700 * This method doesn't try to make the shortest string, but rather | |
| 1701 * to be as close to the original string as possible. | |
| 1702 */ | |
| 1703 void writeEscaped(StringBuffer buffer, int quote) { | |
| 1704 bool raw = this.isRaw; | |
| 1705 Iterator<int> iter = | |
| 1706 wrappedString.copyWithoutQuotes(leftQuoteLength, | |
| 1707 rightQuoteLength).iterator(); | |
| 1708 while (iter.hasNext()) { | |
| 1709 int code = iter.next(); | |
| 1710 if (code == quote) { | |
| 1711 // We need to add a backslash before quotes, both in normal | |
| 1712 // and in raw strings. | |
| 1713 buffer.add(@'\'); | |
| 1714 buffer.add(code == $SQ ? "'" : '"'); | |
| 1715 } else if (code == $LF) { | |
| 1716 // Newlines in strings only occour in multiline strings. | |
| 1717 // They need to be written using escapes in JS.. | |
| 1718 assert(isMultiLine); | |
| 1719 buffer.add(@'\n'); | |
| 1720 } else if (code == $CR) { | |
| 1721 assert(isMultiLine); | |
| 1722 buffer.add(@'\r'); | |
| 1723 } else if (code == $LS || code == $PS) { | |
| 1724 // These Unicode line terminators are invalid in JS strings. | |
| 1725 buffer.add(code == $LS ? @'\u2028' : @'\u2029'); | |
| 1726 } else if (code != $BACKSLASH) { | |
| 1727 buffer.add(new String.fromCharCodes([code])); | |
| 1728 } else if (raw) { | |
| 1729 buffer.add(@'\\'); | |
| 1730 } else { | |
| 1731 code = iter.next(); | |
| 1732 switch (code) { | |
| 1733 case $u: | |
| 1734 writeUnicodeEscape(iter, buffer); | |
| 1735 break; | |
| 1736 case $x: | |
| 1737 buffer.add(@'\x'); | |
| 1738 // Remaining character will be copied literally. | |
| 1739 break; | |
| 1740 // Character escapes that identical in meaning in JS. | |
| 1741 case $b: buffer.add(@'\b'); break; | |
| 1742 case $f: buffer.add(@'\f'); break; | |
| 1743 case $n: buffer.add(@'\n'); break; | |
| 1744 case $r: buffer.add(@'\r'); break; | |
| 1745 case $t: buffer.add(@'\t'); break; | |
| 1746 case $v: buffer.add(@'\v'); break; | |
| 1747 // Identity escapes that must be escaped in JS strings. | |
| 1748 case $BACKSLASH: buffer.add(@'\\'); break; | |
| 1749 case $LF: buffer.add(@'\n'); break; | |
| 1750 case $CR: buffer.add(@'\r'); break; | |
| 1751 case $LS: buffer.add(@'\u2028'); break; | |
| 1752 case $PS: buffer.add(@'\u2029'); break; | |
| 1753 // Quotes may or may not need the escape. | |
| 1754 case $SQ: | |
| 1755 case $DQ: | |
| 1756 // Only escape quotes if they match the generated string quotes. | |
| 1757 if (code == quote) buffer.add(@'\'); | |
| 1758 buffer.add(code == $SQ ? "'" : '"'); | |
| 1759 break; | |
| 1760 default: | |
| 1761 // All other escaped characters are identity escapes, | |
| 1762 // and don't need a backslash in JS. | |
| 1763 buffer.add(new String.fromCharCodes([code])); | |
| 1764 break; | |
| 1765 } | |
| 1766 } | |
| 1767 } | |
| 1768 } | |
| 1769 | |
| 1653 /** | 1770 /** |
| 1654 * Does a conservative test for equality between two quoted strings. | 1771 * Does a conservative test for equality between two quoted strings. |
| 1655 * Returns true if the two definitly have the same string. | 1772 * Returns true if the two definitly have the same string. |
| 1656 * Returns false if the strings are different, or if it's not possible | 1773 * Returns false if the strings are different, or if it's not possible |
| 1657 * to (quickly) determine whether they are equal. | 1774 * to (quickly) determine whether they are equal. |
| 1658 */ | 1775 */ |
| 1659 bool definitlyEquals(QuotedString other) { | 1776 bool definitlyEquals(QuotedString other) { |
| 1660 return flags == other.flags && wrappedString == other.wrappedString; | 1777 return flags == other.flags && wrappedString == other.wrappedString; |
| 1661 } | 1778 } |
| 1662 | 1779 |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2107 | 2224 |
| 2108 HInstruction get expression() => inputs[0]; | 2225 HInstruction get expression() => inputs[0]; |
| 2109 | 2226 |
| 2110 HType computeType() => HType.BOOLEAN; | 2227 HType computeType() => HType.BOOLEAN; |
| 2111 bool hasExpectedType() => true; | 2228 bool hasExpectedType() => true; |
| 2112 | 2229 |
| 2113 accept(HVisitor visitor) => visitor.visitIs(this); | 2230 accept(HVisitor visitor) => visitor.visitIs(this); |
| 2114 | 2231 |
| 2115 toString() => "$expression is $typeExpression"; | 2232 toString() => "$expression is $typeExpression"; |
| 2116 } | 2233 } |
| OLD | NEW |