Chromium Code Reviews| 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 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 '../constants/expressions.dart'; | 10 import '../constants/expressions.dart'; |
| 10 import '../constants/values.dart'; | 11 import '../constants/values.dart'; |
| 11 import '../core_types.dart' show CommonElements; | 12 import '../core_types.dart' show CommonElements; |
| 13 import '../elements/elements.dart'; | |
| 12 import '../elements/resolution_types.dart'; | 14 import '../elements/resolution_types.dart'; |
| 13 import '../elements/elements.dart'; | 15 import '../elements/types.dart'; |
| 14 import '../js/js.dart' as js; | 16 import '../js/js.dart' as js; |
| 15 import '../js_backend/js_backend.dart'; | 17 import '../js_backend/js_backend.dart'; |
| 18 import '../js_backend/backend_helpers.dart'; | |
| 19 import '../options.dart'; | |
| 16 import '../tree/tree.dart'; | 20 import '../tree/tree.dart'; |
| 17 import '../universe/side_effects.dart' show SideEffects; | 21 import '../universe/side_effects.dart' show SideEffects; |
| 18 import '../util/util.dart'; | 22 import '../util/util.dart'; |
| 19 import 'enqueue.dart'; | |
| 20 import 'js.dart'; | 23 import 'js.dart'; |
| 21 | 24 |
| 22 typedef dynamic /*DartType|SpecialType*/ TypeLookup(String typeString); | 25 typedef dynamic /*DartType|SpecialType*/ TypeLookup(String typeString); |
| 23 | 26 |
| 24 /// This class is a temporary work-around until we get a more powerful DartType. | 27 /// This class is a temporary work-around until we get a more powerful DartType. |
| 25 class SpecialType { | 28 class SpecialType { |
| 26 final String name; | 29 final String name; |
| 27 const SpecialType._(this.name); | 30 const SpecialType._(this.name); |
| 28 | 31 |
| 29 /// The type Object, but no subtypes: | 32 /// The type Object, but no subtypes: |
| (...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 755 | 758 |
| 756 ResolutionDartType lookup(String name) { | 759 ResolutionDartType lookup(String name) { |
| 757 Element e = element.buildScope().lookup(name); | 760 Element e = element.buildScope().lookup(name); |
| 758 if (e == null) return null; | 761 if (e == null) return null; |
| 759 if (e is! ClassElement) return null; | 762 if (e is! ClassElement) return null; |
| 760 ClassElement cls = e; | 763 ClassElement cls = e; |
| 761 cls.ensureResolved(compiler.resolution); | 764 cls.ensureResolved(compiler.resolution); |
| 762 return cls.thisType; | 765 return cls.thisType; |
| 763 } | 766 } |
| 764 | 767 |
| 765 return ofMethod(element, type, metadata, lookup, compiler, | 768 BehaviorComputer computer = new BehaviorComputerImpl(compiler); |
| 769 return computer.ofMethod(type, metadata, lookup, | |
| 766 isJsInterop: compiler.backend.isJsInterop(element)); | 770 isJsInterop: compiler.backend.isJsInterop(element)); |
| 767 } | 771 } |
| 768 | 772 |
| 769 static NativeBehavior ofMethod( | |
| 770 Spannable spannable, | |
| 771 ResolutionFunctionType type, | |
| 772 List<ConstantExpression> metadata, | |
| 773 TypeLookup lookupType, | |
| 774 Compiler compiler, | |
| 775 {bool isJsInterop}) { | |
| 776 var behavior = new NativeBehavior(); | |
| 777 var returnType = type.returnType; | |
| 778 // Note: For dart:html and other internal libraries we maintain, we can | |
| 779 // trust the return type and use it to limit what we enqueue. We have to | |
| 780 // be more conservative about JS interop types and assume they can return | |
| 781 // anything (unless the user provides the experimental flag to trust the | |
| 782 // type of js-interop APIs). We do restrict the allocation effects and say | |
| 783 // that interop calls create only interop types (which may be unsound if | |
| 784 // an interop call returns a DOM type and declares a dynamic return type, | |
| 785 // but otherwise we would include a lot of code by default). | |
| 786 // TODO(sigmund,sra): consider doing something better for numeric types. | |
| 787 behavior.typesReturned.add( | |
| 788 !isJsInterop || compiler.options.trustJSInteropTypeAnnotations | |
| 789 ? returnType | |
| 790 : const ResolutionDynamicType()); | |
| 791 if (!type.returnType.isVoid) { | |
| 792 // Declared types are nullable. | |
| 793 behavior.typesReturned.add(compiler.commonElements.nullType); | |
| 794 } | |
| 795 behavior._capture(type, compiler.resolution, | |
| 796 isInterop: isJsInterop, compiler: compiler); | |
| 797 | |
| 798 for (ResolutionDartType type in type.optionalParameterTypes) { | |
| 799 behavior._escape(type, compiler.resolution); | |
| 800 } | |
| 801 for (ResolutionDartType type in type.namedParameterTypes) { | |
| 802 behavior._escape(type, compiler.resolution); | |
| 803 } | |
| 804 | |
| 805 behavior._overrideWithAnnotations( | |
| 806 spannable, metadata, lookupType, compiler); | |
| 807 return behavior; | |
| 808 } | |
| 809 | |
| 810 static NativeBehavior ofFieldElementLoad( | 773 static NativeBehavior ofFieldElementLoad( |
| 811 MemberElement element, Compiler compiler) { | 774 MemberElement element, Compiler compiler) { |
| 812 Resolution resolution = compiler.resolution; | 775 Resolution resolution = compiler.resolution; |
| 813 ResolutionDartType type = element.computeType(resolution); | 776 ResolutionDartType type = element.computeType(resolution); |
| 814 List<ConstantExpression> metadata = <ConstantExpression>[]; | 777 List<ConstantExpression> metadata = <ConstantExpression>[]; |
| 815 for (MetadataAnnotation annotation in element.implementation.metadata) { | 778 for (MetadataAnnotation annotation in element.implementation.metadata) { |
| 816 annotation.ensureResolved(compiler.resolution); | 779 annotation.ensureResolved(compiler.resolution); |
| 817 metadata.add(annotation.constant); | 780 metadata.add(annotation.constant); |
| 818 } | 781 } |
| 819 | 782 |
| 820 ResolutionDartType lookup(String name) { | 783 ResolutionDartType lookup(String name) { |
| 821 Element e = element.buildScope().lookup(name); | 784 Element e = element.buildScope().lookup(name); |
| 822 if (e == null) return null; | 785 if (e == null) return null; |
| 823 if (e is! ClassElement) return null; | 786 if (e is! ClassElement) return null; |
| 824 ClassElement cls = e; | 787 ClassElement cls = e; |
| 825 cls.ensureResolved(compiler.resolution); | 788 cls.ensureResolved(compiler.resolution); |
| 826 return cls.thisType; | 789 return cls.thisType; |
| 827 } | 790 } |
| 828 | 791 |
| 829 return ofFieldLoad(element, type, metadata, lookup, compiler, | 792 BehaviorComputer computer = new BehaviorComputerImpl(compiler); |
| 793 return computer.ofFieldLoad(type, metadata, lookup, | |
| 830 isJsInterop: compiler.backend.isJsInterop(element)); | 794 isJsInterop: compiler.backend.isJsInterop(element)); |
| 831 } | 795 } |
| 832 | 796 |
| 833 static NativeBehavior ofFieldLoad( | 797 static NativeBehavior ofFieldElementStore( |
| 834 Spannable spannable, | 798 MemberElement field, Compiler compiler) { |
| 835 ResolutionDartType type, | 799 BehaviorComputer computer = new BehaviorComputerImpl(compiler); |
| 836 List<ConstantExpression> metadata, | 800 ResolutionDartType type = field.computeType(compiler.resolution); |
| 837 TypeLookup lookupType, | 801 return computer.ofFieldStore(type); |
| 838 Compiler compiler, | |
| 839 {bool isJsInterop}) { | |
| 840 Resolution resolution = compiler.resolution; | |
| 841 var behavior = new NativeBehavior(); | |
| 842 // TODO(sigmund,sra): consider doing something better for numeric types. | |
| 843 behavior.typesReturned.add( | |
| 844 !isJsInterop || compiler.options.trustJSInteropTypeAnnotations | |
| 845 ? type | |
| 846 : const ResolutionDynamicType()); | |
| 847 // Declared types are nullable. | |
| 848 behavior.typesReturned.add(resolution.commonElements.nullType); | |
| 849 behavior._capture(type, resolution, | |
| 850 isInterop: isJsInterop, compiler: compiler); | |
| 851 behavior._overrideWithAnnotations( | |
| 852 spannable, metadata, lookupType, compiler); | |
| 853 return behavior; | |
| 854 } | 802 } |
| 855 | 803 |
| 856 static NativeBehavior ofFieldElementStore( | 804 static dynamic /*DartType|SpecialType*/ _parseType(String typeString, |
| 857 MemberElement field, Resolution resolution) { | 805 Spannable spannable, DiagnosticReporter reporter, TypeLookup lookupType) { |
| 858 ResolutionDartType type = field.computeType(resolution); | 806 if (typeString == '=Object') return SpecialType.JsObject; |
| 859 return ofFieldStore(type, resolution); | 807 if (typeString == 'dynamic') { |
| 808 return const ResolutionDynamicType(); | |
| 809 } | |
| 810 var type = lookupType(typeString); | |
| 811 if (type != null) return type; | |
| 812 | |
| 813 int index = typeString.indexOf('<'); | |
| 814 if (index < 1) { | |
| 815 reporter.reportErrorMessage(spannable, MessageKind.GENERIC, | |
| 816 {'text': "Type '$typeString' not found."}); | |
| 817 return const ResolutionDynamicType(); | |
| 818 } | |
| 819 type = lookupType(typeString.substring(0, index)); | |
| 820 if (type != null) { | |
| 821 // TODO(sra): Parse type parameters. | |
| 822 return type; | |
| 823 } | |
| 824 reporter.reportErrorMessage(spannable, MessageKind.GENERIC, | |
| 825 {'text': "Type '$typeString' not found."}); | |
| 826 return const ResolutionDynamicType(); | |
| 860 } | 827 } |
| 828 } | |
| 861 | 829 |
| 862 static NativeBehavior ofFieldStore( | 830 abstract class BehaviorComputer { |
|
Siggi Cherem (dart-lang)
2017/02/08 17:00:28
nit: rename as BehaviorBuilder or BehaviorFactory
Johnni Winther
2017/02/10 09:11:45
Done.
| |
| 863 ResolutionDartType type, Resolution resolution) { | 831 CommonElements get commonElements; |
| 864 var behavior = new NativeBehavior(); | 832 BackendClasses get backendClasses; |
| 865 behavior._escape(type, resolution); | 833 BackendHelpers get helpers; |
| 866 // We don't override the default behaviour - the annotations apply to | 834 DiagnosticReporter get reporter; |
| 867 // loading the field. | 835 ConstantEnvironment get constants; |
| 868 return behavior; | 836 bool get trustJSInteropTypeAnnotations; |
| 869 } | 837 |
| 838 Resolution get resolution => null; | |
| 839 | |
| 840 NativeBehavior _behavior; | |
| 870 | 841 |
| 871 void _overrideWithAnnotations( | 842 void _overrideWithAnnotations( |
| 872 Spannable spannable, | 843 Iterable<ConstantExpression> metadata, TypeLookup lookupType) { |
| 873 Iterable<ConstantExpression> metadata, | |
| 874 TypeLookup lookupType, | |
| 875 Compiler compiler) { | |
| 876 if (metadata.isEmpty) return; | 844 if (metadata.isEmpty) return; |
| 877 | 845 |
| 878 NativeEnqueuer enqueuer = compiler.enqueuer.resolution.nativeEnqueuer; | 846 List creates = |
| 879 var creates = _collect(spannable, metadata, compiler, | 847 _collect(metadata, helpers.annotationCreatesClass, lookupType); |
| 880 enqueuer.annotationCreatesClass, lookupType); | 848 List returns = |
| 881 var returns = _collect(spannable, metadata, compiler, | 849 _collect(metadata, helpers.annotationReturnsClass, lookupType); |
| 882 enqueuer.annotationReturnsClass, lookupType); | |
| 883 | 850 |
| 884 if (creates != null) { | 851 if (creates != null) { |
| 885 typesInstantiated | 852 _behavior.typesInstantiated |
| 886 ..clear() | 853 ..clear() |
| 887 ..addAll(creates); | 854 ..addAll(creates); |
| 888 } | 855 } |
| 889 if (returns != null) { | 856 if (returns != null) { |
| 890 typesReturned | 857 _behavior.typesReturned |
| 891 ..clear() | 858 ..clear() |
| 892 ..addAll(returns); | 859 ..addAll(returns); |
| 893 } | 860 } |
| 894 } | 861 } |
| 895 | 862 |
| 896 /** | 863 /** |
| 897 * Returns a list of type constraints from the annotations of | 864 * Returns a list of type constraints from the annotations of |
| 898 * [annotationClass]. | 865 * [annotationClass]. |
| 899 * Returns `null` if no constraints. | 866 * Returns `null` if no constraints. |
| 900 */ | 867 */ |
| 901 static _collect(Spannable spannable, Iterable<ConstantExpression> metadata, | 868 List _collect(Iterable<ConstantExpression> metadata, Element annotationClass, |
| 902 Compiler compiler, Element annotationClass, TypeLookup lookupType) { | 869 TypeLookup lookupType) { |
| 903 DiagnosticReporter reporter = compiler.reporter; | |
| 904 var types = null; | 870 var types = null; |
| 905 for (ConstantExpression constant in metadata) { | 871 for (ConstantExpression constant in metadata) { |
| 906 ConstantValue value = compiler.constants.getConstantValue(constant); | 872 ConstantValue value = constants.getConstantValue(constant); |
| 907 if (!value.isConstructedObject) continue; | 873 if (!value.isConstructedObject) continue; |
| 908 ConstructedConstantValue constructedObject = value; | 874 ConstructedConstantValue constructedObject = value; |
| 909 if (constructedObject.type.element != annotationClass) continue; | 875 if (constructedObject.type.element != annotationClass) continue; |
| 910 | 876 |
| 911 Iterable<ConstantValue> fields = constructedObject.fields.values; | 877 Iterable<ConstantValue> fields = constructedObject.fields.values; |
| 912 // TODO(sra): Better validation of the constant. | 878 // TODO(sra): Better validation of the constant. |
| 913 if (fields.length != 1 || !fields.single.isString) { | 879 if (fields.length != 1 || !fields.single.isString) { |
| 914 reporter.internalError(spannable, | 880 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, |
| 915 'Annotations needs one string: ${constant.toStructuredText()}'); | 881 'Annotations needs one string: ${constant.toStructuredText()}'); |
| 916 } | 882 } |
| 917 StringConstantValue specStringConstant = fields.single; | 883 StringConstantValue specStringConstant = fields.single; |
| 918 String specString = specStringConstant.toDartString().slowToString(); | 884 String specString = specStringConstant.toDartString().slowToString(); |
| 919 for (final typeString in specString.split('|')) { | 885 for (final typeString in specString.split('|')) { |
| 920 var type = _parseType(typeString, spannable, reporter, lookupType); | 886 var type = NativeBehavior._parseType( |
| 887 typeString, CURRENT_ELEMENT_SPANNABLE, reporter, lookupType); | |
| 921 if (types == null) types = []; | 888 if (types == null) types = []; |
| 922 types.add(type); | 889 types.add(type); |
| 923 } | 890 } |
| 924 } | 891 } |
| 925 return types; | 892 return types; |
| 926 } | 893 } |
| 927 | 894 |
| 928 /// Models the behavior of having intances of [type] escape from Dart code | 895 /// Models the behavior of having intances of [type] escape from Dart code |
| 929 /// into native code. | 896 /// into native code. |
| 930 void _escape(ResolutionDartType type, Resolution resolution) { | 897 void _escape(DartType type) { |
| 931 type.computeUnaliased(resolution); | 898 if (type is ResolutionDartType) { |
| 899 type.computeUnaliased(resolution); | |
| 900 } | |
| 932 type = type.unaliased; | 901 type = type.unaliased; |
| 933 if (type is ResolutionFunctionType) { | 902 if (type is FunctionType) { |
| 934 ResolutionFunctionType functionType = type; | 903 FunctionType functionType = type; |
| 935 // A function might be called from native code, passing us novel | 904 // A function might be called from native code, passing us novel |
| 936 // parameters. | 905 // parameters. |
| 937 _escape(functionType.returnType, resolution); | 906 _escape(functionType.returnType); |
| 938 for (ResolutionDartType parameter in functionType.parameterTypes) { | 907 for (DartType parameter in functionType.parameterTypes) { |
| 939 _capture(parameter, resolution); | 908 _capture(parameter); |
| 940 } | 909 } |
| 941 } | 910 } |
| 942 } | 911 } |
| 943 | 912 |
| 944 /// Models the behavior of Dart code receiving instances and methods of [type] | 913 /// Models the behavior of Dart code receiving instances and methods of [type] |
| 945 /// from native code. We usually start the analysis by capturing a native | 914 /// from native code. We usually start the analysis by capturing a native |
| 946 /// method that has been used. | 915 /// method that has been used. |
| 947 /// | 916 /// |
| 948 /// We assume that JS-interop APIs cannot instantiate Dart types or | 917 /// We assume that JS-interop APIs cannot instantiate Dart types or |
| 949 /// non-JSInterop native types. | 918 /// non-JSInterop native types. |
| 950 void _capture(ResolutionDartType type, Resolution resolution, | 919 void _capture(DartType type, {bool isInterop: false}) { |
| 951 {bool isInterop: false, Compiler compiler}) { | 920 if (type is ResolutionDartType) { |
| 952 type.computeUnaliased(resolution); | 921 type.computeUnaliased(resolution); |
| 922 } | |
| 953 type = type.unaliased; | 923 type = type.unaliased; |
| 954 if (type is ResolutionFunctionType) { | 924 if (type is FunctionType) { |
| 955 ResolutionFunctionType functionType = type; | 925 FunctionType functionType = type; |
| 956 _capture(functionType.returnType, resolution, | 926 _capture(functionType.returnType, isInterop: isInterop); |
| 957 isInterop: isInterop, compiler: compiler); | 927 for (DartType parameter in functionType.parameterTypes) { |
| 958 for (ResolutionDartType parameter in functionType.parameterTypes) { | 928 _escape(parameter); |
| 959 _escape(parameter, resolution); | |
| 960 } | 929 } |
| 961 } else { | 930 } else { |
| 962 JavaScriptBackend backend = compiler?.backend; | |
| 963 if (!isInterop) { | 931 if (!isInterop) { |
| 964 typesInstantiated.add(type); | 932 _behavior.typesInstantiated.add(type); |
| 965 } else { | 933 } else { |
| 966 if (type.element != null && backend.isNative(type.element)) { | 934 if (type is InterfaceType && |
| 935 backendClasses.isNativeClass(type.element)) { | |
| 967 // Any declared native or interop type (isNative implies isJsInterop) | 936 // Any declared native or interop type (isNative implies isJsInterop) |
| 968 // is assumed to be allocated. | 937 // is assumed to be allocated. |
| 969 typesInstantiated.add(type); | 938 _behavior.typesInstantiated.add(type); |
| 970 } | 939 } |
| 971 | 940 |
| 972 if (!compiler.options.trustJSInteropTypeAnnotations || | 941 if (!trustJSInteropTypeAnnotations || |
| 973 type.isDynamic || | 942 type.isDynamic || |
| 974 type.isObject) { | 943 type == commonElements.objectType) { |
| 975 // By saying that only JS-interop types can be created, we prevent | 944 // By saying that only JS-interop types can be created, we prevent |
| 976 // pulling in every other native type (e.g. all of dart:html) when a | 945 // pulling in every other native type (e.g. all of dart:html) when a |
| 977 // JS interop API returns dynamic or when we don't trust the type | 946 // JS interop API returns dynamic or when we don't trust the type |
| 978 // annotations. This means that to some degree we still use the return | 947 // annotations. This means that to some degree we still use the return |
| 979 // type to decide whether to include native types, even if we don't | 948 // type to decide whether to include native types, even if we don't |
| 980 // trust the type annotation. | 949 // trust the type annotation. |
| 981 ClassElement cls = backend.helpers.jsJavaScriptObjectClass; | 950 ClassElement cls = helpers.jsJavaScriptObjectClass; |
| 982 cls.ensureResolved(resolution); | 951 cls.ensureResolved(resolution); |
| 983 typesInstantiated.add(cls.thisType); | 952 _behavior.typesInstantiated.add(cls.thisType); |
| 984 } else { | 953 } else { |
| 985 // Otherwise, when the declared type is a Dart type, we do not | 954 // Otherwise, when the declared type is a Dart type, we do not |
| 986 // register an allocation because we assume it cannot be instantiated | 955 // register an allocation because we assume it cannot be instantiated |
| 987 // from within the JS-interop code. It must have escaped from another | 956 // from within the JS-interop code. It must have escaped from another |
| 988 // API. | 957 // API. |
| 989 } | 958 } |
| 990 } | 959 } |
| 991 } | 960 } |
| 992 } | 961 } |
| 993 | 962 |
| 994 static dynamic /*DartType|SpecialType*/ _parseType(String typeString, | 963 NativeBehavior ofFieldLoad(DartType type, |
|
Siggi Cherem (dart-lang)
2017/02/08 17:00:28
Let's rename these now that they are no longer on
Johnni Winther
2017/02/10 09:11:45
Done.
| |
| 995 Spannable spannable, DiagnosticReporter reporter, TypeLookup lookupType) { | 964 Iterable<ConstantExpression> metadata, TypeLookup lookupType, |
| 996 if (typeString == '=Object') return SpecialType.JsObject; | 965 {bool isJsInterop}) { |
| 997 if (typeString == 'dynamic') { | 966 _behavior = new NativeBehavior(); |
| 998 return const ResolutionDynamicType(); | 967 // TODO(sigmund,sra): consider doing something better for numeric types. |
| 968 _behavior.typesReturned.add(!isJsInterop || trustJSInteropTypeAnnotations | |
| 969 ? type | |
| 970 : commonElements.dynamicType); | |
| 971 // Declared types are nullable. | |
| 972 _behavior.typesReturned.add(commonElements.nullType); | |
| 973 _capture(type, isInterop: isJsInterop); | |
| 974 _overrideWithAnnotations(metadata, lookupType); | |
| 975 return _behavior; | |
| 976 } | |
| 977 | |
| 978 NativeBehavior ofFieldStore(DartType type) { | |
| 979 _behavior = new NativeBehavior(); | |
| 980 _escape(type); | |
| 981 // We don't override the default behaviour - the annotations apply to | |
| 982 // loading the field. | |
| 983 return _behavior; | |
| 984 } | |
| 985 | |
| 986 NativeBehavior ofMethod(FunctionType type, List<ConstantExpression> metadata, | |
| 987 TypeLookup lookupType, | |
| 988 {bool isJsInterop}) { | |
| 989 _behavior = new NativeBehavior(); | |
| 990 DartType returnType = type.returnType; | |
| 991 // Note: For dart:html and other internal libraries we maintain, we can | |
| 992 // trust the return type and use it to limit what we enqueue. We have to | |
| 993 // be more conservative about JS interop types and assume they can return | |
| 994 // anything (unless the user provides the experimental flag to trust the | |
| 995 // type of js-interop APIs). We do restrict the allocation effects and say | |
| 996 // that interop calls create only interop types (which may be unsound if | |
| 997 // an interop call returns a DOM type and declares a dynamic return type, | |
| 998 // but otherwise we would include a lot of code by default). | |
| 999 // TODO(sigmund,sra): consider doing something better for numeric types. | |
| 1000 _behavior.typesReturned.add(!isJsInterop || trustJSInteropTypeAnnotations | |
| 1001 ? returnType | |
| 1002 : commonElements.dynamicType); | |
| 1003 if (!type.returnType.isVoid) { | |
| 1004 // Declared types are nullable. | |
| 1005 _behavior.typesReturned.add(commonElements.nullType); | |
| 999 } | 1006 } |
| 1000 var type = lookupType(typeString); | 1007 _capture(type, isInterop: isJsInterop); |
| 1001 if (type != null) return type; | |
| 1002 | 1008 |
| 1003 int index = typeString.indexOf('<'); | 1009 for (DartType type in type.optionalParameterTypes) { |
| 1004 if (index < 1) { | 1010 _escape(type); |
| 1005 reporter.reportErrorMessage(spannable, MessageKind.GENERIC, | |
| 1006 {'text': "Type '$typeString' not found."}); | |
| 1007 return const ResolutionDynamicType(); | |
| 1008 } | 1011 } |
| 1009 type = lookupType(typeString.substring(0, index)); | 1012 for (DartType type in type.namedParameterTypes) { |
| 1010 if (type != null) { | 1013 _escape(type); |
| 1011 // TODO(sra): Parse type parameters. | |
| 1012 return type; | |
| 1013 } | 1014 } |
| 1014 reporter.reportErrorMessage(spannable, MessageKind.GENERIC, | 1015 |
| 1015 {'text': "Type '$typeString' not found."}); | 1016 _overrideWithAnnotations(metadata, lookupType); |
| 1016 return const ResolutionDynamicType(); | 1017 return _behavior; |
| 1017 } | 1018 } |
| 1018 } | 1019 } |
| 1020 | |
| 1021 class BehaviorComputerImpl extends BehaviorComputer { | |
|
Siggi Cherem (dart-lang)
2017/02/08 17:00:28
nit: rename to ResolverBehaviorBuilder? (so the ne
Johnni Winther
2017/02/10 09:11:45
Done.
| |
| 1022 final Compiler compiler; | |
| 1023 | |
| 1024 BehaviorComputerImpl(this.compiler); | |
| 1025 | |
| 1026 @override | |
| 1027 CommonElements get commonElements => compiler.commonElements; | |
| 1028 | |
| 1029 @override | |
| 1030 bool get trustJSInteropTypeAnnotations => | |
| 1031 compiler.options.trustJSInteropTypeAnnotations; | |
| 1032 | |
| 1033 @override | |
| 1034 ConstantEnvironment get constants => compiler.constants; | |
| 1035 | |
| 1036 @override | |
| 1037 DiagnosticReporter get reporter => compiler.reporter; | |
| 1038 | |
| 1039 @override | |
| 1040 BackendHelpers get helpers { | |
| 1041 JavaScriptBackend backend = compiler.backend; | |
| 1042 return backend.helpers; | |
| 1043 } | |
| 1044 | |
| 1045 @override | |
| 1046 BackendClasses get backendClasses => compiler.backend.backendClasses; | |
| 1047 | |
| 1048 @override | |
| 1049 Resolution get resolution => compiler.resolution; | |
| 1050 } | |
| OLD | NEW |