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

Side by Side Diff: pkg/compiler/lib/src/native/behavior.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/mirrors_used.dart ('k') | pkg/compiler/lib/src/native/enqueue.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 part of native; 5 part of native;
6 6
7 /// This class is a temporary work-around until we get a more powerful DartType. 7 /// This class is a temporary work-around until we get a more powerful DartType.
8 class SpecialType { 8 class SpecialType {
9 final String name; 9 final String name;
10 const SpecialType._(this.name); 10 const SpecialType._(this.name);
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 } 459 }
460 460
461 behavior.codeTemplate = 461 behavior.codeTemplate =
462 js.js.parseForeignJS(codeArgument.dartString.slowToString()); 462 js.js.parseForeignJS(codeArgument.dartString.slowToString());
463 463
464 String specString = specArgument.dartString.slowToString(); 464 String specString = specArgument.dartString.slowToString();
465 465
466 dynamic resolveType(String typeString) { 466 dynamic resolveType(String typeString) {
467 return _parseType( 467 return _parseType(
468 typeString, 468 typeString,
469 compiler, 469 compiler.resolution,
470 (name) => resolver.resolveTypeFromString(specArgument, name), 470 (name) => resolver.resolveTypeFromString(specArgument, name),
471 specArgument); 471 specArgument);
472 } 472 }
473 473
474 bool sideEffectsAreEncodedInSpecString = false; 474 bool sideEffectsAreEncodedInSpecString = false;
475 475
476 void setSideEffects(SideEffects newEffects) { 476 void setSideEffects(SideEffects newEffects) {
477 sideEffectsAreEncodedInSpecString = true; 477 sideEffectsAreEncodedInSpecString = true;
478 behavior.sideEffects.setTo(newEffects); 478 behavior.sideEffects.setTo(newEffects);
479 } 479 }
(...skipping 14 matching lines...) Expand all
494 494
495 processSpecString(compiler, specArgument, 495 processSpecString(compiler, specArgument,
496 specString, 496 specString,
497 setSideEffects: setSideEffects, 497 setSideEffects: setSideEffects,
498 setThrows: setThrows, 498 setThrows: setThrows,
499 setIsAllocation: setIsAllocation, 499 setIsAllocation: setIsAllocation,
500 setUseGvn: setUseGvn, 500 setUseGvn: setUseGvn,
501 resolveType: resolveType, 501 resolveType: resolveType,
502 typesReturned: behavior.typesReturned, 502 typesReturned: behavior.typesReturned,
503 typesInstantiated: behavior.typesInstantiated, 503 typesInstantiated: behavior.typesInstantiated,
504 objectType: compiler.objectClass.computeType(compiler), 504 objectType: compiler.coreTypes.objectType,
505 nullType: compiler.nullClass.computeType(compiler)); 505 nullType: compiler.coreTypes.nullType);
506 506
507 if (!sideEffectsAreEncodedInSpecString) { 507 if (!sideEffectsAreEncodedInSpecString) {
508 new SideEffectsVisitor(behavior.sideEffects) 508 new SideEffectsVisitor(behavior.sideEffects)
509 .visit(behavior.codeTemplate.ast); 509 .visit(behavior.codeTemplate.ast);
510 } 510 }
511 if (!throwBehaviorFromSpecString) { 511 if (!throwBehaviorFromSpecString) {
512 behavior.throwBehavior = 512 behavior.throwBehavior =
513 new ThrowBehaviorVisitor().analyze(behavior.codeTemplate.ast); 513 new ThrowBehaviorVisitor().analyze(behavior.codeTemplate.ast);
514 } 514 }
515 515
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2'). It 557 // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2'). It
558 // is not very satisfactory because it does not work for void, dynamic. 558 // is not very satisfactory because it does not work for void, dynamic.
559 compiler.internalError(argNodes.head, "Unexpected first argument."); 559 compiler.internalError(argNodes.head, "Unexpected first argument.");
560 } 560 }
561 561
562 String specString = specLiteral.dartString.slowToString(); 562 String specString = specLiteral.dartString.slowToString();
563 563
564 dynamic resolveType(String typeString) { 564 dynamic resolveType(String typeString) {
565 return _parseType( 565 return _parseType(
566 typeString, 566 typeString,
567 compiler, 567 compiler.resolution,
568 (name) => resolver.resolveTypeFromString(specLiteral, name), 568 (name) => resolver.resolveTypeFromString(specLiteral, name),
569 jsBuiltinOrEmbeddedGlobalCall); 569 jsBuiltinOrEmbeddedGlobalCall);
570 } 570 }
571 571
572 void setSideEffects(SideEffects newEffects) { 572 void setSideEffects(SideEffects newEffects) {
573 behavior.sideEffects.setTo(newEffects); 573 behavior.sideEffects.setTo(newEffects);
574 } 574 }
575 575
576 processSpecString(compiler, jsBuiltinOrEmbeddedGlobalCall, 576 processSpecString(compiler, jsBuiltinOrEmbeddedGlobalCall,
577 specString, 577 specString,
578 validTags: validTags, 578 validTags: validTags,
579 resolveType: resolveType, 579 resolveType: resolveType,
580 setSideEffects: setSideEffects, 580 setSideEffects: setSideEffects,
581 typesReturned: behavior.typesReturned, 581 typesReturned: behavior.typesReturned,
582 typesInstantiated: behavior.typesInstantiated, 582 typesInstantiated: behavior.typesInstantiated,
583 objectType: compiler.objectClass.computeType(compiler), 583 objectType: compiler.coreTypes.objectType,
584 nullType: compiler.nullClass.computeType(compiler)); 584 nullType: compiler.coreTypes.nullType);
585 } 585 }
586 586
587 static NativeBehavior ofJsBuiltinCall(Send jsBuiltinCall, 587 static NativeBehavior ofJsBuiltinCall(Send jsBuiltinCall,
588 Compiler compiler, 588 Compiler compiler,
589 ResolverVisitor resolver) { 589 ResolverVisitor resolver) {
590 NativeBehavior behavior = new NativeBehavior(); 590 NativeBehavior behavior = new NativeBehavior();
591 behavior.sideEffects.setTo(new SideEffects()); 591 behavior.sideEffects.setTo(new SideEffects());
592 592
593 _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( 593 _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal(
594 behavior, jsBuiltinCall, compiler, resolver, isBuiltin: true); 594 behavior, jsBuiltinCall, compiler, resolver, isBuiltin: true);
(...skipping 12 matching lines...) Expand all
607 behavior.throwBehavior = NativeThrowBehavior.NEVER; 607 behavior.throwBehavior = NativeThrowBehavior.NEVER;
608 608
609 _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( 609 _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal(
610 behavior, jsEmbeddedGlobalCall, compiler, resolver, 610 behavior, jsEmbeddedGlobalCall, compiler, resolver,
611 isBuiltin: false, 611 isBuiltin: false,
612 validTags: const ['returns', 'creates']); 612 validTags: const ['returns', 'creates']);
613 613
614 return behavior; 614 return behavior;
615 } 615 }
616 616
617 static NativeBehavior ofMethod(FunctionElement method, Compiler compiler) { 617 static NativeBehavior ofMethod(FunctionElement method, Compiler compiler) {
618 FunctionType type = method.computeType(compiler); 618 FunctionType type = method.computeType(compiler.resolution);
619 var behavior = new NativeBehavior(); 619 var behavior = new NativeBehavior();
620 behavior.typesReturned.add(type.returnType); 620 behavior.typesReturned.add(type.returnType);
621 if (!type.returnType.isVoid) { 621 if (!type.returnType.isVoid) {
622 // Declared types are nullable. 622 // Declared types are nullable.
623 behavior.typesReturned.add(compiler.nullClass.computeType(compiler)); 623 behavior.typesReturned.add(compiler.coreTypes.nullType);
624 } 624 }
625 behavior._capture(type, compiler); 625 behavior._capture(type, compiler.resolution);
626 626
627 // TODO(sra): Optional arguments are currently missing from the 627 // TODO(sra): Optional arguments are currently missing from the
628 // DartType. This should be fixed so the following work-around can be 628 // DartType. This should be fixed so the following work-around can be
629 // removed. 629 // removed.
630 method.functionSignature.forEachOptionalParameter( 630 method.functionSignature.forEachOptionalParameter(
631 (ParameterElement parameter) { 631 (ParameterElement parameter) {
632 behavior._escape(parameter.type, compiler); 632 behavior._escape(parameter.type, compiler.resolution);
633 }); 633 });
634 634
635 behavior._overrideWithAnnotations(method, compiler); 635 behavior._overrideWithAnnotations(method, compiler);
636 return behavior; 636 return behavior;
637 } 637 }
638 638
639 static NativeBehavior ofFieldLoad(MemberElement field, Compiler compiler) { 639 static NativeBehavior ofFieldLoad(MemberElement field, Compiler compiler) {
640 DartType type = field.computeType(compiler); 640 DartType type = field.computeType(compiler.resolution);
641 var behavior = new NativeBehavior(); 641 var behavior = new NativeBehavior();
642 behavior.typesReturned.add(type); 642 behavior.typesReturned.add(type);
643 // Declared types are nullable. 643 // Declared types are nullable.
644 behavior.typesReturned.add(compiler.nullClass.computeType(compiler)); 644 behavior.typesReturned.add(compiler.coreTypes.nullType);
645 behavior._capture(type, compiler); 645 behavior._capture(type, compiler.resolution);
646 behavior._overrideWithAnnotations(field, compiler); 646 behavior._overrideWithAnnotations(field, compiler);
647 return behavior; 647 return behavior;
648 } 648 }
649 649
650 static NativeBehavior ofFieldStore(MemberElement field, Compiler compiler) { 650 static NativeBehavior ofFieldStore(MemberElement field, Compiler compiler) {
651 DartType type = field.computeType(compiler); 651 DartType type = field.computeType(compiler.resolution);
652 var behavior = new NativeBehavior(); 652 var behavior = new NativeBehavior();
653 behavior._escape(type, compiler); 653 behavior._escape(type, compiler.resolution);
654 // We don't override the default behaviour - the annotations apply to 654 // We don't override the default behaviour - the annotations apply to
655 // loading the field. 655 // loading the field.
656 return behavior; 656 return behavior;
657 } 657 }
658 658
659 void _overrideWithAnnotations(Element element, Compiler compiler) { 659 void _overrideWithAnnotations(Element element, Compiler compiler) {
660 if (element.implementation.metadata.isEmpty) return; 660 if (element.implementation.metadata.isEmpty) return;
661 661
662 DartType lookup(String name) { 662 DartType lookup(String name) {
663 Element e = element.buildScope().lookup(name); 663 Element e = element.buildScope().lookup(name);
664 if (e == null) return null; 664 if (e == null) return null;
665 if (e is! ClassElement) return null; 665 if (e is! ClassElement) return null;
666 ClassElement cls = e; 666 ClassElement cls = e;
667 cls.ensureResolved(compiler); 667 cls.ensureResolved(compiler.resolution);
668 return cls.thisType; 668 return cls.thisType;
669 } 669 }
670 670
671 NativeEnqueuer enqueuer = compiler.enqueuer.resolution.nativeEnqueuer; 671 NativeEnqueuer enqueuer = compiler.enqueuer.resolution.nativeEnqueuer;
672 var creates = _collect(element, compiler, enqueuer.annotationCreatesClass, 672 var creates = _collect(element, compiler, enqueuer.annotationCreatesClass,
673 lookup); 673 lookup);
674 var returns = _collect(element, compiler, enqueuer.annotationReturnsClass, 674 var returns = _collect(element, compiler, enqueuer.annotationReturnsClass,
675 lookup); 675 lookup);
676 676
677 if (creates != null) { 677 if (creates != null) {
678 typesInstantiated..clear()..addAll(creates); 678 typesInstantiated..clear()..addAll(creates);
679 } 679 }
680 if (returns != null) { 680 if (returns != null) {
681 typesReturned..clear()..addAll(returns); 681 typesReturned..clear()..addAll(returns);
682 } 682 }
683 } 683 }
684 684
685 /** 685 /**
686 * Returns a list of type constraints from the annotations of 686 * Returns a list of type constraints from the annotations of
687 * [annotationClass]. 687 * [annotationClass].
688 * Returns `null` if no constraints. 688 * Returns `null` if no constraints.
689 */ 689 */
690 static _collect(Element element, Compiler compiler, Element annotationClass, 690 static _collect(Element element, Compiler compiler, Element annotationClass,
691 lookup(str)) { 691 lookup(str)) {
692 var types = null; 692 var types = null;
693 for (MetadataAnnotation annotation in element.implementation.metadata) { 693 for (MetadataAnnotation annotation in element.implementation.metadata) {
694 annotation.ensureResolved(compiler); 694 annotation.ensureResolved(compiler.resolution);
695 ConstantValue value = 695 ConstantValue value =
696 compiler.constants.getConstantValue(annotation.constant); 696 compiler.constants.getConstantValue(annotation.constant);
697 if (!value.isConstructedObject) continue; 697 if (!value.isConstructedObject) continue;
698 ConstructedConstantValue constructedObject = value; 698 ConstructedConstantValue constructedObject = value;
699 if (constructedObject.type.element != annotationClass) continue; 699 if (constructedObject.type.element != annotationClass) continue;
700 700
701 Iterable<ConstantValue> fields = constructedObject.fields.values; 701 Iterable<ConstantValue> fields = constructedObject.fields.values;
702 // TODO(sra): Better validation of the constant. 702 // TODO(sra): Better validation of the constant.
703 if (fields.length != 1 || !fields.single.isString) { 703 if (fields.length != 1 || !fields.single.isString) {
704 PartialMetadataAnnotation partial = annotation;
705 compiler.internalError(annotation, 704 compiler.internalError(annotation,
706 'Annotations needs one string: ${partial.parseNode(compiler)}'); 705 'Annotations needs one string: ${annotation.node}');
707 } 706 }
708 StringConstantValue specStringConstant = fields.single; 707 StringConstantValue specStringConstant = fields.single;
709 String specString = specStringConstant.toDartString().slowToString(); 708 String specString = specStringConstant.toDartString().slowToString();
710 for (final typeString in specString.split('|')) { 709 for (final typeString in specString.split('|')) {
711 var type = _parseType(typeString, compiler, lookup, annotation); 710 var type =
711 _parseType(typeString, compiler.resolution, lookup, annotation);
712 if (types == null) types = []; 712 if (types == null) types = [];
713 types.add(type); 713 types.add(type);
714 } 714 }
715 } 715 }
716 return types; 716 return types;
717 } 717 }
718 718
719 /// Models the behavior of having intances of [type] escape from Dart code 719 /// Models the behavior of having intances of [type] escape from Dart code
720 /// into native code. 720 /// into native code.
721 void _escape(DartType type, Compiler compiler) { 721 void _escape(DartType type, Resolution resolution) {
722 type = type.unalias(compiler); 722 type = type.unalias(resolution);
723 if (type is FunctionType) { 723 if (type is FunctionType) {
724 FunctionType functionType = type; 724 FunctionType functionType = type;
725 // A function might be called from native code, passing us novel 725 // A function might be called from native code, passing us novel
726 // parameters. 726 // parameters.
727 _escape(functionType.returnType, compiler); 727 _escape(functionType.returnType, resolution);
728 for (DartType parameter in functionType.parameterTypes) { 728 for (DartType parameter in functionType.parameterTypes) {
729 _capture(parameter, compiler); 729 _capture(parameter, resolution);
730 } 730 }
731 } 731 }
732 } 732 }
733 733
734 /// Models the behavior of Dart code receiving instances and methods of [type] 734 /// Models the behavior of Dart code receiving instances and methods of [type]
735 /// from native code. We usually start the analysis by capturing a native 735 /// from native code. We usually start the analysis by capturing a native
736 /// method that has been used. 736 /// method that has been used.
737 void _capture(DartType type, Compiler compiler) { 737 void _capture(DartType type, Resolution resolution) {
738 type = type.unalias(compiler); 738 type = type.unalias(resolution);
739 if (type is FunctionType) { 739 if (type is FunctionType) {
740 FunctionType functionType = type; 740 FunctionType functionType = type;
741 _capture(functionType.returnType, compiler); 741 _capture(functionType.returnType, resolution);
742 for (DartType parameter in functionType.parameterTypes) { 742 for (DartType parameter in functionType.parameterTypes) {
743 _escape(parameter, compiler); 743 _escape(parameter, resolution);
744 } 744 }
745 } else { 745 } else {
746 typesInstantiated.add(type); 746 typesInstantiated.add(type);
747 } 747 }
748 } 748 }
749 749
750 static dynamic _parseType(String typeString, Compiler compiler, 750 static dynamic _parseType(
751 String typeString,
752 Resolution resolution,
751 lookup(name), locationNodeOrElement) { 753 lookup(name), locationNodeOrElement) {
752 if (typeString == '=Object') return SpecialType.JsObject; 754 if (typeString == '=Object') return SpecialType.JsObject;
753 if (typeString == 'dynamic') { 755 if (typeString == 'dynamic') {
754 return const DynamicType(); 756 return const DynamicType();
755 } 757 }
756 var type = lookup(typeString); 758 var type = lookup(typeString);
757 if (type != null) return type; 759 if (type != null) return type;
758 760
759 int index = typeString.indexOf('<'); 761 int index = typeString.indexOf('<');
760 if (index < 1) { 762 if (index < 1) {
761 compiler.reportErrorMessage( 763 resolution.listener.reportErrorMessage(
762 _errorNode(locationNodeOrElement, compiler), 764 _errorNode(locationNodeOrElement, resolution.parsing),
763 MessageKind.GENERIC, 765 MessageKind.GENERIC,
764 {'text': "Type '$typeString' not found."}); 766 {'text': "Type '$typeString' not found."});
765 return const DynamicType(); 767 return const DynamicType();
766 } 768 }
767 type = lookup(typeString.substring(0, index)); 769 type = lookup(typeString.substring(0, index));
768 if (type != null) { 770 if (type != null) {
769 // TODO(sra): Parse type parameters. 771 // TODO(sra): Parse type parameters.
770 return type; 772 return type;
771 } 773 }
772 compiler.reportErrorMessage( 774 resolution.listener.reportErrorMessage(
773 _errorNode(locationNodeOrElement, compiler), 775 _errorNode(locationNodeOrElement, resolution.parsing),
774 MessageKind.GENERIC, 776 MessageKind.GENERIC,
775 {'text': "Type '$typeString' not found."}); 777 {'text': "Type '$typeString' not found."});
776 return const DynamicType(); 778 return const DynamicType();
777 } 779 }
778 780
779 static _errorNode(locationNodeOrElement, compiler) { 781 static _errorNode(locationNodeOrElement, Parsing parsing) {
780 if (locationNodeOrElement is Node) return locationNodeOrElement; 782 if (locationNodeOrElement is Node) return locationNodeOrElement;
781 return locationNodeOrElement.parseNode(compiler); 783 return locationNodeOrElement.parseNode(parsing);
782 } 784 }
783 } 785 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/mirrors_used.dart ('k') | pkg/compiler/lib/src/native/enqueue.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698