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

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

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

Powered by Google App Engine
This is Rietveld 408576698