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

Side by Side Diff: pkg/analyzer_experimental/lib/src/generated/html.dart

Issue 16256021: Remove trailing spaces in analyzer_experimental (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 6 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 // This code was auto-generated, is not intended to be edited, and is subject to 1 // This code was auto-generated, is not intended to be edited, and is subject to
2 // significant change. Please see the README file for more information. 2 // significant change. Please see the README file for more information.
3
4 library engine.html; 3 library engine.html;
5
6 import 'dart:collection'; 4 import 'dart:collection';
7 import 'java_core.dart'; 5 import 'java_core.dart';
8 import 'java_engine.dart'; 6 import 'java_engine.dart';
9 import 'source.dart'; 7 import 'source.dart';
10 import 'error.dart'; 8 import 'error.dart';
11 import 'instrumentation.dart'; 9 import 'instrumentation.dart';
12 import 'element.dart' show HtmlElementImpl; 10 import 'element.dart' show HtmlElementImpl;
13
14
15 /** 11 /**
16 * Instances of the class {@code Token} represent a token that was scanned from the input. Each 12 * Instances of the class {@code Token} represent a token that was scanned from the input. Each
17 * token knows which token follows it, acting as the head of a linked list of to kens. 13 * token knows which token follows it, acting as the head of a linked list of to kens.
18 * @coverage dart.engine.html 14 * @coverage dart.engine.html
19 */ 15 */
20 class Token { 16 class Token {
21 17
22 /** 18 /**
23 * The offset from the beginning of the file to the first character in the tok en. 19 * The offset from the beginning of the file to the first character in the tok en.
24 */ 20 */
25 int _offset = 0; 21 int _offset = 0;
26 22
27 /** 23 /**
28 * The previous token in the token stream. 24 * The previous token in the token stream.
29 */ 25 */
30 Token _previous; 26 Token _previous;
31 27
32 /** 28 /**
33 * The next token in the token stream. 29 * The next token in the token stream.
34 */ 30 */
35 Token _next; 31 Token _next;
36 32
37 /** 33 /**
38 * The type of the token. 34 * The type of the token.
39 */ 35 */
40 TokenType _type; 36 TokenType _type;
41 37
42 /** 38 /**
43 * The lexeme represented by this token. 39 * The lexeme represented by this token.
44 */ 40 */
45 String _value; 41 String _value;
46 42
47 /** 43 /**
48 * Initialize a newly created token. 44 * Initialize a newly created token.
49 * @param type the token type (not {@code null}) 45 * @param type the token type (not {@code null})
50 * @param offset the offset from the beginning of the file to the first charac ter in the token 46 * @param offset the offset from the beginning of the file to the first charac ter in the token
51 */ 47 */
52 Token.con1(TokenType type, int offset) { 48 Token.con1(TokenType type, int offset) {
53 _jtd_constructor_154_impl(type, offset); 49 _jtd_constructor_155_impl(type, offset);
54 } 50 }
55 _jtd_constructor_154_impl(TokenType type, int offset) { 51 _jtd_constructor_155_impl(TokenType type, int offset) {
56 _jtd_constructor_155_impl(type, offset, type.lexeme); 52 _jtd_constructor_156_impl(type, offset, type.lexeme);
57 } 53 }
58 54
59 /** 55 /**
60 * Initialize a newly created token. 56 * Initialize a newly created token.
61 * @param type the token type (not {@code null}) 57 * @param type the token type (not {@code null})
62 * @param offset the offset from the beginning of the file to the first charac ter in the token 58 * @param offset the offset from the beginning of the file to the first charac ter in the token
63 * @param value the lexeme represented by this token (not {@code null}) 59 * @param value the lexeme represented by this token (not {@code null})
64 */ 60 */
65 Token.con2(TokenType type2, int offset2, String value2) { 61 Token.con2(TokenType type2, int offset2, String value2) {
66 _jtd_constructor_155_impl(type2, offset2, value2); 62 _jtd_constructor_156_impl(type2, offset2, value2);
67 } 63 }
68 _jtd_constructor_155_impl(TokenType type2, int offset2, String value2) { 64 _jtd_constructor_156_impl(TokenType type2, int offset2, String value2) {
69 this._type = type2; 65 this._type = type2;
70 this._value = StringUtilities.intern(value2); 66 this._value = StringUtilities.intern(value2);
71 this._offset = offset2; 67 this._offset = offset2;
72 } 68 }
73 69
74 /** 70 /**
75 * Return the offset from the beginning of the file to the character after las t character of the 71 * Return the offset from the beginning of the file to the character after las t character of the
76 * token. 72 * token.
77 * @return the offset from the beginning of the file to the first character af ter last character 73 * @return the offset from the beginning of the file to the first character af ter last character
78 * of the token 74 * of the token
79 */ 75 */
80 int get end => _offset + length; 76 int get end => _offset + length;
81 77
82 /** 78 /**
83 * Return the number of characters in the node's source range. 79 * Return the number of characters in the node's source range.
84 * @return the number of characters in the node's source range 80 * @return the number of characters in the node's source range
85 */ 81 */
86 int get length => lexeme.length; 82 int get length => lexeme.length;
87 83
88 /** 84 /**
89 * Return the lexeme that represents this token. 85 * Return the lexeme that represents this token.
90 * @return the lexeme (not {@code null}) 86 * @return the lexeme (not {@code null})
91 */ 87 */
92 String get lexeme => _value; 88 String get lexeme => _value;
93 89
94 /** 90 /**
95 * Return the next token in the token stream. 91 * Return the next token in the token stream.
96 * @return the next token in the token stream 92 * @return the next token in the token stream
97 */ 93 */
98 Token get next => _next; 94 Token get next => _next;
99 95
100 /** 96 /**
101 * Return the offset from the beginning of the file to the first character in the token. 97 * Return the offset from the beginning of the file to the first character in the token.
102 * @return the offset from the beginning of the file to the first character in the token 98 * @return the offset from the beginning of the file to the first character in the token
103 */ 99 */
104 int get offset => _offset; 100 int get offset => _offset;
105 101
106 /** 102 /**
107 * Return the previous token in the token stream. 103 * Return the previous token in the token stream.
108 * @return the previous token in the token stream 104 * @return the previous token in the token stream
109 */ 105 */
110 Token get previous => _previous; 106 Token get previous => _previous;
111 107
112 /** 108 /**
113 * Answer the token type for the receiver. 109 * Answer the token type for the receiver.
114 * @return the token type (not {@code null}) 110 * @return the token type (not {@code null})
115 */ 111 */
116 TokenType get type => _type; 112 TokenType get type => _type;
117 113
118 /** 114 /**
119 * Return {@code true} if this token is a synthetic token. A synthetic token i s a token that was 115 * Return {@code true} if this token is a synthetic token. A synthetic token i s a token that was
120 * introduced by the parser in order to recover from an error in the code. Syn thetic tokens always 116 * introduced by the parser in order to recover from an error in the code. Syn thetic tokens always
121 * have a length of zero ({@code 0}). 117 * have a length of zero ({@code 0}).
122 * @return {@code true} if this token is a synthetic token 118 * @return {@code true} if this token is a synthetic token
123 */ 119 */
124 bool isSynthetic() => length == 0; 120 bool isSynthetic() => length == 0;
125 121
126 /** 122 /**
127 * Set the next token in the token stream to the given token. This has the sid e-effect of setting 123 * Set the next token in the token stream to the given token. This has the sid e-effect of setting
128 * this token to be the previous token for the given token. 124 * this token to be the previous token for the given token.
129 * @param token the next token in the token stream 125 * @param token the next token in the token stream
130 * @return the token that was passed in 126 * @return the token that was passed in
131 */ 127 */
132 Token setNext(Token token) { 128 Token setNext(Token token) {
133 _next = token; 129 _next = token;
134 token.previous = this; 130 token.previous = this;
135 return token; 131 return token;
136 } 132 }
137 String toString() => lexeme; 133 String toString() => lexeme;
138 134
139 /** 135 /**
140 * Set the previous token in the token stream to the given token. 136 * Set the previous token in the token stream to the given token.
141 * @param previous the previous token in the token stream 137 * @param previous the previous token in the token stream
142 */ 138 */
143 void set previous(Token previous2) { 139 void set previous(Token previous2) {
144 this._previous = previous2; 140 this._previous = previous2;
145 } 141 }
146 } 142 }
147
148 /** 143 /**
149 * Instances of {@code HtmlParseResult} hold the result of parsing an HTML file. 144 * Instances of {@code HtmlParseResult} hold the result of parsing an HTML file.
150 * @coverage dart.engine.html 145 * @coverage dart.engine.html
151 */ 146 */
152 class HtmlParseResult extends HtmlScanResult { 147 class HtmlParseResult extends HtmlScanResult {
153 148
154 /** 149 /**
155 * The unit containing the parsed information (not {@code null}). 150 * The unit containing the parsed information (not {@code null}).
156 */ 151 */
157 HtmlUnit _unit; 152 HtmlUnit _unit;
158 HtmlParseResult(int modificationTime, Token token, List<int> lineStarts, HtmlU nit unit) : super(modificationTime, token, lineStarts) { 153 HtmlParseResult(int modificationTime, Token token, List<int> lineStarts, HtmlU nit unit) : super(modificationTime, token, lineStarts) {
159 this._unit = unit; 154 this._unit = unit;
160 } 155 }
161 156
162 /** 157 /**
163 * Answer the unit generated by parsing the source 158 * Answer the unit generated by parsing the source
164 * @return the unit (not {@code null}) 159 * @return the unit (not {@code null})
165 */ 160 */
166 HtmlUnit get htmlUnit => _unit; 161 HtmlUnit get htmlUnit => _unit;
167 } 162 }
168
169 /** 163 /**
170 * Instances of the class {@code RecursiveXmlVisitor} implement an XML visitor t hat will recursively 164 * Instances of the class {@code RecursiveXmlVisitor} implement an XML visitor t hat will recursively
171 * visit all of the nodes in an XML structure. For example, using an instance of this class to visit 165 * visit all of the nodes in an XML structure. For example, using an instance of this class to visit
172 * a {@link XmlTagNode} will also cause all of the contained {@link XmlAttribute Node}s and{@link XmlTagNode}s to be visited. 166 * a {@link XmlTagNode} will also cause all of the contained {@link XmlAttribute Node}s and{@link XmlTagNode}s to be visited.
173 * <p> 167 * <p>
174 * Subclasses that override a visit method must either invoke the overridden vis it method or must 168 * Subclasses that override a visit method must either invoke the overridden vis it method or must
175 * explicitly ask the visited node to visit its children. Failure to do so will cause the children 169 * explicitly ask the visited node to visit its children. Failure to do so will cause the children
176 * of the visited node to not be visited. 170 * of the visited node to not be visited.
177 * @coverage dart.engine.html 171 * @coverage dart.engine.html
178 */ 172 */
179 class RecursiveXmlVisitor<R> implements XmlVisitor<R> { 173 class RecursiveXmlVisitor<R> implements XmlVisitor<R> {
180 R visitHtmlUnit(HtmlUnit node) { 174 R visitHtmlUnit(HtmlUnit node) {
181 node.visitChildren(this); 175 node.visitChildren(this);
182 return null; 176 return null;
183 } 177 }
184 R visitXmlAttributeNode(XmlAttributeNode node) { 178 R visitXmlAttributeNode(XmlAttributeNode node) {
185 node.visitChildren(this); 179 node.visitChildren(this);
186 return null; 180 return null;
187 } 181 }
188 R visitXmlTagNode(XmlTagNode node) { 182 R visitXmlTagNode(XmlTagNode node) {
189 node.visitChildren(this); 183 node.visitChildren(this);
190 return null; 184 return null;
191 } 185 }
192 } 186 }
193
194 /** 187 /**
195 * The abstract class {@code XmlNode} defines behavior common to all XML/HTML no des. 188 * The abstract class {@code XmlNode} defines behavior common to all XML/HTML no des.
196 * @coverage dart.engine.html 189 * @coverage dart.engine.html
197 */ 190 */
198 abstract class XmlNode { 191 abstract class XmlNode {
199 192
200 /** 193 /**
201 * The parent of the node, or {@code null} if the node is the root of an AST s tructure. 194 * The parent of the node, or {@code null} if the node is the root of an AST s tructure.
202 */ 195 */
203 XmlNode _parent; 196 XmlNode _parent;
204 197
205 /** 198 /**
206 * Use the given visitor to visit this node. 199 * Use the given visitor to visit this node.
207 * @param visitor the visitor that will visit this node 200 * @param visitor the visitor that will visit this node
208 * @return the value returned by the visitor as a result of visiting this node 201 * @return the value returned by the visitor as a result of visiting this node
209 */ 202 */
210 accept(XmlVisitor visitor); 203 accept(XmlVisitor visitor);
211 204
212 /** 205 /**
213 * Return the first token included in this node's source range. 206 * Return the first token included in this node's source range.
214 * @return the first token or {@code null} if none 207 * @return the first token or {@code null} if none
215 */ 208 */
216 Token get beginToken; 209 Token get beginToken;
217 210
218 /** 211 /**
219 * Return the offset of the character immediately following the last character of this node's 212 * Return the offset of the character immediately following the last character of this node's
220 * source range. This is equivalent to {@code node.getOffset() + node.getLengt h()}. For an html 213 * source range. This is equivalent to {@code node.getOffset() + node.getLengt h()}. For an html
221 * unit this will be equal to the length of the unit's source. 214 * unit this will be equal to the length of the unit's source.
222 * @return the offset of the character just past the node's source range 215 * @return the offset of the character just past the node's source range
223 */ 216 */
224 int get end => offset + length; 217 int get end => offset + length;
225 218
226 /** 219 /**
227 * Return the last token included in this node's source range. 220 * Return the last token included in this node's source range.
228 * @return the last token or {@code null} if none 221 * @return the last token or {@code null} if none
229 */ 222 */
230 Token get endToken; 223 Token get endToken;
231 224
232 /** 225 /**
233 * Return the number of characters in the node's source range. 226 * Return the number of characters in the node's source range.
234 * @return the number of characters in the node's source range 227 * @return the number of characters in the node's source range
235 */ 228 */
236 int get length { 229 int get length {
237 Token beginToken2 = beginToken; 230 Token beginToken2 = beginToken;
238 Token endToken2 = endToken; 231 Token endToken2 = endToken;
239 if (beginToken2 == null || endToken2 == null) { 232 if (beginToken2 == null || endToken2 == null) {
240 return -1; 233 return -1;
241 } 234 }
242 return endToken2.offset + endToken2.length - beginToken2.offset; 235 return endToken2.offset + endToken2.length - beginToken2.offset;
243 } 236 }
244 237
245 /** 238 /**
246 * Return the offset from the beginning of the file to the first character in the node's source 239 * Return the offset from the beginning of the file to the first character in the node's source
247 * range. 240 * range.
248 * @return the offset from the beginning of the file to the first character in the node's source 241 * @return the offset from the beginning of the file to the first character in the node's source
249 * range 242 * range
250 */ 243 */
251 int get offset { 244 int get offset {
252 Token beginToken2 = beginToken; 245 Token beginToken2 = beginToken;
253 if (beginToken2 == null) { 246 if (beginToken2 == null) {
254 return -1; 247 return -1;
255 } 248 }
256 return beginToken.offset; 249 return beginToken.offset;
257 } 250 }
258 251
259 /** 252 /**
260 * Return this node's parent node, or {@code null} if this node is the root of an AST structure. 253 * Return this node's parent node, or {@code null} if this node is the root of an AST structure.
261 * <p> 254 * <p>
262 * Note that the relationship between an AST node and its parent node may chan ge over the lifetime 255 * Note that the relationship between an AST node and its parent node may chan ge over the lifetime
263 * of a node. 256 * of a node.
264 * @return the parent of this node, or {@code null} if none 257 * @return the parent of this node, or {@code null} if none
265 */ 258 */
266 XmlNode get parent => _parent; 259 XmlNode get parent => _parent;
267 String toString() { 260 String toString() {
268 PrintStringWriter writer = new PrintStringWriter(); 261 PrintStringWriter writer = new PrintStringWriter();
269 accept(new ToSourceVisitor(writer)); 262 accept(new ToSourceVisitor(writer));
270 return writer.toString(); 263 return writer.toString();
271 } 264 }
272 265
273 /** 266 /**
274 * Use the given visitor to visit all of the children of this node. The childr en will be visited 267 * Use the given visitor to visit all of the children of this node. The childr en will be visited
275 * in source order. 268 * in source order.
276 * @param visitor the visitor that will be used to visit the children of this node 269 * @param visitor the visitor that will be used to visit the children of this node
277 */ 270 */
278 void visitChildren(XmlVisitor<Object> visitor); 271 void visitChildren(XmlVisitor<Object> visitor);
279 272
280 /** 273 /**
281 * Make this node the parent of the given child nodes. 274 * Make this node the parent of the given child nodes.
282 * @param children the nodes that will become the children of this node 275 * @param children the nodes that will become the children of this node
283 * @return the nodes that were made children of this node 276 * @return the nodes that were made children of this node
284 */ 277 */
285 List becomeParentOf(List children) { 278 List becomeParentOf(List children) {
286 if (children != null) { 279 if (children != null) {
287 for (JavaIterator iter = new JavaIterator(children); iter.hasNext;) { 280 for (JavaIterator iter = new JavaIterator(children); iter.hasNext;) {
288 XmlNode node = iter.next(); 281 XmlNode node = iter.next();
289 node.parent = this; 282 node.parent = this;
290 } 283 }
291 return new List.from(children); 284 return new List.from(children);
292 } 285 }
293 return children; 286 return children;
294 } 287 }
295 288
296 /** 289 /**
297 * Make this node the parent of the given child node. 290 * Make this node the parent of the given child node.
298 * @param child the node that will become a child of this node 291 * @param child the node that will become a child of this node
299 * @return the node that was made a child of this node 292 * @return the node that was made a child of this node
300 */ 293 */
301 XmlNode becomeParentOf2(XmlNode child) { 294 XmlNode becomeParentOf2(XmlNode child) {
302 if (child != null) { 295 if (child != null) {
303 XmlNode node = child; 296 XmlNode node = child;
304 node.parent = this; 297 node.parent = this;
305 } 298 }
306 return child; 299 return child;
307 } 300 }
308 301
309 /** 302 /**
310 * Set the parent of this node to the given node. 303 * Set the parent of this node to the given node.
311 * @param newParent the node that is to be made the parent of this node 304 * @param newParent the node that is to be made the parent of this node
312 */ 305 */
313 void set parent(XmlNode newParent) { 306 void set parent(XmlNode newParent) {
314 _parent = newParent; 307 _parent = newParent;
315 } 308 }
316 } 309 }
317
318 /** 310 /**
319 * Instances of the class {@code SimpleXmlVisitor} implement an AST visitor that will do nothing 311 * Instances of the class {@code SimpleXmlVisitor} implement an AST visitor that will do nothing
320 * when visiting an AST node. It is intended to be a superclass for classes that use the visitor 312 * when visiting an AST node. It is intended to be a superclass for classes that use the visitor
321 * pattern primarily as a dispatch mechanism (and hence don't need to recursivel y visit a whole 313 * pattern primarily as a dispatch mechanism (and hence don't need to recursivel y visit a whole
322 * structure) and that only need to visit a small number of node types. 314 * structure) and that only need to visit a small number of node types.
323 */ 315 */
324 class SimpleXmlVisitor<R> implements XmlVisitor<R> { 316 class SimpleXmlVisitor<R> implements XmlVisitor<R> {
325 R visitHtmlUnit(HtmlUnit htmlUnit) => null; 317 R visitHtmlUnit(HtmlUnit htmlUnit) => null;
326 R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode) => null; 318 R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode) => null;
327 R visitXmlTagNode(XmlTagNode xmlTagNode) => null; 319 R visitXmlTagNode(XmlTagNode xmlTagNode) => null;
328 } 320 }
329
330 /** 321 /**
331 * The abstract class {@code AbstractScanner} implements a scanner for HTML code . Subclasses are 322 * The abstract class {@code AbstractScanner} implements a scanner for HTML code . Subclasses are
332 * required to implement the interface used to access the characters being scann ed. 323 * required to implement the interface used to access the characters being scann ed.
333 * @coverage dart.engine.html 324 * @coverage dart.engine.html
334 */ 325 */
335 abstract class AbstractScanner { 326 abstract class AbstractScanner {
336 static List<String> _NO_PASS_THROUGH_ELEMENTS = <String> []; 327 static List<String> _NO_PASS_THROUGH_ELEMENTS = <String> [];
337 328
338 /** 329 /**
339 * The source being scanned. 330 * The source being scanned.
340 */ 331 */
341 Source _source; 332 Source _source;
342 333
343 /** 334 /**
344 * The token pointing to the head of the linked list of tokens. 335 * The token pointing to the head of the linked list of tokens.
345 */ 336 */
346 Token _tokens; 337 Token _tokens;
347 338
348 /** 339 /**
349 * The last token that was scanned. 340 * The last token that was scanned.
350 */ 341 */
351 Token _tail; 342 Token _tail;
352 343
353 /** 344 /**
354 * A list containing the offsets of the first character of each line in the so urce code. 345 * A list containing the offsets of the first character of each line in the so urce code.
355 */ 346 */
356 List<int> _lineStarts = new List<int>(); 347 List<int> _lineStarts = new List<int>();
357 348
358 /** 349 /**
359 * An array of element tags for which the content between tags should be consi der a single token. 350 * An array of element tags for which the content between tags should be consi der a single token.
360 */ 351 */
361 List<String> _passThroughElements = _NO_PASS_THROUGH_ELEMENTS; 352 List<String> _passThroughElements = _NO_PASS_THROUGH_ELEMENTS;
362 353
363 /** 354 /**
364 * Initialize a newly created scanner. 355 * Initialize a newly created scanner.
365 * @param source the source being scanned 356 * @param source the source being scanned
366 */ 357 */
367 AbstractScanner(Source source) { 358 AbstractScanner(Source source) {
368 this._source = source; 359 this._source = source;
369 _tokens = new Token.con1(TokenType.EOF, -1); 360 _tokens = new Token.con1(TokenType.EOF, -1);
370 _tokens.setNext(_tokens); 361 _tokens.setNext(_tokens);
371 _tail = _tokens; 362 _tail = _tokens;
372 recordStartOfLine(); 363 recordStartOfLine();
373 } 364 }
374 365
375 /** 366 /**
376 * Return an array containing the offsets of the first character of each line in the source code. 367 * Return an array containing the offsets of the first character of each line in the source code.
377 * @return an array containing the offsets of the first character of each line in the source code 368 * @return an array containing the offsets of the first character of each line in the source code
378 */ 369 */
379 List<int> get lineStarts => _lineStarts; 370 List<int> get lineStarts => _lineStarts;
380 371
381 /** 372 /**
382 * Return the current offset relative to the beginning of the file. Return the initial offset if 373 * Return the current offset relative to the beginning of the file. Return the initial offset if
383 * the scanner has not yet scanned the source code, and one (1) past the end o f the source code if 374 * the scanner has not yet scanned the source code, and one (1) past the end o f the source code if
384 * the source code has been scanned. 375 * the source code has been scanned.
385 * @return the current offset of the scanner in the source 376 * @return the current offset of the scanner in the source
386 */ 377 */
387 int get offset; 378 int get offset;
388 379
389 /** 380 /**
390 * Answer the source being scanned. 381 * Answer the source being scanned.
391 * @return the source or {@code null} if undefined 382 * @return the source or {@code null} if undefined
392 */ 383 */
393 Source get source => _source; 384 Source get source => _source;
394 385
395 /** 386 /**
396 * Set array of element tags for which the content between tags should be cons ider a single token. 387 * Set array of element tags for which the content between tags should be cons ider a single token.
397 */ 388 */
398 void set passThroughElements(List<String> passThroughElements2) { 389 void set passThroughElements(List<String> passThroughElements2) {
399 this._passThroughElements = passThroughElements2 != null ? passThroughElemen ts2 : _NO_PASS_THROUGH_ELEMENTS; 390 this._passThroughElements = passThroughElements2 != null ? passThroughElemen ts2 : _NO_PASS_THROUGH_ELEMENTS;
400 } 391 }
401 392
402 /** 393 /**
403 * Scan the source code to produce a list of tokens representing the source. 394 * Scan the source code to produce a list of tokens representing the source.
404 * @return the first token in the list of tokens that were produced 395 * @return the first token in the list of tokens that were produced
405 */ 396 */
406 Token tokenize() { 397 Token tokenize() {
407 scan(); 398 scan();
408 appendEofToken(); 399 appendEofToken();
409 return firstToken(); 400 return firstToken();
410 } 401 }
411 402
412 /** 403 /**
413 * Advance the current position and return the character at the new current po sition. 404 * Advance the current position and return the character at the new current po sition.
414 * @return the character at the new current position 405 * @return the character at the new current position
415 */ 406 */
416 int advance(); 407 int advance();
417 408
418 /** 409 /**
419 * Return the substring of the source code between the start offset and the mo dified current 410 * Return the substring of the source code between the start offset and the mo dified current
420 * position. The current position is modified by adding the end delta. 411 * position. The current position is modified by adding the end delta.
421 * @param start the offset to the beginning of the string, relative to the sta rt of the file 412 * @param start the offset to the beginning of the string, relative to the sta rt of the file
422 * @param endDelta the number of character after the current location to be in cluded in the 413 * @param endDelta the number of character after the current location to be in cluded in the
423 * string, or the number of characters before the current location to be exclu ded if the 414 * string, or the number of characters before the current location to be exclu ded if the
424 * offset is negative 415 * offset is negative
425 * @return the specified substring of the source code 416 * @return the specified substring of the source code
426 */ 417 */
427 String getString(int start, int endDelta); 418 String getString(int start, int endDelta);
428 419
429 /** 420 /**
430 * Return the character at the current position without changing the current p osition. 421 * Return the character at the current position without changing the current p osition.
431 * @return the character at the current position 422 * @return the character at the current position
432 */ 423 */
433 int peek(); 424 int peek();
434 425
435 /** 426 /**
436 * Record the fact that we are at the beginning of a new line in the source. 427 * Record the fact that we are at the beginning of a new line in the source.
437 */ 428 */
438 void recordStartOfLine() { 429 void recordStartOfLine() {
439 _lineStarts.add(offset); 430 _lineStarts.add(offset);
440 } 431 }
441 void appendEofToken() { 432 void appendEofToken() {
442 Token eofToken = new Token.con1(TokenType.EOF, offset); 433 Token eofToken = new Token.con1(TokenType.EOF, offset);
443 eofToken.setNext(eofToken); 434 eofToken.setNext(eofToken);
444 _tail = _tail.setNext(eofToken); 435 _tail = _tail.setNext(eofToken);
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 c = advance(); 585 c = advance();
595 } 586 }
596 emit3(TokenType.TAG, start, -1); 587 emit3(TokenType.TAG, start, -1);
597 } else { 588 } else {
598 emit3(TokenType.TEXT, start, 0); 589 emit3(TokenType.TEXT, start, 0);
599 c = advance(); 590 c = advance();
600 } 591 }
601 } 592 }
602 } 593 }
603 } 594 }
604
605 /** 595 /**
606 * Instances of {@code HtmlScanResult} hold the result of scanning an HTML file. 596 * Instances of {@code HtmlScanResult} hold the result of scanning an HTML file.
607 * @coverage dart.engine.html 597 * @coverage dart.engine.html
608 */ 598 */
609 class HtmlScanResult { 599 class HtmlScanResult {
610 600
611 /** 601 /**
612 * The time at which the contents of the source were last set. 602 * The time at which the contents of the source were last set.
613 */ 603 */
614 int _modificationTime = 0; 604 int _modificationTime = 0;
615 605
616 /** 606 /**
617 * The first token in the token stream (not {@code null}). 607 * The first token in the token stream (not {@code null}).
618 */ 608 */
619 Token _token; 609 Token _token;
620 610
621 /** 611 /**
622 * The line start information that was produced. 612 * The line start information that was produced.
623 */ 613 */
624 List<int> _lineStarts; 614 List<int> _lineStarts;
625 HtmlScanResult(int modificationTime, Token token, List<int> lineStarts) { 615 HtmlScanResult(int modificationTime, Token token, List<int> lineStarts) {
626 this._modificationTime = modificationTime; 616 this._modificationTime = modificationTime;
627 this._token = token; 617 this._token = token;
628 this._lineStarts = lineStarts; 618 this._lineStarts = lineStarts;
629 } 619 }
630 620
631 /** 621 /**
632 * Answer the line start information that was produced. 622 * Answer the line start information that was produced.
633 * @return an array of line starts (not {@code null}) 623 * @return an array of line starts (not {@code null})
634 */ 624 */
635 List<int> get lineStarts => _lineStarts; 625 List<int> get lineStarts => _lineStarts;
636 626
637 /** 627 /**
638 * Return the time at which the contents of the source were last set. 628 * Return the time at which the contents of the source were last set.
639 * @return the time at which the contents of the source were last set 629 * @return the time at which the contents of the source were last set
640 */ 630 */
641 int get modificationTime => _modificationTime; 631 int get modificationTime => _modificationTime;
642 632
643 /** 633 /**
644 * Answer the first token in the token stream. 634 * Answer the first token in the token stream.
645 * @return the token (not {@code null}) 635 * @return the token (not {@code null})
646 */ 636 */
647 Token get token => _token; 637 Token get token => _token;
648 } 638 }
649
650 /** 639 /**
651 * Instances of the class {@code StringScanner} implement a scanner that reads f rom a string. The 640 * Instances of the class {@code StringScanner} implement a scanner that reads f rom a string. The
652 * scanning logic is in the superclass. 641 * scanning logic is in the superclass.
653 * @coverage dart.engine.html 642 * @coverage dart.engine.html
654 */ 643 */
655 class StringScanner extends AbstractScanner { 644 class StringScanner extends AbstractScanner {
656 645
657 /** 646 /**
658 * The string from which characters will be read. 647 * The string from which characters will be read.
659 */ 648 */
660 String _string; 649 String _string;
661 650
662 /** 651 /**
663 * The number of characters in the string. 652 * The number of characters in the string.
664 */ 653 */
665 int _stringLength = 0; 654 int _stringLength = 0;
666 655
667 /** 656 /**
668 * The index, relative to the string, of the last character that was read. 657 * The index, relative to the string, of the last character that was read.
669 */ 658 */
670 int _charOffset = 0; 659 int _charOffset = 0;
671 660
672 /** 661 /**
673 * Initialize a newly created scanner to scan the characters in the given stri ng. 662 * Initialize a newly created scanner to scan the characters in the given stri ng.
674 * @param source the source being scanned 663 * @param source the source being scanned
675 * @param string the string from which characters will be read 664 * @param string the string from which characters will be read
676 */ 665 */
677 StringScanner(Source source, String string) : super(source) { 666 StringScanner(Source source, String string) : super(source) {
678 this._string = string; 667 this._string = string;
679 this._stringLength = string.length; 668 this._stringLength = string.length;
680 this._charOffset = -1; 669 this._charOffset = -1;
681 } 670 }
682 int get offset => _charOffset; 671 int get offset => _charOffset;
683 void set offset(int offset2) { 672 void set offset(int offset2) {
684 _charOffset = offset2; 673 _charOffset = offset2;
685 } 674 }
686 int advance() { 675 int advance() {
687 if (++_charOffset < _stringLength) { 676 if (++_charOffset < _stringLength) {
688 return _string.codeUnitAt(_charOffset); 677 return _string.codeUnitAt(_charOffset);
689 } 678 }
690 _charOffset = _stringLength; 679 _charOffset = _stringLength;
691 return -1; 680 return -1;
692 } 681 }
693 String getString(int start, int endDelta) => _string.substring(start, _charOff set + 1 + endDelta); 682 String getString(int start, int endDelta) => _string.substring(start, _charOff set + 1 + endDelta);
694 int peek() { 683 int peek() {
695 if (_charOffset + 1 < _stringLength) { 684 if (_charOffset + 1 < _stringLength) {
696 return _string.codeUnitAt(_charOffset + 1); 685 return _string.codeUnitAt(_charOffset + 1);
697 } 686 }
698 return -1; 687 return -1;
699 } 688 }
700 } 689 }
701
702 /** 690 /**
703 * Instances of the class {@code CharBufferScanner} implement a scanner that rea ds from a character 691 * Instances of the class {@code CharBufferScanner} implement a scanner that rea ds from a character
704 * buffer. The scanning logic is in the superclass. 692 * buffer. The scanning logic is in the superclass.
705 * @coverage dart.engine.html 693 * @coverage dart.engine.html
706 */ 694 */
707 class CharBufferScanner extends AbstractScanner { 695 class CharBufferScanner extends AbstractScanner {
708 696
709 /** 697 /**
710 * The buffer from which characters will be read. 698 * The buffer from which characters will be read.
711 */ 699 */
712 CharSequence _buffer; 700 CharSequence _buffer;
713 701
714 /** 702 /**
715 * The number of characters in the buffer. 703 * The number of characters in the buffer.
716 */ 704 */
717 int _bufferLength = 0; 705 int _bufferLength = 0;
718 706
719 /** 707 /**
720 * The index of the last character that was read. 708 * The index of the last character that was read.
721 */ 709 */
722 int _charOffset = 0; 710 int _charOffset = 0;
723 711
724 /** 712 /**
725 * Initialize a newly created scanner to scan the characters in the given char acter buffer. 713 * Initialize a newly created scanner to scan the characters in the given char acter buffer.
726 * @param source the source being scanned 714 * @param source the source being scanned
727 * @param buffer the buffer from which characters will be read 715 * @param buffer the buffer from which characters will be read
728 */ 716 */
729 CharBufferScanner(Source source, CharSequence buffer) : super(source) { 717 CharBufferScanner(Source source, CharSequence buffer) : super(source) {
730 this._buffer = buffer; 718 this._buffer = buffer;
731 this._bufferLength = buffer.length(); 719 this._bufferLength = buffer.length();
732 this._charOffset = -1; 720 this._charOffset = -1;
733 } 721 }
734 int get offset => _charOffset; 722 int get offset => _charOffset;
735 int advance() { 723 int advance() {
736 if (++_charOffset < _bufferLength) { 724 if (++_charOffset < _bufferLength) {
737 return _buffer.charAt(_charOffset); 725 return _buffer.charAt(_charOffset);
738 } 726 }
739 _charOffset = _bufferLength; 727 _charOffset = _bufferLength;
740 return -1; 728 return -1;
741 } 729 }
742 String getString(int start, int endDelta) => _buffer.subSequence(start, _charO ffset + 1 + endDelta).toString(); 730 String getString(int start, int endDelta) => _buffer.subSequence(start, _charO ffset + 1 + endDelta).toString();
743 int peek() { 731 int peek() {
744 if (_charOffset + 1 < _bufferLength) { 732 if (_charOffset + 1 < _bufferLength) {
745 return _buffer.charAt(_charOffset + 1); 733 return _buffer.charAt(_charOffset + 1);
746 } 734 }
747 return -1; 735 return -1;
748 } 736 }
749 } 737 }
750
751 /** 738 /**
752 * Instances of the class {@code ToSourceVisitor} write a source representation of a visited XML 739 * Instances of the class {@code ToSourceVisitor} write a source representation of a visited XML
753 * node (and all of it's children) to a writer. 740 * node (and all of it's children) to a writer.
754 * @coverage dart.engine.html 741 * @coverage dart.engine.html
755 */ 742 */
756 class ToSourceVisitor implements XmlVisitor<Object> { 743 class ToSourceVisitor implements XmlVisitor<Object> {
757 744
758 /** 745 /**
759 * The writer to which the source is to be written. 746 * The writer to which the source is to be written.
760 */ 747 */
761 PrintWriter _writer; 748 PrintWriter _writer;
762 749
763 /** 750 /**
764 * Initialize a newly created visitor to write source code representing the vi sited nodes to the 751 * Initialize a newly created visitor to write source code representing the vi sited nodes to the
765 * given writer. 752 * given writer.
766 * @param writer the writer to which the source is to be written 753 * @param writer the writer to which the source is to be written
767 */ 754 */
768 ToSourceVisitor(PrintWriter writer) { 755 ToSourceVisitor(PrintWriter writer) {
769 this._writer = writer; 756 this._writer = writer;
770 } 757 }
771 Object visitHtmlUnit(HtmlUnit node) { 758 Object visitHtmlUnit(HtmlUnit node) {
772 for (XmlTagNode child in node.tagNodes) { 759 for (XmlTagNode child in node.tagNodes) {
(...skipping 29 matching lines...) Expand all
802 if (node.closingTag != null) { 789 if (node.closingTag != null) {
803 for (XmlTagNode child in node.tagNodes) { 790 for (XmlTagNode child in node.tagNodes) {
804 visit(child); 791 visit(child);
805 } 792 }
806 _writer.print("</"); 793 _writer.print("</");
807 _writer.print(tagName); 794 _writer.print(tagName);
808 _writer.print(">"); 795 _writer.print(">");
809 } 796 }
810 return null; 797 return null;
811 } 798 }
812 799
813 /** 800 /**
814 * Safely visit the given node. 801 * Safely visit the given node.
815 * @param node the node to be visited 802 * @param node the node to be visited
816 */ 803 */
817 void visit(XmlNode node) { 804 void visit(XmlNode node) {
818 if (node != null) { 805 if (node != null) {
819 node.accept(this); 806 node.accept(this);
820 } 807 }
821 } 808 }
822 } 809 }
823
824 /** 810 /**
825 * The enumeration {@code TokenType} defines the types of tokens that can be ret urned by the 811 * The enumeration {@code TokenType} defines the types of tokens that can be ret urned by the
826 * scanner. 812 * scanner.
827 * @coverage dart.engine.html 813 * @coverage dart.engine.html
828 */ 814 */
829 class TokenType implements Comparable<TokenType> { 815 class TokenType implements Comparable<TokenType> {
830 816
831 /** 817 /**
832 * The type of the token that marks the end of the input. 818 * The type of the token that marks the end of the input.
833 */ 819 */
834 static final TokenType EOF = new TokenType_EOF('EOF', 0, ""); 820 static final TokenType EOF = new TokenType_EOF('EOF', 0, "");
835 static final TokenType EQ = new TokenType('EQ', 1, "="); 821 static final TokenType EQ = new TokenType('EQ', 1, "=");
836 static final TokenType GT = new TokenType('GT', 2, ">"); 822 static final TokenType GT = new TokenType('GT', 2, ">");
837 static final TokenType LT_SLASH = new TokenType('LT_SLASH', 3, "</"); 823 static final TokenType LT_SLASH = new TokenType('LT_SLASH', 3, "</");
838 static final TokenType LT = new TokenType('LT', 4, "<"); 824 static final TokenType LT = new TokenType('LT', 4, "<");
839 static final TokenType SLASH_GT = new TokenType('SLASH_GT', 5, "/>"); 825 static final TokenType SLASH_GT = new TokenType('SLASH_GT', 5, "/>");
840 static final TokenType COMMENT = new TokenType('COMMENT', 6, null); 826 static final TokenType COMMENT = new TokenType('COMMENT', 6, null);
841 static final TokenType DECLARATION = new TokenType('DECLARATION', 7, null); 827 static final TokenType DECLARATION = new TokenType('DECLARATION', 7, null);
842 static final TokenType DIRECTIVE = new TokenType('DIRECTIVE', 8, null); 828 static final TokenType DIRECTIVE = new TokenType('DIRECTIVE', 8, null);
843 static final TokenType STRING = new TokenType('STRING', 9, null); 829 static final TokenType STRING = new TokenType('STRING', 9, null);
844 static final TokenType TAG = new TokenType('TAG', 10, null); 830 static final TokenType TAG = new TokenType('TAG', 10, null);
845 static final TokenType TEXT = new TokenType('TEXT', 11, null); 831 static final TokenType TEXT = new TokenType('TEXT', 11, null);
846 static final List<TokenType> values = [EOF, EQ, GT, LT_SLASH, LT, SLASH_GT, CO MMENT, DECLARATION, DIRECTIVE, STRING, TAG, TEXT]; 832 static final List<TokenType> values = [EOF, EQ, GT, LT_SLASH, LT, SLASH_GT, CO MMENT, DECLARATION, DIRECTIVE, STRING, TAG, TEXT];
847 833
848 /// The name of this enum constant, as declared in the enum declaration. 834 /// The name of this enum constant, as declared in the enum declaration.
849 final String name; 835 final String name;
850 836
851 /// The position in the enum declaration. 837 /// The position in the enum declaration.
852 final int ordinal; 838 final int ordinal;
853 839
854 /** 840 /**
855 * The lexeme that defines this type of token, or {@code null} if there is mor e than one possible 841 * The lexeme that defines this type of token, or {@code null} if there is mor e than one possible
856 * lexeme for this type of token. 842 * lexeme for this type of token.
857 */ 843 */
858 String _lexeme; 844 String _lexeme;
859 TokenType(this.name, this.ordinal, String lexeme) { 845 TokenType(this.name, this.ordinal, String lexeme) {
860 this._lexeme = lexeme; 846 this._lexeme = lexeme;
861 } 847 }
862 848
863 /** 849 /**
864 * Return the lexeme that defines this type of token, or {@code null} if there is more than one 850 * Return the lexeme that defines this type of token, or {@code null} if there is more than one
865 * possible lexeme for this type of token. 851 * possible lexeme for this type of token.
866 * @return the lexeme that defines this type of token 852 * @return the lexeme that defines this type of token
867 */ 853 */
868 String get lexeme => _lexeme; 854 String get lexeme => _lexeme;
869 int compareTo(TokenType other) => ordinal - other.ordinal; 855 int compareTo(TokenType other) => ordinal - other.ordinal;
870 String toString() => name; 856 String toString() => name;
871 } 857 }
872 class TokenType_EOF extends TokenType { 858 class TokenType_EOF extends TokenType {
873 TokenType_EOF(String name, int ordinal, String arg0) : super(name, ordinal, ar g0); 859 TokenType_EOF(String name, int ordinal, String arg0) : super(name, ordinal, ar g0);
874 String toString() => "-eof-"; 860 String toString() => "-eof-";
875 } 861 }
876
877 /** 862 /**
878 * Instances of {@code XmlAttributeNode} represent name/value pairs owned by an {@link XmlTagNode}. 863 * Instances of {@code XmlAttributeNode} represent name/value pairs owned by an {@link XmlTagNode}.
879 * @coverage dart.engine.html 864 * @coverage dart.engine.html
880 */ 865 */
881 class XmlAttributeNode extends XmlNode { 866 class XmlAttributeNode extends XmlNode {
882 Token _name; 867 Token _name;
883 Token _equals; 868 Token _equals;
884 Token _value; 869 Token _value;
885 870
886 /** 871 /**
887 * Construct a new instance representing an XML attribute. 872 * Construct a new instance representing an XML attribute.
888 * @param name the name token (not {@code null}). This may be a zero length to ken if the attribute 873 * @param name the name token (not {@code null}). This may be a zero length to ken if the attribute
889 * is badly formed. 874 * is badly formed.
890 * @param equals the equals sign or {@code null} if none 875 * @param equals the equals sign or {@code null} if none
891 * @param value the value token (not {@code null}) 876 * @param value the value token (not {@code null})
892 */ 877 */
893 XmlAttributeNode(Token name, Token equals, Token value) { 878 XmlAttributeNode(Token name, Token equals, Token value) {
894 this._name = name; 879 this._name = name;
895 this._equals = equals; 880 this._equals = equals;
896 this._value = value; 881 this._value = value;
897 } 882 }
898 accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this); 883 accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this);
899 Token get beginToken => _name; 884 Token get beginToken => _name;
900 Token get endToken => _value; 885 Token get endToken => _value;
901 886
902 /** 887 /**
903 * Answer the equals sign token that appears between the name and value tokens . This may be{@code null} if the attribute is badly formed. 888 * Answer the equals sign token that appears between the name and value tokens . This may be{@code null} if the attribute is badly formed.
904 * @return the token or {@code null} if there is no equals sign between the na me and value 889 * @return the token or {@code null} if there is no equals sign between the na me and value
905 */ 890 */
906 Token get equals => _equals; 891 Token get equals => _equals;
907 892
908 /** 893 /**
909 * Answer the attribute name. This may be a zero length token if the attribute is badly formed. 894 * Answer the attribute name. This may be a zero length token if the attribute is badly formed.
910 * @return the name (not {@code null}) 895 * @return the name (not {@code null})
911 */ 896 */
912 Token get name => _name; 897 Token get name => _name;
913 898
914 /** 899 /**
915 * Answer the lexeme for the value token without the leading and trailing quot es. 900 * Answer the lexeme for the value token without the leading and trailing quot es.
916 * @return the text or {@code null} if the value is not specified 901 * @return the text or {@code null} if the value is not specified
917 */ 902 */
918 String get text { 903 String get text {
919 if (_value == null) { 904 if (_value == null) {
920 return null; 905 return null;
921 } 906 }
922 String text = _value.lexeme; 907 String text = _value.lexeme;
923 int len = text.length; 908 int len = text.length;
924 if (len > 0) { 909 if (len > 0) {
925 if (text.codeUnitAt(0) == 0x22) { 910 if (text.codeUnitAt(0) == 0x22) {
926 if (len > 1 && text.codeUnitAt(len - 1) == 0x22) { 911 if (len > 1 && text.codeUnitAt(len - 1) == 0x22) {
927 return text.substring(1, len - 1); 912 return text.substring(1, len - 1);
928 } else { 913 } else {
929 return text.substring(1); 914 return text.substring(1);
930 } 915 }
931 } else if (text.codeUnitAt(0) == 0x27) { 916 } else if (text.codeUnitAt(0) == 0x27) {
932 if (len > 1 && text.codeUnitAt(len - 1) == 0x27) { 917 if (len > 1 && text.codeUnitAt(len - 1) == 0x27) {
933 return text.substring(1, len - 1); 918 return text.substring(1, len - 1);
934 } else { 919 } else {
935 return text.substring(1); 920 return text.substring(1);
936 } 921 }
937 } 922 }
938 } 923 }
939 return text; 924 return text;
940 } 925 }
941 926
942 /** 927 /**
943 * Answer the attribute value. A properly formed value will start and end with matching quote 928 * Answer the attribute value. A properly formed value will start and end with matching quote
944 * characters, but the value returned may not be properly formed. 929 * characters, but the value returned may not be properly formed.
945 * @return the value or {@code null} if this represents a badly formed attribu te 930 * @return the value or {@code null} if this represents a badly formed attribu te
946 */ 931 */
947 Token get value => _value; 932 Token get value => _value;
948 void visitChildren(XmlVisitor<Object> visitor) { 933 void visitChildren(XmlVisitor<Object> visitor) {
949 } 934 }
950 } 935 }
951
952 /** 936 /**
953 * The interface {@code XmlVisitor} defines the behavior of objects that can be used to visit an{@link XmlNode} structure. 937 * The interface {@code XmlVisitor} defines the behavior of objects that can be used to visit an{@link XmlNode} structure.
954 * @coverage dart.engine.html 938 * @coverage dart.engine.html
955 */ 939 */
956 abstract class XmlVisitor<R> { 940 abstract class XmlVisitor<R> {
957 R visitHtmlUnit(HtmlUnit htmlUnit); 941 R visitHtmlUnit(HtmlUnit htmlUnit);
958 R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode); 942 R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode);
959 R visitXmlTagNode(XmlTagNode xmlTagNode); 943 R visitXmlTagNode(XmlTagNode xmlTagNode);
960 } 944 }
961
962 /** 945 /**
963 * Instances of {@code HtmlScanner} receive and scan HTML content from a {@link Source}.<br/> 946 * Instances of {@code HtmlScanner} receive and scan HTML content from a {@link Source}.<br/>
964 * For example, the following code scans HTML source and returns the result: 947 * For example, the following code scans HTML source and returns the result:
965 * <pre> 948 * <pre>
966 * HtmlScanner scanner = new HtmlScanner(source); 949 * HtmlScanner scanner = new HtmlScanner(source);
967 * source.getContents(scanner); 950 * source.getContents(scanner);
968 * return scanner.getResult(); 951 * return scanner.getResult();
969 * </pre> 952 * </pre>
970 * @coverage dart.engine.html 953 * @coverage dart.engine.html
971 */ 954 */
972 class HtmlScanner implements Source_ContentReceiver { 955 class HtmlScanner implements Source_ContentReceiver {
973 List<String> _SCRIPT_TAG = <String> ["script"]; 956 List<String> _SCRIPT_TAG = <String> ["script"];
974 957
975 /** 958 /**
976 * The source being scanned (not {@code null}) 959 * The source being scanned (not {@code null})
977 */ 960 */
978 Source _source; 961 Source _source;
979 962
980 /** 963 /**
981 * The time at which the contents of the source were last set. 964 * The time at which the contents of the source were last set.
982 */ 965 */
983 int _modificationTime = 0; 966 int _modificationTime = 0;
984 967
985 /** 968 /**
986 * The scanner used to scan the source 969 * The scanner used to scan the source
987 */ 970 */
988 AbstractScanner _scanner; 971 AbstractScanner _scanner;
989 972
990 /** 973 /**
991 * The first token in the token stream. 974 * The first token in the token stream.
992 */ 975 */
993 Token _token; 976 Token _token;
994 977
995 /** 978 /**
996 * Construct a new instance to scan the specified source. 979 * Construct a new instance to scan the specified source.
997 * @param source the source to be scanned (not {@code null}) 980 * @param source the source to be scanned (not {@code null})
998 */ 981 */
999 HtmlScanner(Source source) { 982 HtmlScanner(Source source) {
1000 this._source = source; 983 this._source = source;
1001 } 984 }
1002 void accept(CharBuffer contents, int modificationTime2) { 985 void accept(CharBuffer contents, int modificationTime2) {
1003 this._modificationTime = modificationTime2; 986 this._modificationTime = modificationTime2;
1004 _scanner = new CharBufferScanner(_source, contents); 987 _scanner = new CharBufferScanner(_source, contents);
1005 _scanner.passThroughElements = _SCRIPT_TAG; 988 _scanner.passThroughElements = _SCRIPT_TAG;
1006 _token = _scanner.tokenize(); 989 _token = _scanner.tokenize();
1007 } 990 }
1008 void accept2(String contents, int modificationTime2) { 991 void accept2(String contents, int modificationTime2) {
1009 this._modificationTime = modificationTime2; 992 this._modificationTime = modificationTime2;
1010 _scanner = new StringScanner(_source, contents); 993 _scanner = new StringScanner(_source, contents);
1011 _scanner.passThroughElements = _SCRIPT_TAG; 994 _scanner.passThroughElements = _SCRIPT_TAG;
1012 _token = _scanner.tokenize(); 995 _token = _scanner.tokenize();
1013 } 996 }
1014 997
1015 /** 998 /**
1016 * Answer the result of scanning the source 999 * Answer the result of scanning the source
1017 * @return the result (not {@code null}) 1000 * @return the result (not {@code null})
1018 */ 1001 */
1019 HtmlScanResult get result => new HtmlScanResult(_modificationTime, _token, _sc anner.lineStarts); 1002 HtmlScanResult get result => new HtmlScanResult(_modificationTime, _token, _sc anner.lineStarts);
1020 } 1003 }
1021
1022 /** 1004 /**
1023 * Instances of the class {@code XmlParser} are used to parse tokens into a AST structure comprised 1005 * Instances of the class {@code XmlParser} are used to parse tokens into a AST structure comprised
1024 * of {@link XmlNode}s. 1006 * of {@link XmlNode}s.
1025 * @coverage dart.engine.html 1007 * @coverage dart.engine.html
1026 */ 1008 */
1027 class XmlParser { 1009 class XmlParser {
1028 1010
1029 /** 1011 /**
1030 * The source being parsed. 1012 * The source being parsed.
1031 */ 1013 */
1032 Source _source; 1014 Source _source;
1033 1015
1034 /** 1016 /**
1035 * The next token to be parsed. 1017 * The next token to be parsed.
1036 */ 1018 */
1037 Token _currentToken; 1019 Token _currentToken;
1038 1020
1039 /** 1021 /**
1040 * Construct a parser for the specified source. 1022 * Construct a parser for the specified source.
1041 * @param source the source being parsed 1023 * @param source the source being parsed
1042 */ 1024 */
1043 XmlParser(Source source) { 1025 XmlParser(Source source) {
1044 this._source = source; 1026 this._source = source;
1045 } 1027 }
1046 1028
1047 /** 1029 /**
1048 * Answer the source being parsed. 1030 * Answer the source being parsed.
1049 * @return the source 1031 * @return the source
1050 */ 1032 */
1051 Source get source => _source; 1033 Source get source => _source;
1052 1034
1053 /** 1035 /**
1054 * Answer {@code true} if the specified tag is self closing and thus should ne ver have content or 1036 * Answer {@code true} if the specified tag is self closing and thus should ne ver have content or
1055 * child tag nodes. 1037 * child tag nodes.
1056 * @param tag the tag (not {@code null}) 1038 * @param tag the tag (not {@code null})
1057 * @return {@code true} if self closing 1039 * @return {@code true} if self closing
1058 */ 1040 */
1059 bool isSelfClosing(Token tag) => false; 1041 bool isSelfClosing(Token tag) => false;
1060 1042
1061 /** 1043 /**
1062 * Parse the entire token stream and in the process, advance the current token to the end of the 1044 * Parse the entire token stream and in the process, advance the current token to the end of the
1063 * token stream. 1045 * token stream.
1064 * @return the list of tag nodes found (not {@code null}, contains no {@code n ull}) 1046 * @return the list of tag nodes found (not {@code null}, contains no {@code n ull})
1065 */ 1047 */
1066 List<XmlTagNode> parseTopTagNodes(Token firstToken) { 1048 List<XmlTagNode> parseTopTagNodes(Token firstToken) {
1067 _currentToken = firstToken; 1049 _currentToken = firstToken;
1068 List<XmlTagNode> tagNodes = new List<XmlTagNode>(); 1050 List<XmlTagNode> tagNodes = new List<XmlTagNode>();
1069 while (true) { 1051 while (true) {
1070 while (true) { 1052 while (true) {
1071 if (_currentToken.type == TokenType.LT) { 1053 if (_currentToken.type == TokenType.LT) {
1072 tagNodes.add(parseTagNode()); 1054 tagNodes.add(parseTagNode());
1073 } else if (_currentToken.type == TokenType.DECLARATION || _currentToken. type == TokenType.DIRECTIVE || _currentToken.type == TokenType.COMMENT) { 1055 } else if (_currentToken.type == TokenType.DECLARATION || _currentToken. type == TokenType.DIRECTIVE || _currentToken.type == TokenType.COMMENT) {
1074 _currentToken = _currentToken.next; 1056 _currentToken = _currentToken.next;
1075 } else if (_currentToken.type == TokenType.EOF) { 1057 } else if (_currentToken.type == TokenType.EOF) {
1076 return tagNodes; 1058 return tagNodes;
1077 } else { 1059 } else {
1078 reportUnexpectedToken(); 1060 reportUnexpectedToken();
1079 _currentToken = _currentToken.next; 1061 _currentToken = _currentToken.next;
1080 } 1062 }
1081 break; 1063 break;
1082 } 1064 }
1083 } 1065 }
1084 } 1066 }
1085 1067
1086 /** 1068 /**
1087 * Answer the current token. 1069 * Answer the current token.
1088 * @return the current token 1070 * @return the current token
1089 */ 1071 */
1090 Token get currentToken => _currentToken; 1072 Token get currentToken => _currentToken;
1091 1073
1092 /** 1074 /**
1093 * Insert a synthetic token of the specified type before the current token 1075 * Insert a synthetic token of the specified type before the current token
1094 * @param type the type of token to be inserted (not {@code null}) 1076 * @param type the type of token to be inserted (not {@code null})
1095 * @return the synthetic token that was inserted (not {@code null}) 1077 * @return the synthetic token that was inserted (not {@code null})
1096 */ 1078 */
1097 Token insertSyntheticToken(TokenType type) { 1079 Token insertSyntheticToken(TokenType type) {
1098 Token token = new Token.con2(type, _currentToken.offset, ""); 1080 Token token = new Token.con2(type, _currentToken.offset, "");
1099 _currentToken.previous.setNext(token); 1081 _currentToken.previous.setNext(token);
1100 token.setNext(_currentToken); 1082 token.setNext(_currentToken);
1101 return token; 1083 return token;
1102 } 1084 }
1103 1085
1104 /** 1086 /**
1105 * Parse the token stream for an attribute. This method advances the current t oken over the 1087 * Parse the token stream for an attribute. This method advances the current t oken over the
1106 * attribute, but should not be called if the {@link #currentToken} is not {@l ink TokenType#TAG}. 1088 * attribute, but should not be called if the {@link #currentToken} is not {@l ink TokenType#TAG}.
1107 * @return the attribute (not {@code null}) 1089 * @return the attribute (not {@code null})
1108 */ 1090 */
1109 XmlAttributeNode parseAttribute() { 1091 XmlAttributeNode parseAttribute() {
1110 Token name = _currentToken; 1092 Token name = _currentToken;
1111 _currentToken = _currentToken.next; 1093 _currentToken = _currentToken.next;
1112 Token equals; 1094 Token equals;
1113 if (identical(_currentToken.type, TokenType.EQ)) { 1095 if (identical(_currentToken.type, TokenType.EQ)) {
1114 equals = _currentToken; 1096 equals = _currentToken;
1115 _currentToken = _currentToken.next; 1097 _currentToken = _currentToken.next;
1116 } else { 1098 } else {
1117 reportUnexpectedToken(); 1099 reportUnexpectedToken();
1118 equals = insertSyntheticToken(TokenType.EQ); 1100 equals = insertSyntheticToken(TokenType.EQ);
1119 } 1101 }
1120 Token value; 1102 Token value;
1121 if (identical(_currentToken.type, TokenType.STRING)) { 1103 if (identical(_currentToken.type, TokenType.STRING)) {
1122 value = _currentToken; 1104 value = _currentToken;
1123 _currentToken = _currentToken.next; 1105 _currentToken = _currentToken.next;
1124 } else { 1106 } else {
1125 reportUnexpectedToken(); 1107 reportUnexpectedToken();
1126 value = insertSyntheticToken(TokenType.STRING); 1108 value = insertSyntheticToken(TokenType.STRING);
1127 } 1109 }
1128 return new XmlAttributeNode(name, equals, value); 1110 return new XmlAttributeNode(name, equals, value);
1129 } 1111 }
1130 1112
1131 /** 1113 /**
1132 * Parse the stream for a sequence of attributes. This method advances the cur rent token to the 1114 * Parse the stream for a sequence of attributes. This method advances the cur rent token to the
1133 * next {@link TokenType#GT}, {@link TokenType#SLASH_GT}, or {@link TokenType# EOF}. 1115 * next {@link TokenType#GT}, {@link TokenType#SLASH_GT}, or {@link TokenType# EOF}.
1134 * @return a collection of zero or more attributes (not {@code null}, contains no {@code null}s) 1116 * @return a collection of zero or more attributes (not {@code null}, contains no {@code null}s)
1135 */ 1117 */
1136 List<XmlAttributeNode> parseAttributes() { 1118 List<XmlAttributeNode> parseAttributes() {
1137 TokenType type2 = _currentToken.type; 1119 TokenType type2 = _currentToken.type;
1138 if (identical(type2, TokenType.GT) || identical(type2, TokenType.SLASH_GT) | | identical(type2, TokenType.EOF)) { 1120 if (identical(type2, TokenType.GT) || identical(type2, TokenType.SLASH_GT) | | identical(type2, TokenType.EOF)) {
1139 return XmlTagNode.NO_ATTRIBUTES; 1121 return XmlTagNode.NO_ATTRIBUTES;
1140 } 1122 }
1141 List<XmlAttributeNode> attributes = new List<XmlAttributeNode>(); 1123 List<XmlAttributeNode> attributes = new List<XmlAttributeNode>();
1142 while (true) { 1124 while (true) {
1143 while (true) { 1125 while (true) {
1144 if (_currentToken.type == TokenType.GT || _currentToken.type == TokenTyp e.SLASH_GT || _currentToken.type == TokenType.EOF) { 1126 if (_currentToken.type == TokenType.GT || _currentToken.type == TokenTyp e.SLASH_GT || _currentToken.type == TokenType.EOF) {
1145 return attributes; 1127 return attributes;
1146 } else if (_currentToken.type == TokenType.TAG) { 1128 } else if (_currentToken.type == TokenType.TAG) {
1147 attributes.add(parseAttribute()); 1129 attributes.add(parseAttribute());
1148 } else { 1130 } else {
1149 reportUnexpectedToken(); 1131 reportUnexpectedToken();
1150 _currentToken = _currentToken.next; 1132 _currentToken = _currentToken.next;
1151 } 1133 }
1152 break; 1134 break;
1153 } 1135 }
1154 } 1136 }
1155 } 1137 }
1156 1138
1157 /** 1139 /**
1158 * Parse the stream for a sequence of tag nodes existing within a parent tag n ode. This method 1140 * Parse the stream for a sequence of tag nodes existing within a parent tag n ode. This method
1159 * advances the current token to the next {@link TokenType#LT_SLASH} or {@link TokenType#EOF}. 1141 * advances the current token to the next {@link TokenType#LT_SLASH} or {@link TokenType#EOF}.
1160 * @return a list of nodes (not {@code null}, contains no {@code null}s) 1142 * @return a list of nodes (not {@code null}, contains no {@code null}s)
1161 */ 1143 */
1162 List<XmlTagNode> parseChildTagNodes() { 1144 List<XmlTagNode> parseChildTagNodes() {
1163 TokenType type2 = _currentToken.type; 1145 TokenType type2 = _currentToken.type;
1164 if (identical(type2, TokenType.LT_SLASH) || identical(type2, TokenType.EOF)) { 1146 if (identical(type2, TokenType.LT_SLASH) || identical(type2, TokenType.EOF)) {
1165 return XmlTagNode.NO_TAG_NODES; 1147 return XmlTagNode.NO_TAG_NODES;
1166 } 1148 }
1167 List<XmlTagNode> nodes = new List<XmlTagNode>(); 1149 List<XmlTagNode> nodes = new List<XmlTagNode>();
1168 while (true) { 1150 while (true) {
1169 while (true) { 1151 while (true) {
1170 if (_currentToken.type == TokenType.LT) { 1152 if (_currentToken.type == TokenType.LT) {
1171 nodes.add(parseTagNode()); 1153 nodes.add(parseTagNode());
1172 } else if (_currentToken.type == TokenType.LT_SLASH || _currentToken.typ e == TokenType.EOF) { 1154 } else if (_currentToken.type == TokenType.LT_SLASH || _currentToken.typ e == TokenType.EOF) {
1173 return nodes; 1155 return nodes;
1174 } else if (_currentToken.type == TokenType.COMMENT) { 1156 } else if (_currentToken.type == TokenType.COMMENT) {
1175 _currentToken = _currentToken.next; 1157 _currentToken = _currentToken.next;
1176 } else { 1158 } else {
1177 reportUnexpectedToken(); 1159 reportUnexpectedToken();
1178 _currentToken = _currentToken.next; 1160 _currentToken = _currentToken.next;
1179 } 1161 }
1180 break; 1162 break;
1181 } 1163 }
1182 } 1164 }
1183 } 1165 }
1184 1166
1185 /** 1167 /**
1186 * Parse the token stream for the next tag node. This method advances current token over the 1168 * Parse the token stream for the next tag node. This method advances current token over the
1187 * parsed tag node, but should only be called if the current token is {@link T okenType#LT} 1169 * parsed tag node, but should only be called if the current token is {@link T okenType#LT}
1188 * @return the tag node or {@code null} if none found 1170 * @return the tag node or {@code null} if none found
1189 */ 1171 */
1190 XmlTagNode parseTagNode() { 1172 XmlTagNode parseTagNode() {
1191 Token nodeStart = _currentToken; 1173 Token nodeStart = _currentToken;
1192 _currentToken = _currentToken.next; 1174 _currentToken = _currentToken.next;
1193 Token tag; 1175 Token tag;
1194 if (identical(_currentToken.type, TokenType.TAG)) { 1176 if (identical(_currentToken.type, TokenType.TAG)) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 Token nodeEnd; 1212 Token nodeEnd;
1231 if (identical(_currentToken.type, TokenType.GT)) { 1213 if (identical(_currentToken.type, TokenType.GT)) {
1232 nodeEnd = _currentToken; 1214 nodeEnd = _currentToken;
1233 _currentToken = _currentToken.next; 1215 _currentToken = _currentToken.next;
1234 } else { 1216 } else {
1235 reportUnexpectedToken(); 1217 reportUnexpectedToken();
1236 nodeEnd = insertSyntheticToken(TokenType.GT); 1218 nodeEnd = insertSyntheticToken(TokenType.GT);
1237 } 1219 }
1238 return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, co ntentEnd, closingTag, nodeEnd); 1220 return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, co ntentEnd, closingTag, nodeEnd);
1239 } 1221 }
1240 1222
1241 /** 1223 /**
1242 * Report the current token as unexpected 1224 * Report the current token as unexpected
1243 */ 1225 */
1244 void reportUnexpectedToken() { 1226 void reportUnexpectedToken() {
1245 } 1227 }
1246 } 1228 }
1247
1248 /** 1229 /**
1249 * Instances of {@code XmlTagNode} represent XML or HTML elements such as {@code <p>} and{@code <body foo="bar"> ... </body>}. 1230 * Instances of {@code XmlTagNode} represent XML or HTML elements such as {@code <p>} and{@code <body foo="bar"> ... </body>}.
1250 * @coverage dart.engine.html 1231 * @coverage dart.engine.html
1251 */ 1232 */
1252 class XmlTagNode extends XmlNode { 1233 class XmlTagNode extends XmlNode {
1253 1234
1254 /** 1235 /**
1255 * Constant representing empty list of attributes. 1236 * Constant representing empty list of attributes.
1256 */ 1237 */
1257 static List<XmlAttributeNode> NO_ATTRIBUTES = new UnmodifiableListView(new Lis t<XmlAttributeNode>()); 1238 static List<XmlAttributeNode> NO_ATTRIBUTES = new UnmodifiableListView(new Lis t<XmlAttributeNode>());
1258 1239
1259 /** 1240 /**
1260 * Constant representing empty list of tag nodes. 1241 * Constant representing empty list of tag nodes.
1261 */ 1242 */
1262 static List<XmlTagNode> NO_TAG_NODES = new UnmodifiableListView(new List<XmlTa gNode>()); 1243 static List<XmlTagNode> NO_TAG_NODES = new UnmodifiableListView(new List<XmlTa gNode>());
1263 1244
1264 /** 1245 /**
1265 * The starting {@link TokenType#LT} token (not {@code null}). 1246 * The starting {@link TokenType#LT} token (not {@code null}).
1266 */ 1247 */
1267 Token _nodeStart; 1248 Token _nodeStart;
1268 1249
1269 /** 1250 /**
1270 * The {@link TokenType#TAG} token after the starting '&lt;' (not {@code null} ). 1251 * The {@link TokenType#TAG} token after the starting '&lt;' (not {@code null} ).
1271 */ 1252 */
1272 Token _tag; 1253 Token _tag;
1273 1254
1274 /** 1255 /**
1275 * The attributes contained by the receiver (not {@code null}, contains no {@c ode null}s). 1256 * The attributes contained by the receiver (not {@code null}, contains no {@c ode null}s).
1276 */ 1257 */
1277 List<XmlAttributeNode> _attributes; 1258 List<XmlAttributeNode> _attributes;
1278 1259
1279 /** 1260 /**
1280 * The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the attr ibutes (not{@code null}). The token may be the same token as {@link #nodeEnd} if there are no child{@link #tagNodes}. 1261 * The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the attr ibutes (not{@code null}). The token may be the same token as {@link #nodeEnd} if there are no child{@link #tagNodes}.
1281 */ 1262 */
1282 Token _attributeEnd; 1263 Token _attributeEnd;
1283 1264
1284 /** 1265 /**
1285 * The tag nodes contained in the receiver (not {@code null}, contains no {@co de null}s). 1266 * The tag nodes contained in the receiver (not {@code null}, contains no {@co de null}s).
1286 */ 1267 */
1287 List<XmlTagNode> _tagNodes; 1268 List<XmlTagNode> _tagNodes;
1288 1269
1289 /** 1270 /**
1290 * The token (not {@code null}) after the content, which may be 1271 * The token (not {@code null}) after the content, which may be
1291 * <ul> 1272 * <ul>
1292 * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</ li> 1273 * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</ li>
1293 * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is self 1274 * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is self
1294 * closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li> 1275 * closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li>
1295 * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and i s the last node in 1276 * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and i s the last node in
1296 * the stream {@link TokenType#LT_SLASH} token after the content, or {@code nu ll} if there is no 1277 * the stream {@link TokenType#LT_SLASH} token after the content, or {@code nu ll} if there is no
1297 * content and the attributes ended with {@link TokenType#SLASH_GT}.</li> 1278 * content and the attributes ended with {@link TokenType#SLASH_GT}.</li>
1298 * </ul> 1279 * </ul>
1299 */ 1280 */
1300 Token _contentEnd; 1281 Token _contentEnd;
1301 1282
1302 /** 1283 /**
1303 * The closing {@link TokenType#TAG} after the child elements or {@code null} if there is no 1284 * The closing {@link TokenType#TAG} after the child elements or {@code null} if there is no
1304 * content and the attributes ended with {@link TokenType#SLASH_GT} 1285 * content and the attributes ended with {@link TokenType#SLASH_GT}
1305 */ 1286 */
1306 Token _closingTag; 1287 Token _closingTag;
1307 1288
1308 /** 1289 /**
1309 * The ending {@link TokenType#GT} or {@link TokenType#SLASH_GT} token (not {@ code null}). 1290 * The ending {@link TokenType#GT} or {@link TokenType#SLASH_GT} token (not {@ code null}).
1310 */ 1291 */
1311 Token _nodeEnd; 1292 Token _nodeEnd;
1312 1293
1313 /** 1294 /**
1314 * Construct a new instance representing an XML or HTML element 1295 * Construct a new instance representing an XML or HTML element
1315 * @param nodeStart the starting {@link TokenType#LT} token (not {@code null}) 1296 * @param nodeStart the starting {@link TokenType#LT} token (not {@code null})
1316 * @param tag the {@link TokenType#TAG} token after the starting '&lt;' (not { @code null}). 1297 * @param tag the {@link TokenType#TAG} token after the starting '&lt;' (not { @code null}).
1317 * @param attributes the attributes associated with this element or {@link #NO _ATTRIBUTES} (not{@code null}, contains no {@code null}s) 1298 * @param attributes the attributes associated with this element or {@link #NO _ATTRIBUTES} (not{@code null}, contains no {@code null}s)
1318 * @param attributeEnd The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the 1299 * @param attributeEnd The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the
1319 * attributes (not {@code null}). The token may be the same token as {@link #n odeEnd} if 1300 * attributes (not {@code null}). The token may be the same token as {@link #n odeEnd} if
1320 * there are no child {@link #tagNodes}. 1301 * there are no child {@link #tagNodes}.
1321 * @param tagNodes child tag nodes of the receiver or {@link #NO_TAG_NODES} (n ot {@code null}, 1302 * @param tagNodes child tag nodes of the receiver or {@link #NO_TAG_NODES} (n ot {@code null},
1322 * contains no {@code null}s) 1303 * contains no {@code null}s)
(...skipping 13 matching lines...) Expand all
1336 this._nodeStart = nodeStart; 1317 this._nodeStart = nodeStart;
1337 this._tag = tag; 1318 this._tag = tag;
1338 this._attributes = becomeParentOfEmpty(attributes, NO_ATTRIBUTES); 1319 this._attributes = becomeParentOfEmpty(attributes, NO_ATTRIBUTES);
1339 this._attributeEnd = attributeEnd; 1320 this._attributeEnd = attributeEnd;
1340 this._tagNodes = becomeParentOfEmpty(tagNodes, NO_TAG_NODES); 1321 this._tagNodes = becomeParentOfEmpty(tagNodes, NO_TAG_NODES);
1341 this._contentEnd = contentEnd; 1322 this._contentEnd = contentEnd;
1342 this._closingTag = closingTag; 1323 this._closingTag = closingTag;
1343 this._nodeEnd = nodeEnd; 1324 this._nodeEnd = nodeEnd;
1344 } 1325 }
1345 accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this); 1326 accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this);
1346 1327
1347 /** 1328 /**
1348 * Answer the attribute with the specified name. 1329 * Answer the attribute with the specified name.
1349 * @param name the attribute name 1330 * @param name the attribute name
1350 * @return the attribute or {@code null} if no matching attribute is found 1331 * @return the attribute or {@code null} if no matching attribute is found
1351 */ 1332 */
1352 XmlAttributeNode getAttribute(String name2) { 1333 XmlAttributeNode getAttribute(String name2) {
1353 for (XmlAttributeNode attribute in _attributes) { 1334 for (XmlAttributeNode attribute in _attributes) {
1354 if (attribute.name.lexeme == name2) { 1335 if (attribute.name.lexeme == name2) {
1355 return attribute; 1336 return attribute;
1356 } 1337 }
1357 } 1338 }
1358 return null; 1339 return null;
1359 } 1340 }
1360 1341
1361 /** 1342 /**
1362 * The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the attr ibutes (not{@code null}). The token may be the same token as {@link #nodeEnd} if there are no child{@link #tagNodes}. 1343 * The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the attr ibutes (not{@code null}). The token may be the same token as {@link #nodeEnd} if there are no child{@link #tagNodes}.
1363 * @return the token (not {@code null}) 1344 * @return the token (not {@code null})
1364 */ 1345 */
1365 Token get attributeEnd => _attributeEnd; 1346 Token get attributeEnd => _attributeEnd;
1366 1347
1367 /** 1348 /**
1368 * Answer the receiver's attributes. Callers should not manipulate the returne d list to edit the 1349 * Answer the receiver's attributes. Callers should not manipulate the returne d list to edit the
1369 * AST structure. 1350 * AST structure.
1370 * @return the attributes (not {@code null}, contains no {@code null}s) 1351 * @return the attributes (not {@code null}, contains no {@code null}s)
1371 */ 1352 */
1372 List<XmlAttributeNode> get attributes => _attributes; 1353 List<XmlAttributeNode> get attributes => _attributes;
1373 1354
1374 /** 1355 /**
1375 * Find the attribute with the given name (see {@link #getAttribute(String)} a nd answer the lexeme 1356 * Find the attribute with the given name (see {@link #getAttribute(String)} a nd answer the lexeme
1376 * for the attribute's value token without the leading and trailing quotes (se e{@link XmlAttributeNode#getText()}). 1357 * for the attribute's value token without the leading and trailing quotes (se e{@link XmlAttributeNode#getText()}).
1377 * @param name the attribute name 1358 * @param name the attribute name
1378 * @return the attribute text or {@code null} if no matching attribute is foun d 1359 * @return the attribute text or {@code null} if no matching attribute is foun d
1379 */ 1360 */
1380 String getAttributeText(String name) { 1361 String getAttributeText(String name) {
1381 XmlAttributeNode attribute = getAttribute(name); 1362 XmlAttributeNode attribute = getAttribute(name);
1382 return attribute != null ? attribute.text : null; 1363 return attribute != null ? attribute.text : null;
1383 } 1364 }
1384 Token get beginToken => _nodeStart; 1365 Token get beginToken => _nodeStart;
1385 1366
1386 /** 1367 /**
1387 * The the closing {@link TokenType#TAG} after the child elements or {@code nu ll} if there is no 1368 * The the closing {@link TokenType#TAG} after the child elements or {@code nu ll} if there is no
1388 * content and the attributes ended with {@link TokenType#SLASH_GT} 1369 * content and the attributes ended with {@link TokenType#SLASH_GT}
1389 * @return the closing tag or {@code null} 1370 * @return the closing tag or {@code null}
1390 */ 1371 */
1391 Token get closingTag => _closingTag; 1372 Token get closingTag => _closingTag;
1392 1373
1393 /** 1374 /**
1394 * Answer a string representing the content contained in the receiver. This in cludes the textual 1375 * Answer a string representing the content contained in the receiver. This in cludes the textual
1395 * representation of any child tag nodes ({@link #getTagNodes()}). Whitespace between '&lt;', 1376 * representation of any child tag nodes ({@link #getTagNodes()}). Whitespace between '&lt;',
1396 * '&lt;/', and '>', '/>' is discarded, but all other whitespace is preserved. 1377 * '&lt;/', and '>', '/>' is discarded, but all other whitespace is preserved.
1397 * @return the content (not {@code null}) 1378 * @return the content (not {@code null})
1398 */ 1379 */
1399 String get content { 1380 String get content {
1400 Token token = _attributeEnd.next; 1381 Token token = _attributeEnd.next;
1401 if (identical(token, _contentEnd)) { 1382 if (identical(token, _contentEnd)) {
1402 return ""; 1383 return "";
1403 } 1384 }
1404 String content = token.lexeme; 1385 String content = token.lexeme;
1405 token = token.next; 1386 token = token.next;
1406 if (identical(token, _contentEnd)) { 1387 if (identical(token, _contentEnd)) {
1407 return content; 1388 return content;
1408 } 1389 }
1409 JavaStringBuilder buffer = new JavaStringBuilder(); 1390 JavaStringBuilder buffer = new JavaStringBuilder();
1410 while (token != _contentEnd) { 1391 while (token != _contentEnd) {
1411 buffer.append(token.lexeme); 1392 buffer.append(token.lexeme);
1412 token = token.next; 1393 token = token.next;
1413 } 1394 }
1414 return buffer.toString(); 1395 return buffer.toString();
1415 } 1396 }
1416 1397
1417 /** 1398 /**
1418 * Answer the token (not {@code null}) after the content, which may be 1399 * Answer the token (not {@code null}) after the content, which may be
1419 * <ul> 1400 * <ul>
1420 * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</ li> 1401 * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</ li>
1421 * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is self 1402 * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is self
1422 * closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li> 1403 * closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li>
1423 * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and i s the last node in 1404 * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and i s the last node in
1424 * the stream {@link TokenType#LT_SLASH} token after the content, or {@code nu ll} if there is no 1405 * the stream {@link TokenType#LT_SLASH} token after the content, or {@code nu ll} if there is no
1425 * content and the attributes ended with {@link TokenType#SLASH_GT}.</li> 1406 * content and the attributes ended with {@link TokenType#SLASH_GT}.</li>
1426 * </ul> 1407 * </ul>
(...skipping 14 matching lines...) Expand all
1441 return _tagNodes[_tagNodes.length - 1].endToken; 1422 return _tagNodes[_tagNodes.length - 1].endToken;
1442 } 1423 }
1443 if (_attributeEnd != null) { 1424 if (_attributeEnd != null) {
1444 return _attributeEnd; 1425 return _attributeEnd;
1445 } 1426 }
1446 if (!_attributes.isEmpty) { 1427 if (!_attributes.isEmpty) {
1447 return _attributes[_attributes.length - 1].endToken; 1428 return _attributes[_attributes.length - 1].endToken;
1448 } 1429 }
1449 return _tag; 1430 return _tag;
1450 } 1431 }
1451 1432
1452 /** 1433 /**
1453 * Answer the ending {@link TokenType#GT} or {@link TokenType#SLASH_GT} token. 1434 * Answer the ending {@link TokenType#GT} or {@link TokenType#SLASH_GT} token.
1454 * @return the token (not {@code null}) 1435 * @return the token (not {@code null})
1455 */ 1436 */
1456 Token get nodeEnd => _nodeEnd; 1437 Token get nodeEnd => _nodeEnd;
1457 1438
1458 /** 1439 /**
1459 * Answer the starting {@link TokenType#LT} token. 1440 * Answer the starting {@link TokenType#LT} token.
1460 * @return the token (not {@code null}) 1441 * @return the token (not {@code null})
1461 */ 1442 */
1462 Token get nodeStart => _nodeStart; 1443 Token get nodeStart => _nodeStart;
1463 1444
1464 /** 1445 /**
1465 * Answer the {@link TokenType#TAG} token after the starting '&lt;'. 1446 * Answer the {@link TokenType#TAG} token after the starting '&lt;'.
1466 * @return the token (not {@code null}) 1447 * @return the token (not {@code null})
1467 */ 1448 */
1468 Token get tag => _tag; 1449 Token get tag => _tag;
1469 1450
1470 /** 1451 /**
1471 * Answer the tag nodes contained in the receiver. Callers should not manipula te the returned list 1452 * Answer the tag nodes contained in the receiver. Callers should not manipula te the returned list
1472 * to edit the AST structure. 1453 * to edit the AST structure.
1473 * @return the children (not {@code null}, contains no {@code null}s) 1454 * @return the children (not {@code null}, contains no {@code null}s)
1474 */ 1455 */
1475 List<XmlTagNode> get tagNodes => _tagNodes; 1456 List<XmlTagNode> get tagNodes => _tagNodes;
1476 void visitChildren(XmlVisitor<Object> visitor) { 1457 void visitChildren(XmlVisitor<Object> visitor) {
1477 for (XmlAttributeNode node in _attributes) { 1458 for (XmlAttributeNode node in _attributes) {
1478 node.accept(visitor); 1459 node.accept(visitor);
1479 } 1460 }
1480 for (XmlTagNode node in _tagNodes) { 1461 for (XmlTagNode node in _tagNodes) {
1481 node.accept(visitor); 1462 node.accept(visitor);
1482 } 1463 }
1483 } 1464 }
1484 1465
1485 /** 1466 /**
1486 * Same as {@link #becomeParentOf(List)}, but returns given "ifEmpty" if "chil dren" is empty 1467 * Same as {@link #becomeParentOf(List)}, but returns given "ifEmpty" if "chil dren" is empty
1487 */ 1468 */
1488 List becomeParentOfEmpty(List children, List ifEmpty) { 1469 List becomeParentOfEmpty(List children, List ifEmpty) {
1489 if (children != null && children.isEmpty) { 1470 if (children != null && children.isEmpty) {
1490 return ifEmpty; 1471 return ifEmpty;
1491 } 1472 }
1492 return becomeParentOf(children); 1473 return becomeParentOf(children);
1493 } 1474 }
1494 } 1475 }
1495
1496 /** 1476 /**
1497 * Instances of the class {@code HtmlParser} are used to parse tokens into a AST structure comprised 1477 * Instances of the class {@code HtmlParser} are used to parse tokens into a AST structure comprised
1498 * of {@link XmlNode}s. 1478 * of {@link XmlNode}s.
1499 * @coverage dart.engine.html 1479 * @coverage dart.engine.html
1500 */ 1480 */
1501 class HtmlParser extends XmlParser { 1481 class HtmlParser extends XmlParser {
1502 static Set<String> SELF_CLOSING = new Set<String>(); 1482 static Set<String> SELF_CLOSING = new Set<String>();
1503 1483
1504 /** 1484 /**
1505 * Construct a parser for the specified source. 1485 * Construct a parser for the specified source.
1506 * @param source the source being parsed 1486 * @param source the source being parsed
1507 */ 1487 */
1508 HtmlParser(Source source) : super(source) { 1488 HtmlParser(Source source) : super(source) {
1509 } 1489 }
1510 1490
1511 /** 1491 /**
1512 * Parse the tokens specified by the given scan result. 1492 * Parse the tokens specified by the given scan result.
1513 * @param scanResult the result of scanning an HTML source (not {@code null}) 1493 * @param scanResult the result of scanning an HTML source (not {@code null})
1514 * @return the parse result (not {@code null}) 1494 * @return the parse result (not {@code null})
1515 */ 1495 */
1516 HtmlParseResult parse(HtmlScanResult scanResult) { 1496 HtmlParseResult parse(HtmlScanResult scanResult) {
1517 Token firstToken = scanResult.token; 1497 Token firstToken = scanResult.token;
1518 List<XmlTagNode> tagNodes = parseTopTagNodes(firstToken); 1498 List<XmlTagNode> tagNodes = parseTopTagNodes(firstToken);
1519 HtmlUnit unit = new HtmlUnit(firstToken, tagNodes, currentToken); 1499 HtmlUnit unit = new HtmlUnit(firstToken, tagNodes, currentToken);
1520 return new HtmlParseResult(scanResult.modificationTime, firstToken, scanResu lt.lineStarts, unit); 1500 return new HtmlParseResult(scanResult.modificationTime, firstToken, scanResu lt.lineStarts, unit);
1521 } 1501 }
1522 1502
1523 /** 1503 /**
1524 * Scan then parse the specified source. 1504 * Scan then parse the specified source.
1525 * @param source the source to be scanned and parsed (not {@code null}) 1505 * @param source the source to be scanned and parsed (not {@code null})
1526 * @return the parse result (not {@code null}) 1506 * @return the parse result (not {@code null})
1527 */ 1507 */
1528 HtmlParseResult parse2(Source source) { 1508 HtmlParseResult parse2(Source source) {
1529 HtmlScanner scanner = new HtmlScanner(source); 1509 HtmlScanner scanner = new HtmlScanner(source);
1530 source.getContents(scanner); 1510 source.getContents(scanner);
1531 return parse(scanner.result); 1511 return parse(scanner.result);
1532 } 1512 }
1533 bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme); 1513 bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme);
1534 } 1514 }
1535
1536 /** 1515 /**
1537 * Instances of the class {@code HtmlUnit} represent the contents of an HTML fil e. 1516 * Instances of the class {@code HtmlUnit} represent the contents of an HTML fil e.
1538 * @coverage dart.engine.html 1517 * @coverage dart.engine.html
1539 */ 1518 */
1540 class HtmlUnit extends XmlNode { 1519 class HtmlUnit extends XmlNode {
1541 1520
1542 /** 1521 /**
1543 * The first token in the token stream that was parsed to form this HTML unit. 1522 * The first token in the token stream that was parsed to form this HTML unit.
1544 */ 1523 */
1545 Token _beginToken; 1524 Token _beginToken;
1546 1525
1547 /** 1526 /**
1548 * The last token in the token stream that was parsed to form this compilation unit. This token 1527 * The last token in the token stream that was parsed to form this compilation unit. This token
1549 * should always have a type of {@link TokenType.EOF}. 1528 * should always have a type of {@link TokenType.EOF}.
1550 */ 1529 */
1551 Token _endToken; 1530 Token _endToken;
1552 1531
1553 /** 1532 /**
1554 * The tag nodes contained in the receiver (not {@code null}, contains no {@co de null}s). 1533 * The tag nodes contained in the receiver (not {@code null}, contains no {@co de null}s).
1555 */ 1534 */
1556 List<XmlTagNode> _tagNodes; 1535 List<XmlTagNode> _tagNodes;
1557 1536
1558 /** 1537 /**
1559 * The element associated with this HTML unit or {@code null} if the receiver is not resolved. 1538 * The element associated with this HTML unit or {@code null} if the receiver is not resolved.
1560 */ 1539 */
1561 HtmlElementImpl _element; 1540 HtmlElementImpl _element;
1562 1541
1563 /** 1542 /**
1564 * Construct a new instance representing the content of an HTML file. 1543 * Construct a new instance representing the content of an HTML file.
1565 * @param beginToken the first token in the file (not {@code null}) 1544 * @param beginToken the first token in the file (not {@code null})
1566 * @param tagNodes child tag nodes of the receiver (not {@code null}, contains no {@code null}s) 1545 * @param tagNodes child tag nodes of the receiver (not {@code null}, contains no {@code null}s)
1567 * @param endToken the last token in the token stream which should be of type{ @link TokenType.EOF} 1546 * @param endToken the last token in the token stream which should be of type{ @link TokenType.EOF}
1568 */ 1547 */
1569 HtmlUnit(Token beginToken, List<XmlTagNode> tagNodes, Token endToken) { 1548 HtmlUnit(Token beginToken, List<XmlTagNode> tagNodes, Token endToken) {
1570 this._beginToken = beginToken; 1549 this._beginToken = beginToken;
1571 this._tagNodes = becomeParentOf(tagNodes); 1550 this._tagNodes = becomeParentOf(tagNodes);
1572 this._endToken = endToken; 1551 this._endToken = endToken;
1573 } 1552 }
1574 accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this); 1553 accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this);
1575 Token get beginToken => _beginToken; 1554 Token get beginToken => _beginToken;
1576 1555
1577 /** 1556 /**
1578 * Return the element associated with this HTML unit. 1557 * Return the element associated with this HTML unit.
1579 * @return the element or {@code null} if the receiver is not resolved 1558 * @return the element or {@code null} if the receiver is not resolved
1580 */ 1559 */
1581 HtmlElementImpl get element => _element; 1560 HtmlElementImpl get element => _element;
1582 Token get endToken => _endToken; 1561 Token get endToken => _endToken;
1583 1562
1584 /** 1563 /**
1585 * Answer the tag nodes contained in the receiver. Callers should not manipula te the returned list 1564 * Answer the tag nodes contained in the receiver. Callers should not manipula te the returned list
1586 * to edit the AST structure. 1565 * to edit the AST structure.
1587 * @return the children (not {@code null}, contains no {@code null}s) 1566 * @return the children (not {@code null}, contains no {@code null}s)
1588 */ 1567 */
1589 List<XmlTagNode> get tagNodes => _tagNodes; 1568 List<XmlTagNode> get tagNodes => _tagNodes;
1590 1569
1591 /** 1570 /**
1592 * Set the element associated with this HTML unit. 1571 * Set the element associated with this HTML unit.
1593 * @param element the element 1572 * @param element the element
1594 */ 1573 */
1595 void set element(HtmlElementImpl element2) { 1574 void set element(HtmlElementImpl element2) {
1596 this._element = element2; 1575 this._element = element2;
1597 } 1576 }
1598 void visitChildren(XmlVisitor<Object> visitor) { 1577 void visitChildren(XmlVisitor<Object> visitor) {
1599 for (XmlTagNode node in _tagNodes) { 1578 for (XmlTagNode node in _tagNodes) {
1600 node.accept(visitor); 1579 node.accept(visitor);
1601 } 1580 }
1602 } 1581 }
1603 } 1582 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698