OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart2js.parser.partial_elements; | 5 library dart2js.parser.partial_elements; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/resolution.dart' show Parsing, Resolution; | 8 import '../common/resolution.dart' show ParsingContext, Resolution; |
9 import '../dart_types.dart' show DynamicType; | 9 import '../dart_types.dart' show DynamicType; |
10 import '../elements/elements.dart' | 10 import '../elements/elements.dart' |
11 show | 11 show |
12 CompilationUnitElement, | 12 CompilationUnitElement, |
13 Element, | 13 Element, |
14 ElementKind, | 14 ElementKind, |
15 GetterElement, | 15 GetterElement, |
16 MetadataAnnotation, | 16 MetadataAnnotation, |
17 SetterElement, | 17 SetterElement, |
18 STATE_NOT_STARTED, | 18 STATE_NOT_STARTED, |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 } | 76 } |
77 | 77 |
78 bool get hasNode => cachedNode != null; | 78 bool get hasNode => cachedNode != null; |
79 | 79 |
80 FunctionExpression get node { | 80 FunctionExpression get node { |
81 assert(invariant(this, cachedNode != null, | 81 assert(invariant(this, cachedNode != null, |
82 message: "Node has not been computed for $this.")); | 82 message: "Node has not been computed for $this.")); |
83 return cachedNode; | 83 return cachedNode; |
84 } | 84 } |
85 | 85 |
86 FunctionExpression parseNode(Parsing parsing) { | 86 FunctionExpression parseNode(ParsingContext parsing) { |
87 if (cachedNode != null) return cachedNode; | 87 if (cachedNode != null) return cachedNode; |
88 parseFunction(Parser p) { | 88 parseFunction(Parser p) { |
89 if (isClassMember && modifiers.isFactory) { | 89 if (isClassMember && modifiers.isFactory) { |
90 p.parseFactoryMethod(beginToken); | 90 p.parseFactoryMethod(beginToken); |
91 } else { | 91 } else { |
92 p.parseFunction(beginToken, getOrSet); | 92 p.parseFunction(beginToken, getOrSet); |
93 } | 93 } |
94 } | 94 } |
95 cachedNode = parse(parsing, this, declarationSite, parseFunction); | 95 cachedNode = parse(parsing, this, declarationSite, parseFunction); |
96 return cachedNode; | 96 return cachedNode; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 | 219 |
220 class PartialFieldList extends VariableList with PartialElement { | 220 class PartialFieldList extends VariableList with PartialElement { |
221 PartialFieldList( | 221 PartialFieldList( |
222 Token beginToken, Token endToken, Modifiers modifiers, bool hasParseError) | 222 Token beginToken, Token endToken, Modifiers modifiers, bool hasParseError) |
223 : super(modifiers) { | 223 : super(modifiers) { |
224 super.beginToken = beginToken; | 224 super.beginToken = beginToken; |
225 super.endToken = endToken; | 225 super.endToken = endToken; |
226 super.hasParseError = hasParseError; | 226 super.hasParseError = hasParseError; |
227 } | 227 } |
228 | 228 |
229 VariableDefinitions parseNode(Element element, Parsing parsing) { | 229 VariableDefinitions parseNode(Element element, ParsingContext parsing) { |
230 if (definitions != null) return definitions; | 230 if (definitions != null) return definitions; |
231 DiagnosticReporter reporter = parsing.reporter; | 231 DiagnosticReporter reporter = parsing.reporter; |
232 reporter.withCurrentElement(element, () { | 232 reporter.withCurrentElement(element, () { |
233 definitions = parse(parsing, element, declarationSite, | 233 definitions = parse(parsing, element, declarationSite, |
234 (Parser parser) => parser.parseMember(beginToken)); | 234 (Parser parser) => parser.parseMember(beginToken)); |
235 | 235 |
236 if (!hasParseError && | 236 if (!hasParseError && |
237 !definitions.modifiers.isVar && | 237 !definitions.modifiers.isVar && |
238 !definitions.modifiers.isFinal && | 238 !definitions.modifiers.isFinal && |
239 !definitions.modifiers.isConst && | 239 !definitions.modifiers.isConst && |
240 definitions.type == null && | 240 definitions.type == null && |
241 !definitions.isErroneous) { | 241 !definitions.isErroneous) { |
242 reporter.reportErrorMessage(definitions, MessageKind.GENERIC, { | 242 reporter.reportErrorMessage(definitions, MessageKind.GENERIC, { |
243 'text': 'A field declaration must start with var, final, ' | 243 'text': 'A field declaration must start with var, final, ' |
244 'const, or a type annotation.' | 244 'const, or a type annotation.' |
245 }); | 245 }); |
246 } | 246 } |
247 }); | 247 }); |
248 return definitions; | 248 return definitions; |
249 } | 249 } |
250 | 250 |
251 computeType(Element element, Resolution resolution) { | 251 computeType(Element element, Resolution resolution) { |
252 if (type != null) return type; | 252 if (type != null) return type; |
253 // TODO(johnniwinther): Compute this in the resolver. | 253 // TODO(johnniwinther): Compute this in the resolver. |
254 VariableDefinitions node = parseNode(element, resolution.parsing); | 254 VariableDefinitions node = parseNode(element, resolution.parsingContext); |
255 if (node.type != null) { | 255 if (node.type != null) { |
256 type = resolution.reporter.withCurrentElement(element, () { | 256 type = resolution.reporter.withCurrentElement(element, () { |
257 return resolution.resolveTypeAnnotation(element, node.type); | 257 return resolution.resolveTypeAnnotation(element, node.type); |
258 }); | 258 }); |
259 } else { | 259 } else { |
260 type = const DynamicType(); | 260 type = const DynamicType(); |
261 } | 261 } |
262 assert(type != null); | 262 assert(type != null); |
263 return type; | 263 return type; |
264 } | 264 } |
265 } | 265 } |
266 | 266 |
267 class PartialTypedefElement extends TypedefElementX with PartialElement { | 267 class PartialTypedefElement extends TypedefElementX with PartialElement { |
268 PartialTypedefElement( | 268 PartialTypedefElement( |
269 String name, Element enclosing, Token beginToken, Token endToken) | 269 String name, Element enclosing, Token beginToken, Token endToken) |
270 : super(name, enclosing) { | 270 : super(name, enclosing) { |
271 this.beginToken = beginToken; | 271 this.beginToken = beginToken; |
272 this.endToken = endToken; | 272 this.endToken = endToken; |
273 } | 273 } |
274 | 274 |
275 Token get token => beginToken; | 275 Token get token => beginToken; |
276 | 276 |
277 Node parseNode(Parsing parsing) { | 277 Node parseNode(ParsingContext parsing) { |
278 if (cachedNode != null) return cachedNode; | 278 if (cachedNode != null) return cachedNode; |
279 cachedNode = parse(parsing, this, declarationSite, | 279 cachedNode = parse(parsing, this, declarationSite, |
280 (p) => p.parseTopLevelDeclaration(token)); | 280 (p) => p.parseTopLevelDeclaration(token)); |
281 return cachedNode; | 281 return cachedNode; |
282 } | 282 } |
283 | 283 |
284 Token get position => findMyName(token); | 284 Token get position => findMyName(token); |
285 } | 285 } |
286 | 286 |
287 /// A [MetadataAnnotation] which is constructed on demand. | 287 /// A [MetadataAnnotation] which is constructed on demand. |
(...skipping 20 matching lines...) Expand all Loading... |
308 token = token.next; | 308 token = token.next; |
309 } | 309 } |
310 assert(token != null); | 310 assert(token != null); |
311 return token; | 311 return token; |
312 } | 312 } |
313 | 313 |
314 void set endToken(_) { | 314 void set endToken(_) { |
315 throw new UnsupportedError("endToken="); | 315 throw new UnsupportedError("endToken="); |
316 } | 316 } |
317 | 317 |
318 Node parseNode(Parsing parsing) { | 318 Node parseNode(ParsingContext parsing) { |
319 if (cachedNode != null) return cachedNode; | 319 if (cachedNode != null) return cachedNode; |
320 var metadata = parse(parsing, annotatedElement, declarationSite, | 320 var metadata = parse(parsing, annotatedElement, declarationSite, |
321 (p) => p.parseMetadata(beginToken)); | 321 (p) => p.parseMetadata(beginToken)); |
322 if (metadata is Metadata) { | 322 if (metadata is Metadata) { |
323 cachedNode = metadata.expression; | 323 cachedNode = metadata.expression; |
324 return cachedNode; | 324 return cachedNode; |
325 } else { | 325 } else { |
326 assert(metadata is ErrorNode); | 326 assert(metadata is ErrorNode); |
327 return metadata; | 327 return metadata; |
328 } | 328 } |
(...skipping 30 matching lines...) Expand all Loading... |
359 } | 359 } |
360 | 360 |
361 bool get hasNode => cachedNode != null; | 361 bool get hasNode => cachedNode != null; |
362 | 362 |
363 ClassNode get node { | 363 ClassNode get node { |
364 assert(invariant(this, cachedNode != null, | 364 assert(invariant(this, cachedNode != null, |
365 message: "Node has not been computed for $this.")); | 365 message: "Node has not been computed for $this.")); |
366 return cachedNode; | 366 return cachedNode; |
367 } | 367 } |
368 | 368 |
369 ClassNode parseNode(Parsing parsing) { | 369 ClassNode parseNode(ParsingContext parsing) { |
370 if (cachedNode != null) return cachedNode; | 370 if (cachedNode != null) return cachedNode; |
371 DiagnosticReporter reporter = parsing.reporter; | 371 DiagnosticReporter reporter = parsing.reporter; |
372 reporter.withCurrentElement(this, () { | 372 reporter.withCurrentElement(this, () { |
373 parsing.measure(() { | 373 parsing.measure(() { |
374 MemberListener listener = new MemberListener( | 374 MemberListener listener = new MemberListener( |
375 parsing.getScannerOptionsFor(this), reporter, this); | 375 parsing.getScannerOptionsFor(this), reporter, this); |
376 Parser parser = new ClassElementParser(listener, parsing.parserOptions); | 376 Parser parser = new ClassElementParser(listener, parsing.parserOptions); |
377 try { | 377 try { |
378 Token token = parser.parseTopLevelDeclaration(beginToken); | 378 Token token = parser.parseTopLevelDeclaration(beginToken); |
379 assert(identical(token, endToken.next)); | 379 assert(identical(token, endToken.next)); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 | 419 |
420 accept(ElementVisitor visitor, arg) { | 420 accept(ElementVisitor visitor, arg) { |
421 return visitor.visitClassElement(this, arg); | 421 return visitor.visitClassElement(this, arg); |
422 } | 422 } |
423 | 423 |
424 PartialClassElement copyWithEnclosing(CompilationUnitElement enclosing) { | 424 PartialClassElement copyWithEnclosing(CompilationUnitElement enclosing) { |
425 return new PartialClassElement(name, beginToken, endToken, enclosing, id); | 425 return new PartialClassElement(name, beginToken, endToken, enclosing, id); |
426 } | 426 } |
427 } | 427 } |
428 | 428 |
429 Node parse(Parsing parsing, ElementX element, PartialElement partial, | 429 Node parse(ParsingContext parsing, ElementX element, PartialElement partial, |
430 doParse(Parser parser)) { | 430 doParse(Parser parser)) { |
431 DiagnosticReporter reporter = parsing.reporter; | 431 DiagnosticReporter reporter = parsing.reporter; |
432 return parsing.measure(() { | 432 return parsing.measure(() { |
433 return reporter.withCurrentElement(element, () { | 433 return reporter.withCurrentElement(element, () { |
434 CompilationUnitElement unit = element.compilationUnit; | 434 CompilationUnitElement unit = element.compilationUnit; |
435 NodeListener listener = new NodeListener( | 435 NodeListener listener = new NodeListener( |
436 parsing.getScannerOptionsFor(element), reporter, unit); | 436 parsing.getScannerOptionsFor(element), reporter, unit); |
437 listener.memberErrors = listener.memberErrors.prepend(false); | 437 listener.memberErrors = listener.memberErrors.prepend(false); |
438 try { | 438 try { |
439 if (partial.hasParseError) { | 439 if (partial.hasParseError) { |
440 listener.suppressParseErrors = true; | 440 listener.suppressParseErrors = true; |
441 } | 441 } |
442 doParse(new Parser(listener, parsing.parserOptions)); | 442 doParse(new Parser(listener, parsing.parserOptions)); |
443 } on ParserError catch (e) { | 443 } on ParserError catch (e) { |
444 partial.hasParseError = true; | 444 partial.hasParseError = true; |
445 return new ErrorNode(element.position, e.reason); | 445 return new ErrorNode(element.position, e.reason); |
446 } | 446 } |
447 Node node = listener.popNode(); | 447 Node node = listener.popNode(); |
448 assert(listener.nodes.isEmpty); | 448 assert(listener.nodes.isEmpty); |
449 return node; | 449 return node; |
450 }); | 450 }); |
451 }); | 451 }); |
452 } | 452 } |
OLD | NEW |