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

Side by Side Diff: pkg/compiler/lib/src/native/behavior.dart

Issue 2685673004: Handle Creates and Returns annotations in KernelBehaviorBuilder (Closed)
Patch Set: Updated cf. comment Created 3 years, 10 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) 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 import '../common.dart'; 5 import '../common.dart';
6 import '../common/backend_api.dart' show BackendClasses, ForeignResolver; 6 import '../common/backend_api.dart' show BackendClasses, ForeignResolver;
7 import '../common/resolution.dart' show ParsingContext, Resolution; 7 import '../common/resolution.dart' show ParsingContext, Resolution;
8 import '../compiler.dart' show Compiler; 8 import '../compiler.dart' show Compiler;
9 import '../compile_time_constants.dart' show ConstantEnvironment; 9 import '../compile_time_constants.dart' show ConstantEnvironment;
10 import '../constants/expressions.dart'; 10 import '../constants/expressions.dart';
11 import '../constants/values.dart'; 11 import '../constants/values.dart';
12 import '../core_types.dart' show CommonElements; 12 import '../core_types.dart' show CommonElements;
13 import '../elements/elements.dart'; 13 import '../elements/elements.dart';
14 import '../elements/entities.dart'; 14 import '../elements/entities.dart';
15 import '../elements/resolution_types.dart'; 15 import '../elements/resolution_types.dart';
16 import '../elements/types.dart'; 16 import '../elements/types.dart';
17 import '../js/js.dart' as js; 17 import '../js/js.dart' as js;
18 import '../js_backend/js_backend.dart'; 18 import '../js_backend/js_backend.dart';
19 import '../js_backend/backend_helpers.dart'; 19 import '../js_backend/backend_helpers.dart';
20 import '../options.dart'; 20 import '../options.dart';
21 import '../tree/tree.dart'; 21 import '../tree/tree.dart';
22 import '../universe/side_effects.dart' show SideEffects; 22 import '../universe/side_effects.dart' show SideEffects;
23 import '../util/util.dart'; 23 import '../util/util.dart';
24 import 'js.dart'; 24 import 'js.dart';
25 25
26 typedef dynamic /*DartType|SpecialType*/ TypeLookup(String typeString); 26 typedef dynamic /*DartType|SpecialType*/ TypeLookup(String typeString,
27 {bool required});
27 28
28 /// This class is a temporary work-around until we get a more powerful DartType. 29 /// This class is a temporary work-around until we get a more powerful DartType.
29 class SpecialType { 30 class SpecialType {
30 final String name; 31 final String name;
31 const SpecialType._(this.name); 32 const SpecialType._(this.name);
32 33
33 /// The type Object, but no subtypes: 34 /// The type Object, but no subtypes:
34 static const JsObject = const SpecialType._('=Object'); 35 static const JsObject = const SpecialType._('=Object');
35 36
36 int get hashCode => name.hashCode; 37 int get hashCode => name.hashCode;
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 } 311 }
311 return; 312 return;
312 } 313 }
313 if (typesString == '' || typesString == 'var') { 314 if (typesString == '' || typesString == 'var') {
314 if (onVar != null) { 315 if (onVar != null) {
315 onVar(); 316 onVar();
316 } 317 }
317 return; 318 return;
318 } 319 }
319 for (final typeString in typesString.split('|')) { 320 for (final typeString in typesString.split('|')) {
320 onType(_parseType(typeString.trim(), spannable, reporter, lookupType)); 321 onType(_parseType(typeString.trim(), lookupType));
321 } 322 }
322 } 323 }
323 324
324 if (!specString.contains(';') && !specString.contains(':')) { 325 if (!specString.contains(';') && !specString.contains(':')) {
325 // Form (1), types or pseudo-types like 'void' and 'var'. 326 // Form (1), types or pseudo-types like 'void' and 'var'.
326 resolveTypesString(specString.trim(), onVar: () { 327 resolveTypesString(specString.trim(), onVar: () {
327 typesReturned.add(objectType); 328 typesReturned.add(objectType);
328 typesReturned.add(nullType); 329 typesReturned.add(nullType);
329 }, onType: (type) { 330 }, onType: (type) {
330 typesInstantiated.add(type); 331 typesInstantiated.add(type);
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 reportError("Unrecognized side-effect flag: '$dependency'."); 493 reportError("Unrecognized side-effect flag: '$dependency'.");
493 } 494 }
494 } 495 }
495 } 496 }
496 497
497 return sideEffects; 498 return sideEffects;
498 } 499 }
499 500
500 /// Returns a [TypeLookup] that uses [resolver] to perform lookup and [node] 501 /// Returns a [TypeLookup] that uses [resolver] to perform lookup and [node]
501 /// as position for errors. 502 /// as position for errors.
502 static TypeLookup _typeLookup(Node node, ForeignResolver resolver) { 503 static TypeLookup _typeLookup(
503 return (String name) => resolver.resolveTypeFromString(node, name); 504 Node node, DiagnosticReporter reporter, ForeignResolver resolver) {
505 ResolutionDartType lookup(String name, {bool required}) {
506 ResolutionDartType type = resolver.resolveTypeFromString(node, name);
507 if (type == null && required) {
508 reporter.reportErrorMessage(
509 node, MessageKind.GENERIC, {'text': "Type '$name' not found."});
510 }
511 return type;
512 }
513
514 return lookup;
504 } 515 }
505 516
506 /// Compute the [NativeBehavior] for a [Send] node calling the 'JS' function. 517 /// Compute the [NativeBehavior] for a [Send] node calling the 'JS' function.
507 static NativeBehavior ofJsCallSend( 518 static NativeBehavior ofJsCallSend(
508 Send jsCall, 519 Send jsCall,
509 DiagnosticReporter reporter, 520 DiagnosticReporter reporter,
510 ParsingContext parsing, 521 ParsingContext parsing,
511 CommonElements commonElements, 522 CommonElements commonElements,
512 ForeignResolver resolver) { 523 ForeignResolver resolver) {
513 var argNodes = jsCall.arguments; 524 var argNodes = jsCall.arguments;
(...skipping 12 matching lines...) Expand all
526 var codeArgument = argNodes.tail.head; 537 var codeArgument = argNodes.tail.head;
527 if (codeArgument is! StringNode || codeArgument.isInterpolation) { 538 if (codeArgument is! StringNode || codeArgument.isInterpolation) {
528 reporter.reportErrorMessage( 539 reporter.reportErrorMessage(
529 codeArgument, MessageKind.WRONG_ARGUMENT_FOR_JS_SECOND); 540 codeArgument, MessageKind.WRONG_ARGUMENT_FOR_JS_SECOND);
530 return new NativeBehavior(); 541 return new NativeBehavior();
531 } 542 }
532 543
533 String specString = specArgument.dartString.slowToString(); 544 String specString = specArgument.dartString.slowToString();
534 String codeString = codeArgument.dartString.slowToString(); 545 String codeString = codeArgument.dartString.slowToString();
535 546
536 return ofJsCall(specString, codeString, _typeLookup(specArgument, resolver), 547 return ofJsCall(
537 specArgument, reporter, commonElements); 548 specString,
549 codeString,
550 _typeLookup(specArgument, reporter, resolver),
551 specArgument,
552 reporter,
553 commonElements);
538 } 554 }
539 555
540 /// Compute the [NativeBehavior] for a call to the 'JS' function with the 556 /// Compute the [NativeBehavior] for a call to the 'JS' function with the
541 /// given [specString] and [codeString] (first and second arguments). 557 /// given [specString] and [codeString] (first and second arguments).
542 static NativeBehavior ofJsCall( 558 static NativeBehavior ofJsCall(
543 String specString, 559 String specString,
544 String codeString, 560 String codeString,
545 TypeLookup lookupType, 561 TypeLookup lookupType,
546 Spannable spannable, 562 Spannable spannable,
547 DiagnosticReporter reporter, 563 DiagnosticReporter reporter,
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 668
653 LiteralString specLiteral = argNodes.head.asLiteralString(); 669 LiteralString specLiteral = argNodes.head.asLiteralString();
654 if (specLiteral == null) { 670 if (specLiteral == null) {
655 // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2'). It 671 // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2'). It
656 // is not very satisfactory because it does not work for void, dynamic. 672 // is not very satisfactory because it does not work for void, dynamic.
657 reporter.internalError(argNodes.head, "Unexpected first argument."); 673 reporter.internalError(argNodes.head, "Unexpected first argument.");
658 } 674 }
659 675
660 String specString = specLiteral.dartString.slowToString(); 676 String specString = specLiteral.dartString.slowToString();
661 677
662 return ofJsBuiltinCall(specString, _typeLookup(jsBuiltinCall, resolver), 678 return ofJsBuiltinCall(
663 jsBuiltinCall, reporter, commonElements); 679 specString,
680 _typeLookup(jsBuiltinCall, reporter, resolver),
681 jsBuiltinCall,
682 reporter,
683 commonElements);
664 } 684 }
665 685
666 static NativeBehavior ofJsBuiltinCall( 686 static NativeBehavior ofJsBuiltinCall(
667 String specString, 687 String specString,
668 TypeLookup lookupType, 688 TypeLookup lookupType,
669 Spannable spannable, 689 Spannable spannable,
670 DiagnosticReporter reporter, 690 DiagnosticReporter reporter,
671 CommonElements commonElements) { 691 CommonElements commonElements) {
672 NativeBehavior behavior = new NativeBehavior(); 692 NativeBehavior behavior = new NativeBehavior();
673 behavior.sideEffects.setTo(new SideEffects()); 693 behavior.sideEffects.setTo(new SideEffects());
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 if (specLiteral == null) { 737 if (specLiteral == null) {
718 // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2'). It 738 // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2'). It
719 // is not very satisfactory because it does not work for void, dynamic. 739 // is not very satisfactory because it does not work for void, dynamic.
720 reporter.internalError(argNodes.head, "Unexpected first argument."); 740 reporter.internalError(argNodes.head, "Unexpected first argument.");
721 } 741 }
722 742
723 String specString = specLiteral.dartString.slowToString(); 743 String specString = specLiteral.dartString.slowToString();
724 744
725 return ofJsEmbeddedGlobalCall( 745 return ofJsEmbeddedGlobalCall(
726 specString, 746 specString,
727 _typeLookup(jsEmbeddedGlobalCall, resolver), 747 _typeLookup(jsEmbeddedGlobalCall, reporter, resolver),
728 jsEmbeddedGlobalCall, 748 jsEmbeddedGlobalCall,
729 reporter, 749 reporter,
730 commonElements); 750 commonElements);
731 } 751 }
732 752
733 static NativeBehavior ofJsEmbeddedGlobalCall( 753 static NativeBehavior ofJsEmbeddedGlobalCall(
734 String specString, 754 String specString,
735 TypeLookup lookupType, 755 TypeLookup lookupType,
736 Spannable spannable, 756 Spannable spannable,
737 DiagnosticReporter reporter, 757 DiagnosticReporter reporter,
(...skipping 12 matching lines...) Expand all
750 770
751 static NativeBehavior ofMethodElement( 771 static NativeBehavior ofMethodElement(
752 FunctionElement element, Compiler compiler) { 772 FunctionElement element, Compiler compiler) {
753 ResolutionFunctionType type = element.computeType(compiler.resolution); 773 ResolutionFunctionType type = element.computeType(compiler.resolution);
754 List<ConstantExpression> metadata = <ConstantExpression>[]; 774 List<ConstantExpression> metadata = <ConstantExpression>[];
755 for (MetadataAnnotation annotation in element.implementation.metadata) { 775 for (MetadataAnnotation annotation in element.implementation.metadata) {
756 annotation.ensureResolved(compiler.resolution); 776 annotation.ensureResolved(compiler.resolution);
757 metadata.add(annotation.constant); 777 metadata.add(annotation.constant);
758 } 778 }
759 779
760 ResolutionDartType lookup(String name) {
761 Element e = element.buildScope().lookup(name);
762 if (e == null) return null;
763 if (e is! ClassElement) return null;
764 ClassElement cls = e;
765 cls.ensureResolved(compiler.resolution);
766 return cls.thisType;
767 }
768
769 BehaviorBuilder builder = new ResolverBehaviorBuilder(compiler); 780 BehaviorBuilder builder = new ResolverBehaviorBuilder(compiler);
770 return builder.buildMethodBehavior(type, metadata, lookup, 781 return builder.buildMethodBehavior(
782 type, metadata, lookupFromElement(compiler.resolution, element),
771 isJsInterop: compiler.backend.isJsInterop(element)); 783 isJsInterop: compiler.backend.isJsInterop(element));
772 } 784 }
773 785
774 static NativeBehavior ofFieldElementLoad( 786 static NativeBehavior ofFieldElementLoad(
775 MemberElement element, Compiler compiler) { 787 MemberElement element, Compiler compiler) {
776 Resolution resolution = compiler.resolution; 788 Resolution resolution = compiler.resolution;
777 ResolutionDartType type = element.computeType(resolution); 789 ResolutionDartType type = element.computeType(resolution);
778 List<ConstantExpression> metadata = <ConstantExpression>[]; 790 List<ConstantExpression> metadata = <ConstantExpression>[];
779 for (MetadataAnnotation annotation in element.implementation.metadata) { 791 for (MetadataAnnotation annotation in element.implementation.metadata) {
780 annotation.ensureResolved(compiler.resolution); 792 annotation.ensureResolved(compiler.resolution);
781 metadata.add(annotation.constant); 793 metadata.add(annotation.constant);
782 } 794 }
783 795
784 ResolutionDartType lookup(String name) {
785 Element e = element.buildScope().lookup(name);
786 if (e == null) return null;
787 if (e is! ClassElement) return null;
788 ClassElement cls = e;
789 cls.ensureResolved(compiler.resolution);
790 return cls.thisType;
791 }
792
793 BehaviorBuilder builder = new ResolverBehaviorBuilder(compiler); 796 BehaviorBuilder builder = new ResolverBehaviorBuilder(compiler);
794 return builder.buildFieldLoadBehavior(type, metadata, lookup, 797 return builder.buildFieldLoadBehavior(
798 type, metadata, lookupFromElement(resolution, element),
795 isJsInterop: compiler.backend.isJsInterop(element)); 799 isJsInterop: compiler.backend.isJsInterop(element));
796 } 800 }
797 801
798 static NativeBehavior ofFieldElementStore( 802 static NativeBehavior ofFieldElementStore(
799 MemberElement field, Compiler compiler) { 803 MemberElement field, Compiler compiler) {
800 BehaviorBuilder builder = new ResolverBehaviorBuilder(compiler); 804 BehaviorBuilder builder = new ResolverBehaviorBuilder(compiler);
801 ResolutionDartType type = field.computeType(compiler.resolution); 805 ResolutionDartType type = field.computeType(compiler.resolution);
802 return builder.buildFieldStoreBehavior(type); 806 return builder.buildFieldStoreBehavior(type);
803 } 807 }
804 808
805 static dynamic /*DartType|SpecialType*/ _parseType(String typeString, 809 static TypeLookup lookupFromElement(Resolution resolution, Element element) {
806 Spannable spannable, DiagnosticReporter reporter, TypeLookup lookupType) { 810 ResolutionDartType lookup(String name, {bool required}) {
811 Element e = element.buildScope().lookup(name);
812 if (e == null || e is! ClassElement) {
813 if (required) {
814 resolution.reporter.reportErrorMessage(element, MessageKind.GENERIC,
815 {'text': "Type '$name' not found."});
816 }
817 return null;
818 }
819 ClassElement cls = e;
820 cls.ensureResolved(resolution);
821 return cls.thisType;
822 }
823
824 return lookup;
825 }
826
827 static dynamic /*DartType|SpecialType*/ _parseType(
828 String typeString, TypeLookup lookupType) {
807 if (typeString == '=Object') return SpecialType.JsObject; 829 if (typeString == '=Object') return SpecialType.JsObject;
808 if (typeString == 'dynamic') { 830 if (typeString == 'dynamic') {
809 return const ResolutionDynamicType(); 831 return const ResolutionDynamicType();
810 } 832 }
811 var type = lookupType(typeString); 833 int index = typeString.indexOf('<');
834 var type = lookupType(typeString, required: index == -1);
812 if (type != null) return type; 835 if (type != null) return type;
813 836
814 int index = typeString.indexOf('<'); 837 if (index != -1) {
815 if (index < 1) { 838 type = lookupType(typeString.substring(0, index), required: true);
816 reporter.reportErrorMessage(spannable, MessageKind.GENERIC, 839 if (type != null) {
817 {'text': "Type '$typeString' not found."}); 840 // TODO(sra): Parse type parameters.
818 return const ResolutionDynamicType(); 841 return type;
842 }
819 } 843 }
820 type = lookupType(typeString.substring(0, index));
821 if (type != null) {
822 // TODO(sra): Parse type parameters.
823 return type;
824 }
825 reporter.reportErrorMessage(spannable, MessageKind.GENERIC,
826 {'text': "Type '$typeString' not found."});
827 return const ResolutionDynamicType(); 844 return const ResolutionDynamicType();
828 } 845 }
829 } 846 }
830 847
831 abstract class BehaviorBuilder { 848 abstract class BehaviorBuilder {
832 CommonElements get commonElements; 849 CommonElements get commonElements;
833 BackendClasses get backendClasses; 850 BackendClasses get backendClasses;
834 BackendHelpers get helpers; 851 BackendHelpers get helpers;
835 DiagnosticReporter get reporter; 852 DiagnosticReporter get reporter;
836 ConstantEnvironment get constants; 853 ConstantEnvironment get constants;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 894
878 Iterable<ConstantValue> fields = constructedObject.fields.values; 895 Iterable<ConstantValue> fields = constructedObject.fields.values;
879 // TODO(sra): Better validation of the constant. 896 // TODO(sra): Better validation of the constant.
880 if (fields.length != 1 || !fields.single.isString) { 897 if (fields.length != 1 || !fields.single.isString) {
881 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, 898 reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
882 'Annotations needs one string: ${constant.toStructuredText()}'); 899 'Annotations needs one string: ${constant.toStructuredText()}');
883 } 900 }
884 StringConstantValue specStringConstant = fields.single; 901 StringConstantValue specStringConstant = fields.single;
885 String specString = specStringConstant.toDartString().slowToString(); 902 String specString = specStringConstant.toDartString().slowToString();
886 for (final typeString in specString.split('|')) { 903 for (final typeString in specString.split('|')) {
887 var type = NativeBehavior._parseType( 904 var type = NativeBehavior._parseType(typeString, lookupType);
888 typeString, CURRENT_ELEMENT_SPANNABLE, reporter, lookupType);
889 if (types == null) types = []; 905 if (types == null) types = [];
890 types.add(type); 906 types.add(type);
891 } 907 }
892 } 908 }
893 return types; 909 return types;
894 } 910 }
895 911
896 /// Models the behavior of having intances of [type] escape from Dart code 912 /// Models the behavior of having intances of [type] escape from Dart code
897 /// into native code. 913 /// into native code.
898 void _escape(DartType type) { 914 void _escape(DartType type) {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 JavaScriptBackend backend = compiler.backend; 1058 JavaScriptBackend backend = compiler.backend;
1043 return backend.helpers; 1059 return backend.helpers;
1044 } 1060 }
1045 1061
1046 @override 1062 @override
1047 BackendClasses get backendClasses => compiler.backend.backendClasses; 1063 BackendClasses get backendClasses => compiler.backend.backendClasses;
1048 1064
1049 @override 1065 @override
1050 Resolution get resolution => compiler.resolution; 1066 Resolution get resolution => compiler.resolution;
1051 } 1067 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/kernel/world_builder.dart ('k') | tests/compiler/dart2js/js_spec_string_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698