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

Side by Side Diff: pkg/compiler/lib/src/resolution/constructors.dart

Issue 1308153007: Revert "Prepare for computation of NewStructure in Resolution." (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 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
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.resolution.constructors; 5 library dart2js.resolution.constructors;
6 import '../compiler.dart' show 6 import '../compiler.dart' show
7 Compiler; 7 Compiler;
8 import '../constants/constructors.dart' show 8 import '../constants/constructors.dart' show
9 GenerativeConstantConstructor, 9 GenerativeConstantConstructor,
10 RedirectingGenerativeConstantConstructor; 10 RedirectingGenerativeConstantConstructor;
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 constructor.constantConstructor = new GenerativeConstantConstructor( 408 constructor.constantConstructor = new GenerativeConstantConstructor(
409 constructor.enclosingClass.thisType, 409 constructor.enclosingClass.thisType,
410 defaultValues, 410 defaultValues,
411 fieldInitializers, 411 fieldInitializers,
412 constructorInvocation); 412 constructorInvocation);
413 } 413 }
414 return null; // If there was no redirection always return null. 414 return null; // If there was no redirection always return null.
415 } 415 }
416 } 416 }
417 417
418 class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> { 418 class ConstructorResolver extends CommonResolverVisitor<Element> {
419 final ResolverVisitor resolver; 419 final ResolverVisitor resolver;
420 final bool inConstContext; 420 bool inConstContext;
421 DartType type;
421 422
422 ConstructorResolver(Compiler compiler, this.resolver, 423 ConstructorResolver(Compiler compiler, this.resolver,
423 {bool this.inConstContext: false}) 424 {bool this.inConstContext: false})
424 : super(compiler); 425 : super(compiler);
425 426
426 ResolutionRegistry get registry => resolver.registry; 427 ResolutionRegistry get registry => resolver.registry;
427 428
428 visitNode(Node node) { 429 visitNode(Node node) {
429 throw 'not supported'; 430 throw 'not supported';
430 } 431 }
431 432
432 ConstructorResult reportAndCreateErroneousConstructorElement( 433 ErroneousConstructorElementX failOrReturnErroneousConstructorElement(
433 Spannable diagnosticNode, 434 Spannable diagnosticNode,
434 ConstructorResultKind resultKind,
435 DartType type,
436 Element enclosing, 435 Element enclosing,
437 String name, 436 String name,
438 MessageKind kind, 437 MessageKind kind,
439 Map arguments, 438 Map arguments,
440 {bool isError: false, 439 {bool isError: false,
441 bool missingConstructor: false}) { 440 bool missingConstructor: false}) {
442 if (missingConstructor) { 441 if (missingConstructor) {
443 registry.registerThrowNoSuchMethod(); 442 registry.registerThrowNoSuchMethod();
444 } else { 443 } else {
445 registry.registerThrowRuntimeError(); 444 registry.registerThrowRuntimeError();
446 } 445 }
447 if (isError || inConstContext) { 446 if (isError || inConstContext) {
448 compiler.reportError(diagnosticNode, kind, arguments); 447 compiler.reportError(diagnosticNode, kind, arguments);
449 } else { 448 } else {
450 compiler.reportWarning(diagnosticNode, kind, arguments); 449 compiler.reportWarning(diagnosticNode, kind, arguments);
451 } 450 }
452 ErroneousElement error = new ErroneousConstructorElementX( 451 return new ErroneousConstructorElementX(
453 kind, arguments, name, enclosing); 452 kind, arguments, name, enclosing);
454 if (type == null) {
455 type = new MalformedType(error, null);
456 }
457 return new ConstructorResult(resultKind, error, type);
458 } 453 }
459 454
460 ConstructorResult resolveConstructor( 455 FunctionElement resolveConstructor(ClassElement cls,
461 InterfaceType type, 456 Node diagnosticNode,
462 Node diagnosticNode, 457 String constructorName) {
463 String constructorName) {
464 ClassElement cls = type.element;
465 cls.ensureResolved(compiler); 458 cls.ensureResolved(compiler);
466 ConstructorElement constructor = cls.lookupConstructor(constructorName); 459 Element result = cls.lookupConstructor(constructorName);
467 // TODO(johnniwinther): Use [Name] for lookup. 460 // TODO(johnniwinther): Use [Name] for lookup.
468 if (Name.isPrivateName(constructorName) && 461 if (Name.isPrivateName(constructorName) &&
469 resolver.enclosingElement.library != cls.library) { 462 resolver.enclosingElement.library != cls.library) {
470 constructor = null; 463 result = null;
471 } 464 }
472 if (constructor == null) { 465 if (result == null) {
473 String fullConstructorName = 466 String fullConstructorName = Elements.constructorNameForDiagnostics(
474 Elements.constructorNameForDiagnostics(cls.name, constructorName); 467 cls.name,
475 return reportAndCreateErroneousConstructorElement( 468 constructorName);
469 return failOrReturnErroneousConstructorElement(
476 diagnosticNode, 470 diagnosticNode,
477 ConstructorResultKind.UNRESOLVED_CONSTRUCTOR, type,
478 cls, constructorName, 471 cls, constructorName,
479 MessageKind.CANNOT_FIND_CONSTRUCTOR, 472 MessageKind.CANNOT_FIND_CONSTRUCTOR,
480 {'constructorName': fullConstructorName}, 473 {'constructorName': fullConstructorName},
481 missingConstructor: true); 474 missingConstructor: true);
482 } else if (inConstContext && !constructor.isConst) { 475 } else if (inConstContext && !result.isConst) {
483 compiler.reportError( 476 error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
484 diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
485 return new ConstructorResult(
486 ConstructorResultKind.NON_CONSTANT, constructor, type);
487 } else {
488 if (constructor.isGenerativeConstructor) {
489 if (cls.isAbstract) {
490 compiler.reportWarning(
491 diagnosticNode, MessageKind.ABSTRACT_CLASS_INSTANTIATION);
492 registry.registerAbstractClassInstantiation();
493 return new ConstructorResult(
494 ConstructorResultKind.ABSTRACT, constructor, type);
495 } else {
496 return new ConstructorResult(
497 ConstructorResultKind.GENERATIVE, constructor, type);
498 }
499 } else {
500 assert(invariant(diagnosticNode, constructor.isFactoryConstructor,
501 message: "Unexpected constructor $constructor."));
502 return new ConstructorResult(
503 ConstructorResultKind.FACTORY, constructor, type);
504 }
505 } 477 }
478 return result;
506 } 479 }
507 480
508 ConstructorResult visitNewExpression(NewExpression node) { 481 Element visitNewExpression(NewExpression node) {
482 inConstContext = node.isConst;
509 Node selector = node.send.selector; 483 Node selector = node.send.selector;
510 ConstructorResult result = visit(selector); 484 Element element = visit(selector);
511 assert(invariant(selector, result != null, 485 assert(invariant(selector, element != null,
512 message: 'No result returned for $selector.')); 486 message: 'No element return for $selector.'));
513 return finishConstructorReference(result, node.send.selector, node); 487 return finishConstructorReference(element, node.send.selector, node);
514 } 488 }
515 489
516 /// Finishes resolution of a constructor reference and records the 490 /// Finishes resolution of a constructor reference and records the
517 /// type of the constructed instance on [expression]. 491 /// type of the constructed instance on [expression].
518 ConstructorResult finishConstructorReference( 492 FunctionElement finishConstructorReference(Element element,
519 ConstructorResult result, 493 Node diagnosticNode,
520 Node diagnosticNode, 494 Node expression) {
521 Node expression) { 495 assert(invariant(diagnosticNode, element != null,
522 assert(invariant(diagnosticNode, result != null, 496 message: 'No element return for $diagnosticNode.'));
523 message: 'No result returned for $diagnosticNode.'));
524
525 if (result.kind != null) {
526 resolver.registry.setType(expression, result.type);
527 return result;
528 }
529
530 // Find the unnamed constructor if the reference resolved to a 497 // Find the unnamed constructor if the reference resolved to a
531 // class. 498 // class.
532 if (result.type != null) { 499 if (!Elements.isUnresolved(element) && !element.isConstructor) {
533 // The unnamed constructor may not exist, so [e] may become unresolved. 500 if (element.isClass) {
534 result = resolveConstructor(result.type, diagnosticNode, ''); 501 ClassElement cls = element;
535 } else { 502 cls.ensureResolved(compiler);
536 Element element = result.element; 503 // The unnamed constructor may not exist, so [e] may become unresolved.
537 if (element.isErroneous) { 504 element = resolveConstructor(cls, diagnosticNode, '');
538 result = constructorResultForErroneous(diagnosticNode, element);
539 } else { 505 } else {
540 result = reportAndCreateErroneousConstructorElement( 506 element = failOrReturnErroneousConstructorElement(
541 diagnosticNode, 507 diagnosticNode,
542 ConstructorResultKind.INVALID_TYPE, null,
543 element, element.name, 508 element, element.name,
544 MessageKind.NOT_A_TYPE, {'node': diagnosticNode}); 509 MessageKind.NOT_A_TYPE, {'node': diagnosticNode});
545 } 510 }
511 } else if (element.isErroneous && element is! ErroneousElementX) {
512 // Parser error. The error has already been reported.
513 element = new ErroneousConstructorElementX(
514 MessageKind.NOT_A_TYPE, {'node': diagnosticNode},
515 element.name, element);
516 registry.registerThrowRuntimeError();
546 } 517 }
547 resolver.registry.setType(expression, result.type); 518
548 return result; 519 if (type == null) {
520 if (Elements.isUnresolved(element)) {
521 type = const DynamicType();
522 } else {
523 type = element.enclosingClass.rawType;
524 }
525 }
526 resolver.registry.setType(expression, type);
527 return element;
549 } 528 }
550 529
551 ConstructorResult visitTypeAnnotation(TypeAnnotation node) { 530 Element visitTypeAnnotation(TypeAnnotation node) {
531 assert(invariant(node, type == null));
552 // This is not really resolving a type-annotation, but the name of the 532 // This is not really resolving a type-annotation, but the name of the
553 // constructor. Therefore we allow deferred types. 533 // constructor. Therefore we allow deferred types.
554 DartType type = resolver.resolveTypeAnnotation( 534 type = resolver.resolveTypeAnnotation(node,
555 node, 535 malformedIsError: inConstContext,
556 malformedIsError: inConstContext, 536 deferredIsMalformed: false);
557 deferredIsMalformed: false);
558 registry.registerRequiredType(type, resolver.enclosingElement); 537 registry.registerRequiredType(type, resolver.enclosingElement);
559 return constructorResultForType(node, type); 538 return type.element;
560 } 539 }
561 540
562 ConstructorResult visitSend(Send node) { 541 Element visitSend(Send node) {
563 ConstructorResult receiver = visit(node.receiver); 542 Element element = visit(node.receiver);
564 assert(invariant(node.receiver, receiver != null, 543 assert(invariant(node.receiver, element != null,
565 message: 'No result returned for $node.receiver.')); 544 message: 'No element return for $node.receiver.'));
566 //if (Elements.isUnresolved(element)) return element; 545 if (Elements.isUnresolved(element)) return element;
567
568 Identifier name = node.selector.asIdentifier(); 546 Identifier name = node.selector.asIdentifier();
569 if (name == null) internalError(node.selector, 'unexpected node'); 547 if (name == null) internalError(node.selector, 'unexpected node');
570 548
571 if (receiver.type != null) { 549 if (element.isClass) {
572 if (receiver.type.isInterfaceType) { 550 ClassElement cls = element;
573 return resolveConstructor(receiver.type, name, name.source); 551 cls.ensureResolved(compiler);
574 } else { 552 return resolveConstructor(cls, name, name.source);
575 // TODO(johnniwinther): Update the message for the different types. 553 } else if (element.isPrefix) {
576 return reportAndCreateErroneousConstructorElement( 554 PrefixElement prefix = element;
555 element = prefix.lookupLocalMember(name.source);
556 element = Elements.unwrap(element, compiler, node);
557 if (element == null) {
558 return failOrReturnErroneousConstructorElement(
577 name, 559 name,
578 ConstructorResultKind.INVALID_TYPE, null,
579 resolver.enclosingElement, name.source, 560 resolver.enclosingElement, name.source,
580 MessageKind.NOT_A_TYPE, {'node': name}); 561 MessageKind.CANNOT_RESOLVE, {'name': name});
562 } else if (!element.isClass) {
563 return failOrReturnErroneousConstructorElement(
564 name,
565 resolver.enclosingElement, name.source,
566 MessageKind.NOT_A_TYPE, {'node': name},
567 isError: true);
581 } 568 }
582 } else if (receiver.element.isPrefix) {
583 PrefixElement prefix = receiver.element;
584 Element member = prefix.lookupLocalMember(name.source);
585 return constructorResultForElement(node, name.source, member);
586 } else { 569 } else {
587 return internalError(node.receiver, 'unexpected receiver $receiver'); 570 internalError(node.receiver, 'unexpected element $element');
588 } 571 }
572 return element;
589 } 573 }
590 574
591 ConstructorResult visitIdentifier(Identifier node) { 575 Element visitIdentifier(Identifier node) {
592 String name = node.source; 576 String name = node.source;
593 Element element = resolver.reportLookupErrorIfAny( 577 Element element = resolver.reportLookupErrorIfAny(
594 lookupInScope(compiler, node, resolver.scope, name), node, name); 578 lookupInScope(compiler, node, resolver.scope, name), node, name);
595 registry.useElement(node, element); 579 registry.useElement(node, element);
596 // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1. 580 // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1.
597 return constructorResultForElement(node, name, element); 581 if (element == null) {
582 return failOrReturnErroneousConstructorElement(
583 node,
584 resolver.enclosingElement, name,
585 MessageKind.CANNOT_RESOLVE,
586 {'name': name});
587 } else if (element.isErroneous) {
588 return element;
589 } else if (element.isTypedef) {
590 element = failOrReturnErroneousConstructorElement(
591 node,
592 resolver.enclosingElement, name,
593 MessageKind.CANNOT_INSTANTIATE_TYPEDEF, {'typedefName': name},
594 isError: true);
595 } else if (element.isTypeVariable) {
596 element = failOrReturnErroneousConstructorElement(
597 node,
598 resolver.enclosingElement, name,
599 MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
600 {'typeVariableName': name},
601 isError: true);
602 } else if (!element.isClass && !element.isPrefix) {
603 element = failOrReturnErroneousConstructorElement(
604 node,
605 resolver.enclosingElement, name,
606 MessageKind.NOT_A_TYPE, {'node': name},
607 isError: true);
608 }
609 return element;
598 } 610 }
599 611
600 /// Assumed to be called by [resolveRedirectingFactory]. 612 /// Assumed to be called by [resolveRedirectingFactory].
601 ConstructorResult visitRedirectingFactoryBody(RedirectingFactoryBody node) { 613 Element visitRedirectingFactoryBody(RedirectingFactoryBody node) {
602 Node constructorReference = node.constructorReference; 614 Node constructorReference = node.constructorReference;
603 return finishConstructorReference(visit(constructorReference), 615 return finishConstructorReference(visit(constructorReference),
604 constructorReference, node); 616 constructorReference, node);
605 } 617 }
606
607 ConstructorResult constructorResultForElement(
608 Node node, String name, Element element) {
609 element = Elements.unwrap(element, compiler, node);
610 if (element == null) {
611 return reportAndCreateErroneousConstructorElement(
612 node,
613 ConstructorResultKind.INVALID_TYPE, null,
614 resolver.enclosingElement, name,
615 MessageKind.CANNOT_RESOLVE,
616 {'name': name});
617 } else if (element.isErroneous) {
618 return constructorResultForErroneous(node, element);
619 } else if (element.isClass) {
620 ClassElement cls = element;
621 cls.computeType(compiler);
622 return constructorResultForType(node, cls.rawType);
623 } else if (element.isPrefix) {
624 return new ConstructorResult.forElement(element);
625 } else if (element.isTypedef) {
626 TypedefElement typdef = element;
627 typdef.ensureResolved(compiler);
628 return constructorResultForType(node, typdef.rawType);
629 } else if (element.isTypeVariable) {
630 TypeVariableElement typeVariableElement = element;
631 return constructorResultForType(node, typeVariableElement.type);
632 } else {
633 return reportAndCreateErroneousConstructorElement(
634 node,
635 ConstructorResultKind.INVALID_TYPE, null,
636 resolver.enclosingElement, name,
637 MessageKind.NOT_A_TYPE, {'node': name});
638 }
639 }
640
641 ConstructorResult constructorResultForErroneous(
642 Node node, Element error) {
643 if (error is! ErroneousElementX) {
644 // Parser error. The error has already been reported.
645 error = new ErroneousConstructorElementX(
646 MessageKind.NOT_A_TYPE, {'node': node},
647 error.name, error);
648 registry.registerThrowRuntimeError();
649 }
650 return new ConstructorResult(
651 ConstructorResultKind.INVALID_TYPE,
652 error,
653 new MalformedType(error, null));
654 }
655
656 ConstructorResult constructorResultForType(
657 Node node,
658 DartType type) {
659 String name = type.name;
660 if (type.isMalformed) {
661 return new ConstructorResult(
662 ConstructorResultKind.INVALID_TYPE, type.element, type);
663 } else if (type.isInterfaceType) {
664 return new ConstructorResult.forType(type);
665 } else if (type.isTypedef) {
666 return reportAndCreateErroneousConstructorElement(
667 node,
668 ConstructorResultKind.INVALID_TYPE, type,
669 resolver.enclosingElement, name,
670 MessageKind.CANNOT_INSTANTIATE_TYPEDEF, {'typedefName': name});
671 } else if (type.isTypeVariable) {
672 return reportAndCreateErroneousConstructorElement(
673 node,
674 ConstructorResultKind.INVALID_TYPE, type,
675 resolver.enclosingElement, name,
676 MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
677 {'typeVariableName': name});
678 }
679 internalError(node, "Unexpected constructor type $type");
680 return null;
681 }
682
683 } 618 }
684
685 enum ConstructorResultKind {
686 GENERATIVE,
687 FACTORY,
688 ABSTRACT,
689 INVALID_TYPE,
690 UNRESOLVED_CONSTRUCTOR,
691 NON_CONSTANT,
692 }
693
694 class ConstructorResult {
695 final ConstructorResultKind kind;
696 final Element element;
697 final DartType type;
698
699 ConstructorResult(this.kind, this.element, this.type);
700
701 ConstructorResult.forElement(this.element)
702 : kind = null,
703 type = null;
704
705 ConstructorResult.forType(this.type)
706 : kind = null,
707 element = null;
708
709 String toString() {
710 StringBuffer sb = new StringBuffer();
711 sb.write('ConstructorResult(');
712 if (kind != null) {
713 sb.write('kind=$kind,');
714 sb.write('element=$element,');
715 sb.write('type=$type');
716 } else if (element != null) {
717 sb.write('element=$element');
718 } else {
719 sb.write('type=$type');
720 }
721 sb.write(')');
722 return sb.toString();
723 }
724 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/resolution/class_members.dart ('k') | pkg/compiler/lib/src/resolution/members.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698