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

Side by Side Diff: pkg/compiler/lib/src/parser/partial_elements.dart

Issue 1383503002: Add Resolution and Parsing interfaces for computeType, ensureResolved and parseNode. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Add TODOs. Created 5 years, 2 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
« no previous file with comments | « pkg/compiler/lib/src/parser/parser_task.dart ('k') | pkg/compiler/lib/src/patch_parser.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/resolution.dart' show
8 Parsing,
9 Resolution;
7 import '../compiler.dart' show 10 import '../compiler.dart' show
8 Compiler; 11 Compiler;
9 import '../dart_types.dart' show DynamicType; 12 import '../dart_types.dart' show DynamicType;
10 import '../diagnostics/diagnostic_listener.dart'; 13 import '../diagnostics/diagnostic_listener.dart';
11 import '../diagnostics/invariant.dart' show 14 import '../diagnostics/invariant.dart' show
12 invariant; 15 invariant;
13 import '../diagnostics/messages.dart'; 16 import '../diagnostics/messages.dart';
14 import '../elements/elements.dart' show 17 import '../elements/elements.dart' show
15 CompilationUnitElement, 18 CompilationUnitElement,
16 ConstructorElement, 19 ConstructorElement,
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 } 100 }
98 101
99 bool get hasNode => cachedNode != null; 102 bool get hasNode => cachedNode != null;
100 103
101 FunctionExpression get node { 104 FunctionExpression get node {
102 assert(invariant(this, cachedNode != null, 105 assert(invariant(this, cachedNode != null,
103 message: "Node has not been computed for $this.")); 106 message: "Node has not been computed for $this."));
104 return cachedNode; 107 return cachedNode;
105 } 108 }
106 109
107 FunctionExpression parseNode(DiagnosticListener listener) { 110 FunctionExpression parseNode(Parsing parsing) {
108 if (cachedNode != null) return cachedNode; 111 if (cachedNode != null) return cachedNode;
109 parseFunction(Parser p) { 112 parseFunction(Parser p) {
110 if (isClassMember && modifiers.isFactory) { 113 if (isClassMember && modifiers.isFactory) {
111 p.parseFactoryMethod(beginToken); 114 p.parseFactoryMethod(beginToken);
112 } else { 115 } else {
113 p.parseFunction(beginToken, getOrSet); 116 p.parseFunction(beginToken, getOrSet);
114 } 117 }
115 } 118 }
116 cachedNode = parse(listener, this, declarationSite, parseFunction); 119 cachedNode = parse(parsing, this, declarationSite, parseFunction);
117 return cachedNode; 120 return cachedNode;
118 } 121 }
119 122
120 Token get position => _position; 123 Token get position => _position;
121 124
122 void reusePartialFunctionMixin() { 125 void reusePartialFunctionMixin() {
123 cachedNode = null; 126 cachedNode = null;
124 } 127 }
125 128
126 DeclarationSite get declarationSite; 129 DeclarationSite get declarationSite;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 PartialFieldList(Token beginToken, 264 PartialFieldList(Token beginToken,
262 Token endToken, 265 Token endToken,
263 Modifiers modifiers, 266 Modifiers modifiers,
264 bool hasParseError) 267 bool hasParseError)
265 : super(modifiers) { 268 : super(modifiers) {
266 super.beginToken = beginToken; 269 super.beginToken = beginToken;
267 super.endToken = endToken; 270 super.endToken = endToken;
268 super.hasParseError = hasParseError; 271 super.hasParseError = hasParseError;
269 } 272 }
270 273
271 VariableDefinitions parseNode(Element element, DiagnosticListener listener) { 274 VariableDefinitions parseNode(Element element, Parsing parsing) {
272 if (definitions != null) return definitions; 275 if (definitions != null) return definitions;
276 DiagnosticListener listener = parsing.listener;
273 listener.withCurrentElement(element, () { 277 listener.withCurrentElement(element, () {
274 definitions = parse( 278 definitions = parse(
275 listener, element, declarationSite, 279 parsing, element, declarationSite,
276 (Parser parser) => parser.parseMember(beginToken)); 280 (Parser parser) => parser.parseMember(beginToken));
277 281
278 if (!hasParseError && 282 if (!hasParseError &&
279 !definitions.modifiers.isVar && 283 !definitions.modifiers.isVar &&
280 !definitions.modifiers.isFinal && 284 !definitions.modifiers.isFinal &&
281 !definitions.modifiers.isConst && 285 !definitions.modifiers.isConst &&
282 definitions.type == null && 286 definitions.type == null &&
283 !definitions.isErroneous) { 287 !definitions.isErroneous) {
284 listener.reportErrorMessage( 288 listener.reportErrorMessage(
285 definitions, 289 definitions,
286 MessageKind.GENERIC, 290 MessageKind.GENERIC,
287 { 'text': 'A field declaration must start with var, final, ' 291 { 'text': 'A field declaration must start with var, final, '
288 'const, or a type annotation.' }); 292 'const, or a type annotation.' });
289 } 293 }
290 }); 294 });
291 return definitions; 295 return definitions;
292 } 296 }
293 297
294 computeType(Element element, Compiler compiler) { 298 computeType(Element element, Resolution resolution) {
295 if (type != null) return type; 299 if (type != null) return type;
296 // TODO(johnniwinther): Compute this in the resolver. 300 // TODO(johnniwinther): Compute this in the resolver.
297 compiler.withCurrentElement(element, () { 301 VariableDefinitions node = parseNode(element, resolution.parsing);
298 VariableDefinitions node = parseNode(element, compiler); 302 if (node.type != null) {
299 if (node.type != null) { 303 type = resolution.resolveTypeAnnotation(element, node.type);
300 type = compiler.resolver.resolveTypeAnnotation(element, node.type); 304 } else {
301 } else { 305 type = const DynamicType();
302 type = const DynamicType(); 306 }
303 }
304 });
305 assert(type != null); 307 assert(type != null);
306 return type; 308 return type;
307 } 309 }
308 } 310 }
309 311
310 class PartialTypedefElement extends TypedefElementX with PartialElement { 312 class PartialTypedefElement extends TypedefElementX with PartialElement {
311 313
312 PartialTypedefElement( 314 PartialTypedefElement(
313 String name, 315 String name,
314 Element enclosing, 316 Element enclosing,
315 Token beginToken, 317 Token beginToken,
316 Token endToken) 318 Token endToken)
317 : super(name, enclosing) { 319 : super(name, enclosing) {
318 this.beginToken = beginToken; 320 this.beginToken = beginToken;
319 this.endToken = endToken; 321 this.endToken = endToken;
320 } 322 }
321 323
322 Token get token => beginToken; 324 Token get token => beginToken;
323 325
324 Node parseNode(DiagnosticListener listener) { 326 Node parseNode(Parsing parsing) {
325 if (cachedNode != null) return cachedNode; 327 if (cachedNode != null) return cachedNode;
326 cachedNode = parse( 328 cachedNode = parse(
327 listener, this, declarationSite, 329 parsing, this, declarationSite,
328 (p) => p.parseTopLevelDeclaration(token)); 330 (p) => p.parseTopLevelDeclaration(token));
329 return cachedNode; 331 return cachedNode;
330 } 332 }
331 333
332 Token get position => findMyName(token); 334 Token get position => findMyName(token);
333 } 335 }
334 336
335 /// A [MetadataAnnotation] which is constructed on demand. 337 /// A [MetadataAnnotation] which is constructed on demand.
336 class PartialMetadataAnnotation extends MetadataAnnotationX 338 class PartialMetadataAnnotation extends MetadataAnnotationX
337 implements PartialElement { 339 implements PartialElement {
(...skipping 18 matching lines...) Expand all
356 token = token.next; 358 token = token.next;
357 } 359 }
358 assert(token != null); 360 assert(token != null);
359 return token; 361 return token;
360 } 362 }
361 363
362 void set endToken(_) { 364 void set endToken(_) {
363 throw new UnsupportedError("endToken="); 365 throw new UnsupportedError("endToken=");
364 } 366 }
365 367
366 Node parseNode(DiagnosticListener listener) { 368 Node parseNode(Parsing parsing) {
367 if (cachedNode != null) return cachedNode; 369 if (cachedNode != null) return cachedNode;
368 var metadata = parse(listener, 370 var metadata = parse(parsing,
369 annotatedElement, 371 annotatedElement,
370 declarationSite, 372 declarationSite,
371 (p) => p.parseMetadata(beginToken)); 373 (p) => p.parseMetadata(beginToken));
372 if (metadata is Metadata) { 374 if (metadata is Metadata) {
373 cachedNode = metadata.expression; 375 cachedNode = metadata.expression;
374 return cachedNode; 376 return cachedNode;
375 } else { 377 } else {
376 assert (metadata is ErrorNode); 378 assert (metadata is ErrorNode);
377 return metadata; 379 return metadata;
378 } 380 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 } 414 }
413 415
414 bool get hasNode => cachedNode != null; 416 bool get hasNode => cachedNode != null;
415 417
416 ClassNode get node { 418 ClassNode get node {
417 assert(invariant(this, cachedNode != null, 419 assert(invariant(this, cachedNode != null,
418 message: "Node has not been computed for $this.")); 420 message: "Node has not been computed for $this."));
419 return cachedNode; 421 return cachedNode;
420 } 422 }
421 423
422 ClassNode parseNode(Compiler compiler) { 424 ClassNode parseNode(Parsing parsing) {
423 if (cachedNode != null) return cachedNode; 425 if (cachedNode != null) return cachedNode;
424 compiler.withCurrentElement(this, () { 426 DiagnosticListener diagnosticListener = parsing.listener;
425 compiler.parser.measure(() { 427 diagnosticListener.withCurrentElement(this, () {
426 MemberListener listener = new MemberListener(compiler, this); 428 parsing.measure(() {
429 MemberListener listener = new MemberListener(diagnosticListener, this);
427 Parser parser = new ClassElementParser(listener); 430 Parser parser = new ClassElementParser(listener);
428 try { 431 try {
429 Token token = parser.parseTopLevelDeclaration(beginToken); 432 Token token = parser.parseTopLevelDeclaration(beginToken);
430 assert(identical(token, endToken.next)); 433 assert(identical(token, endToken.next));
431 cachedNode = listener.popNode(); 434 cachedNode = listener.popNode();
432 assert( 435 assert(
433 invariant( 436 invariant(
434 beginToken, listener.nodes.isEmpty, 437 beginToken, listener.nodes.isEmpty,
435 message: "Non-empty listener stack: ${listener.nodes}")); 438 message: "Non-empty listener stack: ${listener.nodes}"));
436 } on ParserError { 439 } on ParserError {
437 // TODO(ahe): Often, a ParserError is thrown while parsing the class 440 // TODO(ahe): Often, a ParserError is thrown while parsing the class
438 // body. This means that the stack actually contains most of the 441 // body. This means that the stack actually contains most of the
439 // information synthesized below. Consider rewriting the parser so 442 // information synthesized below. Consider rewriting the parser so
440 // endClassDeclaration is called before parsing the class body. 443 // endClassDeclaration is called before parsing the class body.
441 Identifier name = new Identifier(findMyName(beginToken)); 444 Identifier name = new Identifier(findMyName(beginToken));
442 NodeList typeParameters = null; 445 NodeList typeParameters = null;
443 Node supertype = null; 446 Node supertype = null;
444 NodeList interfaces = listener.makeNodeList(0, null, null, ","); 447 NodeList interfaces = listener.makeNodeList(0, null, null, ",");
445 Token extendsKeyword = null; 448 Token extendsKeyword = null;
446 NodeList body = listener.makeNodeList(0, beginToken, endToken, null); 449 NodeList body = listener.makeNodeList(0, beginToken, endToken, null);
447 cachedNode = new ClassNode( 450 cachedNode = new ClassNode(
448 Modifiers.EMPTY, name, typeParameters, supertype, interfaces, 451 Modifiers.EMPTY, name, typeParameters, supertype, interfaces,
449 beginToken, extendsKeyword, body, endToken); 452 beginToken, extendsKeyword, body, endToken);
450 hasParseError = true; 453 hasParseError = true;
451 } 454 }
452 }); 455 });
453 compiler.patchParser.measure(() { 456 if (isPatched) {
454 if (isPatched) { 457 parsing.parsePatchClass(patch);
455 // TODO(lrn): Perhaps extract functionality so it doesn't 458 }
456 // need compiler.
457 compiler.patchParser.parsePatchClassNode(patch);
458 }
459 });
460 }); 459 });
461 return cachedNode; 460 return cachedNode;
462 } 461 }
463 462
464 Token get position => beginToken; 463 Token get position => beginToken;
465 464
466 // TODO(johnniwinther): Ensure that modifiers are always available. 465 // TODO(johnniwinther): Ensure that modifiers are always available.
467 Modifiers get modifiers => 466 Modifiers get modifiers =>
468 cachedNode != null ? cachedNode.modifiers : Modifiers.EMPTY; 467 cachedNode != null ? cachedNode.modifiers : Modifiers.EMPTY;
469 468
470 accept(ElementVisitor visitor, arg) { 469 accept(ElementVisitor visitor, arg) {
471 return visitor.visitClassElement(this, arg); 470 return visitor.visitClassElement(this, arg);
472 } 471 }
473 472
474 PartialClassElement copyWithEnclosing(CompilationUnitElement enclosing) { 473 PartialClassElement copyWithEnclosing(CompilationUnitElement enclosing) {
475 return new PartialClassElement(name, beginToken, endToken, enclosing, id); 474 return new PartialClassElement(name, beginToken, endToken, enclosing, id);
476 } 475 }
477 } 476 }
478 477
479 Node parse( 478 Node parse(
480 DiagnosticListener diagnosticListener, 479 Parsing parsing,
481 ElementX element, 480 ElementX element,
482 PartialElement partial, 481 PartialElement partial,
483 doParse(Parser parser)) { 482 doParse(Parser parser)) {
484 CompilationUnitElement unit = element.compilationUnit; 483 DiagnosticListener diagnosticListener = parsing.listener;
485 NodeListener listener = new NodeListener(diagnosticListener, unit); 484 return parsing.measure(() {
486 listener.memberErrors = listener.memberErrors.prepend(false); 485 return diagnosticListener.withCurrentElement(element, () {
487 try { 486 CompilationUnitElement unit = element.compilationUnit;
488 if (partial.hasParseError) { 487 NodeListener listener = new NodeListener(diagnosticListener, unit);
489 listener.suppressParseErrors = true; 488 listener.memberErrors = listener.memberErrors.prepend(false);
490 } 489 try {
491 doParse(new Parser(listener)); 490 if (partial.hasParseError) {
492 } on ParserError catch (e) { 491 listener.suppressParseErrors = true;
493 partial.hasParseError = true; 492 }
494 return new ErrorNode(element.position, e.reason); 493 doParse(new Parser(listener));
495 } 494 } on ParserError catch (e) {
496 Node node = listener.popNode(); 495 partial.hasParseError = true;
497 assert(listener.nodes.isEmpty); 496 return new ErrorNode(element.position, e.reason);
498 return node; 497 }
498 Node node = listener.popNode();
499 assert(listener.nodes.isEmpty);
500 return node;
501 });
502 });
499 } 503 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/parser/parser_task.dart ('k') | pkg/compiler/lib/src/patch_parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698