Chromium Code Reviews| 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 engine.scanner; | 5 library engine.scanner; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'error.dart'; | 9 import 'error.dart'; |
| 10 import 'instrumentation.dart'; | 10 import 'instrumentation.dart'; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 Token copy() => new BeginToken(type, offset); | 36 Token copy() => new BeginToken(type, offset); |
| 37 } | 37 } |
| 38 | 38 |
| 39 /** | 39 /** |
| 40 * A `BeginTokenWithComment` is a begin token that is preceded by comments. | 40 * A `BeginTokenWithComment` is a begin token that is preceded by comments. |
| 41 */ | 41 */ |
| 42 class BeginTokenWithComment extends BeginToken { | 42 class BeginTokenWithComment extends BeginToken { |
| 43 /** | 43 /** |
| 44 * The first comment in the list of comments that precede this token. | 44 * The first comment in the list of comments that precede this token. |
| 45 */ | 45 */ |
| 46 final Token _precedingComment; | 46 CommentToken precedingComments; |
| 47 | 47 |
| 48 /** | 48 /** |
| 49 * Initialize a newly created token to have the given [type] at the given | 49 * Initialize a newly created token to have the given [type] at the given |
| 50 * [offset] and to be preceded by the comments reachable from the given | 50 * [offset] and to be preceded by the comments reachable from the given |
| 51 * [comment]. | 51 * [comment]. |
| 52 */ | 52 */ |
| 53 BeginTokenWithComment(TokenType type, int offset, this._precedingComment) | 53 BeginTokenWithComment(TokenType type, int offset, this.precedingComments) |
| 54 : super(type, offset); | 54 : super(type, offset) { |
| 55 | 55 if (precedingComments != null) { |
| 56 @override | 56 precedingComments.parent = this; |
|
Brian Wilkerson
2014/12/01 14:21:24
It seems strange to me that only the first of the
| |
| 57 Token get precedingComments => _precedingComment; | 57 } |
| 58 } | |
| 58 | 59 |
| 59 @override | 60 @override |
| 60 void applyDelta(int delta) { | 61 void applyDelta(int delta) { |
| 61 super.applyDelta(delta); | 62 super.applyDelta(delta); |
| 62 Token token = _precedingComment; | 63 Token token = precedingComments; |
| 63 while (token != null) { | 64 while (token != null) { |
| 64 token.applyDelta(delta); | 65 token.applyDelta(delta); |
| 65 token = token.next; | 66 token = token.next; |
| 66 } | 67 } |
| 67 } | 68 } |
| 68 | 69 |
| 69 @override | 70 @override |
| 70 Token copy() => | 71 Token copy() => |
| 71 new BeginTokenWithComment(type, offset, copyComments(_precedingComment)); | 72 new BeginTokenWithComment(type, offset, copyComments(precedingComments)); |
| 72 } | 73 } |
| 73 | 74 |
| 74 /** | 75 /** |
| 75 * A `CharSequenceReader` is a [CharacterReader] that reads characters from a | |
| 76 * character sequence. | |
| 77 */ | |
| 78 class CharSequenceReader implements CharacterReader { | |
| 79 /** | |
| 80 * The sequence from which characters will be read. | |
| 81 */ | |
| 82 final String _sequence; | |
| 83 | |
| 84 /** | |
| 85 * The number of characters in the string. | |
| 86 */ | |
| 87 int _stringLength = 0; | |
| 88 | |
| 89 /** | |
| 90 * The index, relative to the string, of the last character that was read. | |
| 91 */ | |
| 92 int _charOffset = 0; | |
| 93 | |
| 94 /** | |
| 95 * Initialize a newly created reader to read the characters in the given | |
| 96 * [_sequence]. | |
| 97 */ | |
| 98 CharSequenceReader(this._sequence) { | |
| 99 this._stringLength = _sequence.length; | |
| 100 this._charOffset = -1; | |
| 101 } | |
| 102 | |
| 103 @override | |
| 104 int get offset => _charOffset; | |
| 105 | |
| 106 @override | |
| 107 void set offset(int offset) { | |
| 108 _charOffset = offset; | |
| 109 } | |
| 110 | |
| 111 @override | |
| 112 int advance() { | |
| 113 if (_charOffset + 1 >= _stringLength) { | |
| 114 return -1; | |
| 115 } | |
| 116 return _sequence.codeUnitAt(++_charOffset); | |
| 117 } | |
| 118 | |
| 119 @override | |
| 120 String getString(int start, int endDelta) => | |
| 121 _sequence.substring(start, _charOffset + 1 + endDelta).toString(); | |
| 122 | |
| 123 @override | |
| 124 int peek() { | |
| 125 if (_charOffset + 1 >= _stringLength) { | |
| 126 return -1; | |
| 127 } | |
| 128 return _sequence.codeUnitAt(_charOffset + 1); | |
| 129 } | |
| 130 } | |
| 131 | |
| 132 /** | |
| 133 * A `CharacterRangeReader` is a [CharacterReader] that reads a range of | 76 * A `CharacterRangeReader` is a [CharacterReader] that reads a range of |
| 134 * characters from another character reader. | 77 * characters from another character reader. |
| 135 */ | 78 */ |
| 136 class CharacterRangeReader extends CharacterReader { | 79 class CharacterRangeReader extends CharacterReader { |
| 137 /** | 80 /** |
| 138 * The reader from which the characters are actually being read. | 81 * The reader from which the characters are actually being read. |
| 139 */ | 82 */ |
| 140 final CharacterReader baseReader; | 83 final CharacterReader baseReader; |
| 141 | 84 |
| 142 /** | 85 /** |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 217 String getString(int start, int endDelta); | 160 String getString(int start, int endDelta); |
| 218 | 161 |
| 219 /** | 162 /** |
| 220 * Return the character at the current position without changing the current | 163 * Return the character at the current position without changing the current |
| 221 * position. | 164 * position. |
| 222 */ | 165 */ |
| 223 int peek(); | 166 int peek(); |
| 224 } | 167 } |
| 225 | 168 |
| 226 /** | 169 /** |
| 170 * A `CharSequenceReader` is a [CharacterReader] that reads characters from a | |
| 171 * character sequence. | |
| 172 */ | |
| 173 class CharSequenceReader implements CharacterReader { | |
| 174 /** | |
| 175 * The sequence from which characters will be read. | |
| 176 */ | |
| 177 final String _sequence; | |
| 178 | |
| 179 /** | |
| 180 * The number of characters in the string. | |
| 181 */ | |
| 182 int _stringLength = 0; | |
| 183 | |
| 184 /** | |
| 185 * The index, relative to the string, of the last character that was read. | |
| 186 */ | |
| 187 int _charOffset = 0; | |
| 188 | |
| 189 /** | |
| 190 * Initialize a newly created reader to read the characters in the given | |
| 191 * [_sequence]. | |
| 192 */ | |
| 193 CharSequenceReader(this._sequence) { | |
| 194 this._stringLength = _sequence.length; | |
| 195 this._charOffset = -1; | |
| 196 } | |
| 197 | |
| 198 @override | |
| 199 int get offset => _charOffset; | |
| 200 | |
| 201 @override | |
| 202 void set offset(int offset) { | |
| 203 _charOffset = offset; | |
| 204 } | |
| 205 | |
| 206 @override | |
| 207 int advance() { | |
| 208 if (_charOffset + 1 >= _stringLength) { | |
| 209 return -1; | |
| 210 } | |
| 211 return _sequence.codeUnitAt(++_charOffset); | |
| 212 } | |
| 213 | |
| 214 @override | |
| 215 String getString(int start, int endDelta) => | |
| 216 _sequence.substring(start, _charOffset + 1 + endDelta).toString(); | |
| 217 | |
| 218 @override | |
| 219 int peek() { | |
| 220 if (_charOffset + 1 >= _stringLength) { | |
| 221 return -1; | |
| 222 } | |
| 223 return _sequence.codeUnitAt(_charOffset + 1); | |
| 224 } | |
| 225 } | |
| 226 | |
| 227 /** | |
| 228 * A `CommentToken` is a token representing a comment. | |
| 229 */ | |
| 230 class CommentToken extends StringToken { | |
| 231 /** | |
| 232 * The [Token] that contains this comment. | |
| 233 */ | |
| 234 Token parent; | |
| 235 | |
| 236 /** | |
| 237 * Initialize a newly created token to represent a token of the given [type] | |
| 238 * with the given [value] at the given [offset]. | |
| 239 */ | |
| 240 CommentToken(TokenType type, String value, int offset) | |
| 241 : super(type, value, offset); | |
| 242 | |
| 243 @override | |
| 244 CommentToken copy() => new CommentToken(type, _value, offset); | |
| 245 } | |
| 246 | |
| 247 /** | |
| 227 * The enumeration `Keyword` defines the keywords in the Dart programming | 248 * The enumeration `Keyword` defines the keywords in the Dart programming |
| 228 * language. | 249 * language. |
| 229 */ | 250 */ |
| 230 class Keyword { | 251 class Keyword { |
| 231 static const Keyword ASSERT = const Keyword('ASSERT', "assert"); | 252 static const Keyword ASSERT = const Keyword('ASSERT', "assert"); |
| 232 | 253 |
| 233 static const Keyword BREAK = const Keyword('BREAK', "break"); | 254 static const Keyword BREAK = const Keyword('BREAK', "break"); |
| 234 | 255 |
| 235 static const Keyword CASE = const Keyword('CASE', "case"); | 256 static const Keyword CASE = const Keyword('CASE', "case"); |
| 236 | 257 |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 567 Keyword value() => keyword; | 588 Keyword value() => keyword; |
| 568 } | 589 } |
| 569 | 590 |
| 570 /** | 591 /** |
| 571 * A `KeywordTokenWithComment` is a keyword token that is preceded by comments. | 592 * A `KeywordTokenWithComment` is a keyword token that is preceded by comments. |
| 572 */ | 593 */ |
| 573 class KeywordTokenWithComment extends KeywordToken { | 594 class KeywordTokenWithComment extends KeywordToken { |
| 574 /** | 595 /** |
| 575 * The first comment in the list of comments that precede this token. | 596 * The first comment in the list of comments that precede this token. |
| 576 */ | 597 */ |
| 577 final Token _precedingComment; | 598 CommentToken precedingComments; |
| 578 | 599 |
| 579 /** | 600 /** |
| 580 * Initialize a newly created token to to represent the given [keyword] at the | 601 * Initialize a newly created token to to represent the given [keyword] at the |
| 581 * given [offset] and to be preceded by the comments reachable from the given | 602 * given [offset] and to be preceded by the comments reachable from the given |
| 582 * [comment]. | 603 * [comment]. |
| 583 */ | 604 */ |
| 584 KeywordTokenWithComment(Keyword keyword, int offset, this._precedingComment) | 605 KeywordTokenWithComment(Keyword keyword, int offset, this.precedingComments) |
| 585 : super(keyword, offset); | 606 : super(keyword, offset) { |
| 586 | 607 if (precedingComments != null) { |
| 587 @override | 608 precedingComments.parent = this; |
| 588 Token get precedingComments => _precedingComment; | 609 } |
| 610 } | |
| 589 | 611 |
| 590 @override | 612 @override |
| 591 void applyDelta(int delta) { | 613 void applyDelta(int delta) { |
| 592 super.applyDelta(delta); | 614 super.applyDelta(delta); |
| 593 Token token = _precedingComment; | 615 Token token = precedingComments; |
| 594 while (token != null) { | 616 while (token != null) { |
| 595 token.applyDelta(delta); | 617 token.applyDelta(delta); |
| 596 token = token.next; | 618 token = token.next; |
| 597 } | 619 } |
| 598 } | 620 } |
| 599 | 621 |
| 600 @override | 622 @override |
| 601 Token copy() => | 623 Token copy() => |
| 602 new KeywordTokenWithComment(keyword, offset, copyComments(_precedingCommen t)); | 624 new KeywordTokenWithComment(keyword, offset, copyComments(precedingComment s)); |
| 603 } | 625 } |
| 604 | 626 |
| 605 /** | 627 /** |
| 606 * The class `Scanner` implements a scanner for Dart code. | 628 * The class `Scanner` implements a scanner for Dart code. |
| 607 * | 629 * |
| 608 * The lexical structure of Dart is ambiguous without knowledge of the context | 630 * The lexical structure of Dart is ambiguous without knowledge of the context |
| 609 * in which a token is being scanned. For example, without context we cannot | 631 * in which a token is being scanned. For example, without context we cannot |
| 610 * determine whether source of the form "<<" should be scanned as a single | 632 * determine whether source of the form "<<" should be scanned as a single |
| 611 * left-shift operator or as two left angle brackets. This scanner does not have | 633 * left-shift operator or as two left angle brackets. This scanner does not have |
| 612 * any context, so it always resolves such conflicts by scanning the longest | 634 * any context, so it always resolves such conflicts by scanning the longest |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 951 _stackEnd++; | 973 _stackEnd++; |
| 952 } | 974 } |
| 953 | 975 |
| 954 void _appendCommentToken(TokenType type, String value) { | 976 void _appendCommentToken(TokenType type, String value) { |
| 955 // Ignore comment tokens if client specified that it doesn't need them. | 977 // Ignore comment tokens if client specified that it doesn't need them. |
| 956 if (!_preserveComments) { | 978 if (!_preserveComments) { |
| 957 return; | 979 return; |
| 958 } | 980 } |
| 959 // OK, remember comment tokens. | 981 // OK, remember comment tokens. |
| 960 if (_firstComment == null) { | 982 if (_firstComment == null) { |
| 961 _firstComment = new StringToken(type, value, _tokenStart); | 983 _firstComment = new CommentToken(type, value, _tokenStart); |
| 962 _lastComment = _firstComment; | 984 _lastComment = _firstComment; |
| 963 } else { | 985 } else { |
| 964 _lastComment = | 986 _lastComment = |
| 965 _lastComment.setNext(new StringToken(type, value, _tokenStart)); | 987 _lastComment.setNext(new CommentToken(type, value, _tokenStart)); |
| 966 } | 988 } |
| 967 } | 989 } |
| 968 | 990 |
| 969 void _appendEndToken(TokenType type, TokenType beginType) { | 991 void _appendEndToken(TokenType type, TokenType beginType) { |
| 970 Token token; | 992 Token token; |
| 971 if (_firstComment == null) { | 993 if (_firstComment == null) { |
| 972 token = new Token(type, _tokenStart); | 994 token = new Token(type, _tokenStart); |
| 973 } else { | 995 } else { |
| 974 token = new TokenWithComment(type, _tokenStart, _firstComment); | 996 token = new TokenWithComment(type, _tokenStart, _firstComment); |
| 975 _firstComment = null; | 997 _firstComment = null; |
| (...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1813 String value() => _value; | 1835 String value() => _value; |
| 1814 } | 1836 } |
| 1815 | 1837 |
| 1816 /** | 1838 /** |
| 1817 * A `StringTokenWithComment` is a string token that is preceded by comments. | 1839 * A `StringTokenWithComment` is a string token that is preceded by comments. |
| 1818 */ | 1840 */ |
| 1819 class StringTokenWithComment extends StringToken { | 1841 class StringTokenWithComment extends StringToken { |
| 1820 /** | 1842 /** |
| 1821 * The first comment in the list of comments that precede this token. | 1843 * The first comment in the list of comments that precede this token. |
| 1822 */ | 1844 */ |
| 1823 final Token _precedingComment; | 1845 CommentToken precedingComments; |
| 1824 | 1846 |
| 1825 /** | 1847 /** |
| 1826 * Initialize a newly created token to have the given [type] at the given | 1848 * Initialize a newly created token to have the given [type] at the given |
| 1827 * [offset] and to be preceded by the comments reachable from the given | 1849 * [offset] and to be preceded by the comments reachable from the given |
| 1828 * [comment]. | 1850 * [comment]. |
| 1829 */ | 1851 */ |
| 1830 StringTokenWithComment(TokenType type, String value, int offset, | 1852 StringTokenWithComment(TokenType type, String value, int offset, |
| 1831 this._precedingComment) | 1853 this.precedingComments) |
| 1832 : super(type, value, offset); | 1854 : super(type, value, offset) { |
| 1833 | 1855 if (precedingComments != null) { |
| 1834 @override | 1856 precedingComments.parent = this; |
| 1835 Token get precedingComments => _precedingComment; | 1857 } |
| 1858 } | |
| 1836 | 1859 |
| 1837 @override | 1860 @override |
| 1838 void applyDelta(int delta) { | 1861 void applyDelta(int delta) { |
| 1839 super.applyDelta(delta); | 1862 super.applyDelta(delta); |
| 1840 Token token = _precedingComment; | 1863 Token token = precedingComments; |
| 1841 while (token != null) { | 1864 while (token != null) { |
| 1842 token.applyDelta(delta); | 1865 token.applyDelta(delta); |
| 1843 token = token.next; | 1866 token = token.next; |
| 1844 } | 1867 } |
| 1845 } | 1868 } |
| 1846 | 1869 |
| 1847 @override | 1870 @override |
| 1848 Token copy() => | 1871 Token copy() => |
| 1849 new StringTokenWithComment( | 1872 new StringTokenWithComment( |
| 1850 type, | 1873 type, |
| 1851 lexeme, | 1874 lexeme, |
| 1852 offset, | 1875 offset, |
| 1853 copyComments(_precedingComment)); | 1876 copyComments(precedingComments)); |
| 1854 } | 1877 } |
| 1855 | 1878 |
| 1856 /** | 1879 /** |
| 1857 * A `SubSequenceReader` is a [CharacterReader] that reads characters from a | 1880 * A `SubSequenceReader` is a [CharacterReader] that reads characters from a |
| 1858 * character sequence, but adds a delta when reporting the current character | 1881 * character sequence, but adds a delta when reporting the current character |
| 1859 * offset so that the character sequence can be a subsequence from a larger | 1882 * offset so that the character sequence can be a subsequence from a larger |
| 1860 * sequence. | 1883 * sequence. |
| 1861 */ | 1884 */ |
| 1862 class SubSequenceReader extends CharSequenceReader { | 1885 class SubSequenceReader extends CharSequenceReader { |
| 1863 /** | 1886 /** |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1974 */ | 1997 */ |
| 1975 Token get next => _next; | 1998 Token get next => _next; |
| 1976 | 1999 |
| 1977 /** | 2000 /** |
| 1978 * Return the first comment in the list of comments that precede this token, | 2001 * Return the first comment in the list of comments that precede this token, |
| 1979 * or `null` if there are no comments preceding this token. Additional | 2002 * or `null` if there are no comments preceding this token. Additional |
| 1980 * comments can be reached by following the token stream using [next] until | 2003 * comments can be reached by following the token stream using [next] until |
| 1981 * `null` is returned. | 2004 * `null` is returned. |
| 1982 * | 2005 * |
| 1983 * For example, if the original contents were "/* one */ /* two */ id", then | 2006 * For example, if the original contents were "/* one */ /* two */ id", then |
| 1984 * the first precceding comment token will have a lexeme of "/* one */" and | 2007 * the first preceding comment token will have a lexeme of "/* one */" and |
| 1985 * the next comment token will have a lexeme of "/* two */". | 2008 * the next comment token will have a lexeme of "/* two */". |
| 1986 */ | 2009 */ |
| 1987 Token get precedingComments => null; | 2010 Token get precedingComments => null; |
| 1988 | 2011 |
| 1989 /** | 2012 /** |
| 1990 * Apply (add) the given [delta] to this token's offset. | 2013 * Apply (add) the given [delta] to this token's offset. |
| 1991 */ | 2014 */ |
| 1992 void applyDelta(int delta) { | 2015 void applyDelta(int delta) { |
| 1993 offset += delta; | 2016 offset += delta; |
| 1994 } | 2017 } |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2542 String toString() => "-eof-"; | 2565 String toString() => "-eof-"; |
| 2543 } | 2566 } |
| 2544 | 2567 |
| 2545 /** | 2568 /** |
| 2546 * A `TokenWithComment` is a normal token that is preceded by comments. | 2569 * A `TokenWithComment` is a normal token that is preceded by comments. |
| 2547 */ | 2570 */ |
| 2548 class TokenWithComment extends Token { | 2571 class TokenWithComment extends Token { |
| 2549 /** | 2572 /** |
| 2550 * The first comment in the list of comments that precede this token. | 2573 * The first comment in the list of comments that precede this token. |
| 2551 */ | 2574 */ |
| 2552 final Token _precedingComment; | 2575 CommentToken precedingComments; |
| 2553 | 2576 |
| 2554 /** | 2577 /** |
| 2555 * Initialize a newly created token to have the given [type] at the given | 2578 * Initialize a newly created token to have the given [type] at the given |
| 2556 * [offset] and to be preceded by the comments reachable from the given | 2579 * [offset] and to be preceded by the comments reachable from the given |
| 2557 * [comment]. | 2580 * [comment]. |
| 2558 */ | 2581 */ |
| 2559 TokenWithComment(TokenType type, int offset, this._precedingComment) | 2582 TokenWithComment(TokenType type, int offset, this.precedingComments) |
| 2560 : super(type, offset); | 2583 : super(type, offset) { |
| 2584 if (precedingComments != null) { | |
| 2585 precedingComments.parent = this; | |
| 2586 } | |
| 2587 } | |
| 2561 | 2588 |
| 2562 @override | 2589 @override |
| 2563 Token get precedingComments => _precedingComment; | 2590 Token copy() => new TokenWithComment(type, offset, precedingComments); |
| 2564 | |
| 2565 @override | |
| 2566 Token copy() => new TokenWithComment(type, offset, _precedingComment); | |
| 2567 } | 2591 } |
| OLD | NEW |