| OLD | NEW |
| 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 ForeignResolver; | 6 import '../common/backend_api.dart' show 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; | |
| 10 import '../constants/expressions.dart'; | |
| 11 import '../constants/values.dart'; | 9 import '../constants/values.dart'; |
| 12 import '../common_elements.dart' show CommonElements; | 10 import '../common_elements.dart' show CommonElements; |
| 13 import '../elements/elements.dart'; | 11 import '../elements/elements.dart'; |
| 14 import '../elements/entities.dart'; | 12 import '../elements/entities.dart'; |
| 15 import '../elements/resolution_types.dart'; | 13 import '../elements/resolution_types.dart'; |
| 16 import '../elements/types.dart'; | 14 import '../elements/types.dart'; |
| 17 import '../js/js.dart' as js; | 15 import '../js/js.dart' as js; |
| 18 import '../js_backend/native_data.dart' show NativeData; | 16 import '../js_backend/native_data.dart' show NativeData; |
| 19 import '../tree/tree.dart'; | 17 import '../tree/tree.dart'; |
| 20 import '../universe/side_effects.dart' show SideEffects; | 18 import '../universe/side_effects.dart' show SideEffects; |
| (...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 763 _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( | 761 _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( |
| 764 behavior, spannable, specString, lookupType, reporter, commonElements, | 762 behavior, spannable, specString, lookupType, reporter, commonElements, |
| 765 validTags: ['returns', 'creates']); | 763 validTags: ['returns', 'creates']); |
| 766 return behavior; | 764 return behavior; |
| 767 } | 765 } |
| 768 | 766 |
| 769 static NativeBehavior ofMethodElement( | 767 static NativeBehavior ofMethodElement( |
| 770 MethodElement element, Compiler compiler, | 768 MethodElement element, Compiler compiler, |
| 771 {bool isJsInterop}) { | 769 {bool isJsInterop}) { |
| 772 ResolutionFunctionType type = element.computeType(compiler.resolution); | 770 ResolutionFunctionType type = element.computeType(compiler.resolution); |
| 773 List<ConstantExpression> metadata = <ConstantExpression>[]; | 771 List<ConstantValue> metadata = <ConstantValue>[]; |
| 774 for (MetadataAnnotation annotation in element.implementation.metadata) { | 772 for (MetadataAnnotation annotation in element.implementation.metadata) { |
| 775 annotation.ensureResolved(compiler.resolution); | 773 annotation.ensureResolved(compiler.resolution); |
| 776 metadata.add(annotation.constant); | 774 metadata.add(compiler.constants.getConstantValue(annotation.constant)); |
| 777 } | 775 } |
| 778 | 776 |
| 779 BehaviorBuilder builder = | 777 BehaviorBuilder builder = |
| 780 new ResolverBehaviorBuilder(compiler, compiler.backend.nativeData); | 778 new ResolverBehaviorBuilder(compiler, compiler.backend.nativeData); |
| 781 return builder.buildMethodBehavior( | 779 return builder.buildMethodBehavior( |
| 782 type, metadata, lookupFromElement(compiler.resolution, element), | 780 type, metadata, lookupFromElement(compiler.resolution, element), |
| 783 isJsInterop: isJsInterop); | 781 isJsInterop: isJsInterop); |
| 784 } | 782 } |
| 785 | 783 |
| 786 static NativeBehavior ofFieldElementLoad( | 784 static NativeBehavior ofFieldElementLoad( |
| 787 MemberElement element, Compiler compiler, | 785 MemberElement element, Compiler compiler, |
| 788 {bool isJsInterop}) { | 786 {bool isJsInterop}) { |
| 789 Resolution resolution = compiler.resolution; | 787 Resolution resolution = compiler.resolution; |
| 790 ResolutionDartType type = element.computeType(resolution); | 788 ResolutionDartType type = element.computeType(resolution); |
| 791 List<ConstantExpression> metadata = <ConstantExpression>[]; | 789 List<ConstantValue> metadata = <ConstantValue>[]; |
| 792 for (MetadataAnnotation annotation in element.implementation.metadata) { | 790 for (MetadataAnnotation annotation in element.implementation.metadata) { |
| 793 annotation.ensureResolved(compiler.resolution); | 791 annotation.ensureResolved(compiler.resolution); |
| 794 metadata.add(annotation.constant); | 792 metadata.add(compiler.constants.getConstantValue(annotation.constant)); |
| 795 } | 793 } |
| 796 | 794 |
| 797 BehaviorBuilder builder = | 795 BehaviorBuilder builder = |
| 798 new ResolverBehaviorBuilder(compiler, compiler.backend.nativeData); | 796 new ResolverBehaviorBuilder(compiler, compiler.backend.nativeData); |
| 799 return builder.buildFieldLoadBehavior( | 797 return builder.buildFieldLoadBehavior( |
| 800 type, metadata, lookupFromElement(resolution, element), | 798 type, metadata, lookupFromElement(resolution, element), |
| 801 isJsInterop: isJsInterop); | 799 isJsInterop: isJsInterop); |
| 802 } | 800 } |
| 803 | 801 |
| 804 static NativeBehavior ofFieldElementStore( | 802 static NativeBehavior ofFieldElementStore( |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 844 return type; | 842 return type; |
| 845 } | 843 } |
| 846 } | 844 } |
| 847 return const ResolutionDynamicType(); | 845 return const ResolutionDynamicType(); |
| 848 } | 846 } |
| 849 } | 847 } |
| 850 | 848 |
| 851 abstract class BehaviorBuilder { | 849 abstract class BehaviorBuilder { |
| 852 CommonElements get commonElements; | 850 CommonElements get commonElements; |
| 853 DiagnosticReporter get reporter; | 851 DiagnosticReporter get reporter; |
| 854 ConstantEnvironment get constants; | |
| 855 NativeData get nativeData; | 852 NativeData get nativeData; |
| 856 bool get trustJSInteropTypeAnnotations; | 853 bool get trustJSInteropTypeAnnotations; |
| 857 | 854 |
| 858 Resolution get resolution => null; | 855 Resolution get resolution => null; |
| 859 | 856 |
| 860 NativeBehavior _behavior; | 857 NativeBehavior _behavior; |
| 861 | 858 |
| 862 void _overrideWithAnnotations( | 859 void _overrideWithAnnotations( |
| 863 Iterable<ConstantExpression> metadata, TypeLookup lookupType) { | 860 Iterable<ConstantValue> metadata, TypeLookup lookupType) { |
| 864 if (metadata.isEmpty) return; | 861 if (metadata.isEmpty) return; |
| 865 | 862 |
| 866 List creates = | 863 List creates = |
| 867 _collect(metadata, commonElements.annotationCreatesClass, lookupType); | 864 _collect(metadata, commonElements.annotationCreatesClass, lookupType); |
| 868 List returns = | 865 List returns = |
| 869 _collect(metadata, commonElements.annotationReturnsClass, lookupType); | 866 _collect(metadata, commonElements.annotationReturnsClass, lookupType); |
| 870 | 867 |
| 871 if (creates != null) { | 868 if (creates != null) { |
| 872 _behavior.typesInstantiated | 869 _behavior.typesInstantiated |
| 873 ..clear() | 870 ..clear() |
| 874 ..addAll(creates); | 871 ..addAll(creates); |
| 875 } | 872 } |
| 876 if (returns != null) { | 873 if (returns != null) { |
| 877 _behavior.typesReturned | 874 _behavior.typesReturned |
| 878 ..clear() | 875 ..clear() |
| 879 ..addAll(returns); | 876 ..addAll(returns); |
| 880 } | 877 } |
| 881 } | 878 } |
| 882 | 879 |
| 883 /** | 880 /** |
| 884 * Returns a list of type constraints from the annotations of | 881 * Returns a list of type constraints from the annotations of |
| 885 * [annotationClass]. | 882 * [annotationClass]. |
| 886 * Returns `null` if no constraints. | 883 * Returns `null` if no constraints. |
| 887 */ | 884 */ |
| 888 List _collect(Iterable<ConstantExpression> metadata, | 885 List _collect(Iterable<ConstantValue> metadata, ClassEntity annotationClass, |
| 889 ClassEntity annotationClass, TypeLookup lookupType) { | 886 TypeLookup lookupType) { |
| 890 var types = null; | 887 var types = null; |
| 891 for (ConstantExpression constant in metadata) { | 888 for (ConstantValue value in metadata) { |
| 892 ConstantValue value = constants.getConstantValue(constant); | |
| 893 if (!value.isConstructedObject) continue; | 889 if (!value.isConstructedObject) continue; |
| 894 ConstructedConstantValue constructedObject = value; | 890 ConstructedConstantValue constructedObject = value; |
| 895 if (constructedObject.type.element != annotationClass) continue; | 891 if (constructedObject.type.element != annotationClass) continue; |
| 896 | 892 |
| 897 Iterable<ConstantValue> fields = constructedObject.fields.values; | 893 Iterable<ConstantValue> fields = constructedObject.fields.values; |
| 898 // TODO(sra): Better validation of the constant. | 894 // TODO(sra): Better validation of the constant. |
| 899 if (fields.length != 1 || !fields.single.isString) { | 895 if (fields.length != 1 || !fields.single.isString) { |
| 900 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, | 896 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, |
| 901 'Annotations needs one string: ${constant.toStructuredText()}'); | 897 'Annotations needs one string: ${value.toStructuredText()}'); |
| 902 } | 898 } |
| 903 StringConstantValue specStringConstant = fields.single; | 899 StringConstantValue specStringConstant = fields.single; |
| 904 String specString = specStringConstant.toDartString().slowToString(); | 900 String specString = specStringConstant.toDartString().slowToString(); |
| 905 for (final typeString in specString.split('|')) { | 901 for (final typeString in specString.split('|')) { |
| 906 var type = NativeBehavior._parseType(typeString, lookupType); | 902 var type = NativeBehavior._parseType(typeString, lookupType); |
| 907 if (types == null) types = []; | 903 if (types == null) types = []; |
| 908 types.add(type); | 904 types.add(type); |
| 909 } | 905 } |
| 910 } | 906 } |
| 911 return types; | 907 return types; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 } else { | 967 } else { |
| 972 // Otherwise, when the declared type is a Dart type, we do not | 968 // Otherwise, when the declared type is a Dart type, we do not |
| 973 // register an allocation because we assume it cannot be instantiated | 969 // register an allocation because we assume it cannot be instantiated |
| 974 // from within the JS-interop code. It must have escaped from another | 970 // from within the JS-interop code. It must have escaped from another |
| 975 // API. | 971 // API. |
| 976 } | 972 } |
| 977 } | 973 } |
| 978 } | 974 } |
| 979 } | 975 } |
| 980 | 976 |
| 981 NativeBehavior buildFieldLoadBehavior(DartType type, | 977 NativeBehavior buildFieldLoadBehavior( |
| 982 Iterable<ConstantExpression> metadata, TypeLookup lookupType, | 978 DartType type, Iterable<ConstantValue> metadata, TypeLookup lookupType, |
| 983 {bool isJsInterop}) { | 979 {bool isJsInterop}) { |
| 984 _behavior = new NativeBehavior(); | 980 _behavior = new NativeBehavior(); |
| 985 // TODO(sigmund,sra): consider doing something better for numeric types. | 981 // TODO(sigmund,sra): consider doing something better for numeric types. |
| 986 _behavior.typesReturned.add(!isJsInterop || trustJSInteropTypeAnnotations | 982 _behavior.typesReturned.add(!isJsInterop || trustJSInteropTypeAnnotations |
| 987 ? type | 983 ? type |
| 988 : commonElements.dynamicType); | 984 : commonElements.dynamicType); |
| 989 // Declared types are nullable. | 985 // Declared types are nullable. |
| 990 _behavior.typesReturned.add(commonElements.nullType); | 986 _behavior.typesReturned.add(commonElements.nullType); |
| 991 _capture(type, isInterop: isJsInterop); | 987 _capture(type, isInterop: isJsInterop); |
| 992 _overrideWithAnnotations(metadata, lookupType); | 988 _overrideWithAnnotations(metadata, lookupType); |
| 993 return _behavior; | 989 return _behavior; |
| 994 } | 990 } |
| 995 | 991 |
| 996 NativeBehavior buildFieldStoreBehavior(DartType type) { | 992 NativeBehavior buildFieldStoreBehavior(DartType type) { |
| 997 _behavior = new NativeBehavior(); | 993 _behavior = new NativeBehavior(); |
| 998 _escape(type); | 994 _escape(type); |
| 999 // We don't override the default behaviour - the annotations apply to | 995 // We don't override the default behaviour - the annotations apply to |
| 1000 // loading the field. | 996 // loading the field. |
| 1001 return _behavior; | 997 return _behavior; |
| 1002 } | 998 } |
| 1003 | 999 |
| 1004 NativeBehavior buildMethodBehavior(FunctionType type, | 1000 NativeBehavior buildMethodBehavior(FunctionType type, |
| 1005 List<ConstantExpression> metadata, TypeLookup lookupType, | 1001 Iterable<ConstantValue> metadata, TypeLookup lookupType, |
| 1006 {bool isJsInterop}) { | 1002 {bool isJsInterop}) { |
| 1007 _behavior = new NativeBehavior(); | 1003 _behavior = new NativeBehavior(); |
| 1008 DartType returnType = type.returnType; | 1004 DartType returnType = type.returnType; |
| 1009 // Note: For dart:html and other internal libraries we maintain, we can | 1005 // Note: For dart:html and other internal libraries we maintain, we can |
| 1010 // trust the return type and use it to limit what we enqueue. We have to | 1006 // trust the return type and use it to limit what we enqueue. We have to |
| 1011 // be more conservative about JS interop types and assume they can return | 1007 // be more conservative about JS interop types and assume they can return |
| 1012 // anything (unless the user provides the experimental flag to trust the | 1008 // anything (unless the user provides the experimental flag to trust the |
| 1013 // type of js-interop APIs). We do restrict the allocation effects and say | 1009 // type of js-interop APIs). We do restrict the allocation effects and say |
| 1014 // that interop calls create only interop types (which may be unsound if | 1010 // that interop calls create only interop types (which may be unsound if |
| 1015 // an interop call returns a DOM type and declares a dynamic return type, | 1011 // an interop call returns a DOM type and declares a dynamic return type, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1043 ResolverBehaviorBuilder(this.compiler, this.nativeData); | 1039 ResolverBehaviorBuilder(this.compiler, this.nativeData); |
| 1044 | 1040 |
| 1045 @override | 1041 @override |
| 1046 CommonElements get commonElements => compiler.commonElements; | 1042 CommonElements get commonElements => compiler.commonElements; |
| 1047 | 1043 |
| 1048 @override | 1044 @override |
| 1049 bool get trustJSInteropTypeAnnotations => | 1045 bool get trustJSInteropTypeAnnotations => |
| 1050 compiler.options.trustJSInteropTypeAnnotations; | 1046 compiler.options.trustJSInteropTypeAnnotations; |
| 1051 | 1047 |
| 1052 @override | 1048 @override |
| 1053 ConstantEnvironment get constants => compiler.constants; | |
| 1054 | |
| 1055 @override | |
| 1056 DiagnosticReporter get reporter => compiler.reporter; | 1049 DiagnosticReporter get reporter => compiler.reporter; |
| 1057 | 1050 |
| 1058 @override | 1051 @override |
| 1059 Resolution get resolution => compiler.resolution; | 1052 Resolution get resolution => compiler.resolution; |
| 1060 } | 1053 } |
| OLD | NEW |