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 library analyzer.src.dart.element.member; | 5 library analyzer.src.dart.element.member; |
6 | 6 |
7 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
8 import 'package:analyzer/dart/constant/value.dart'; | 8 import 'package:analyzer/dart/constant/value.dart'; |
9 import 'package:analyzer/dart/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
10 import 'package:analyzer/dart/element/type.dart'; | 10 import 'package:analyzer/dart/element/type.dart'; |
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
901 * class C<T> { | 901 * class C<T> { |
902 * S m<S extends T>(S s); | 902 * S m<S extends T>(S s); |
903 * } | 903 * } |
904 * | 904 * |
905 * If we have `C<num>.m` and we ask for the type parameter "S", we should get | 905 * If we have `C<num>.m` and we ask for the type parameter "S", we should get |
906 * `<S extends num>` instead of `<S extends T>`. This is how the parameter | 906 * `<S extends num>` instead of `<S extends T>`. This is how the parameter |
907 * and return types work, see: [FunctionType.parameters], | 907 * and return types work, see: [FunctionType.parameters], |
908 * [FunctionType.returnType], and [ParameterMember]. | 908 * [FunctionType.returnType], and [ParameterMember]. |
909 */ | 909 */ |
910 class TypeParameterMember extends Member implements TypeParameterElement { | 910 class TypeParameterMember extends Member implements TypeParameterElement { |
911 @override | 911 DartType _bound; |
912 final DartType bound; | |
913 | |
914 DartType _type; | 912 DartType _type; |
915 | 913 |
916 TypeParameterMember( | 914 TypeParameterMember( |
917 TypeParameterElement baseElement, DartType definingType, this.bound) | 915 TypeParameterElement baseElement, DartType definingType, this._bound) |
918 : super(baseElement, definingType) { | 916 : super(baseElement, definingType) { |
919 _type = new TypeParameterTypeImpl(this); | 917 _type = new TypeParameterTypeImpl(this); |
920 } | 918 } |
921 | 919 |
922 @override | 920 @override |
923 TypeParameterElement get baseElement => | 921 TypeParameterElement get baseElement => |
924 super.baseElement as TypeParameterElement; | 922 super.baseElement as TypeParameterElement; |
925 | 923 |
926 @override | 924 @override |
| 925 DartType get bound => _bound; |
| 926 |
| 927 @override |
927 Element get enclosingElement => baseElement.enclosingElement; | 928 Element get enclosingElement => baseElement.enclosingElement; |
928 | 929 |
929 @override | 930 @override |
930 int get hashCode => baseElement.hashCode; | 931 int get hashCode => baseElement.hashCode; |
931 | 932 |
932 @override | 933 @override |
933 TypeParameterType get type => _type; | 934 TypeParameterType get type => _type; |
934 | 935 |
935 @override | 936 @override |
936 /*=T*/ accept/*<T>*/(ElementVisitor<dynamic/*=T*/ > visitor) => | 937 /*=T*/ accept/*<T>*/(ElementVisitor<dynamic/*=T*/ > visitor) => |
937 visitor.visitTypeParameterElement(this); | 938 visitor.visitTypeParameterElement(this); |
938 | 939 |
939 /** | 940 /** |
940 * If the given [parameter]'s type is different when any type parameters from | 941 * If the given [parameter]'s type is different when any type parameters from |
941 * the defining type's declaration are replaced with the actual type | 942 * the defining type's declaration are replaced with the actual type |
942 * arguments from the [definingType], create a parameter member representing | 943 * arguments from the [definingType], create a parameter member representing |
943 * the given parameter. Return the member that was created, or the base | 944 * the given parameter. Return the member that was created, or the base |
944 * parameter if no member was created. | 945 * parameter if no member was created. |
945 */ | 946 */ |
946 static TypeParameterElement from( | 947 static List<TypeParameterElement> from( |
947 TypeParameterElement parameter, ParameterizedType definingType) { | 948 List<TypeParameterElement> formals, FunctionType definingType) { |
948 if (parameter?.bound == null || definingType.typeArguments.isEmpty) { | 949 List<DartType> argumentTypes = definingType.typeArguments; |
949 return parameter; | 950 if (argumentTypes.isEmpty) { |
| 951 return formals; |
950 } | 952 } |
951 | |
952 DartType bound = parameter.bound; | |
953 List<DartType> argumentTypes = definingType.typeArguments; | |
954 List<DartType> parameterTypes = | 953 List<DartType> parameterTypes = |
955 TypeParameterTypeImpl.getTypes(definingType.typeParameters); | 954 TypeParameterTypeImpl.getTypes(definingType.typeParameters); |
956 DartType substitutedBound = | 955 |
957 bound.substitute2(argumentTypes, parameterTypes); | 956 // Create type formals with specialized bounds. |
958 return new TypeParameterMember(parameter, definingType, substitutedBound); | 957 // For example `<U extends T>` where T comes from an outer scope. |
| 958 var results = formals.toList(growable: false); |
| 959 for (int i = 0; i < results.length; i++) { |
| 960 var formal = results[i]; |
| 961 DartType bound = formal?.bound; |
| 962 if (bound != null) { |
| 963 // substitute type arguments from the function. |
| 964 bound = bound.substitute2(argumentTypes, parameterTypes); |
| 965 results[i] = new TypeParameterMember(formal, definingType, bound); |
| 966 } |
| 967 } |
| 968 List<TypeParameterType> formalTypes = |
| 969 TypeParameterTypeImpl.getTypes(formals); |
| 970 for (var formal in results) { |
| 971 if (formal is TypeParameterMember) { |
| 972 // Recursive bounds are allowed too, so make sure these are updated |
| 973 // to refer to any new TypeParameterMember we just made, rather than |
| 974 // the original type parameter |
| 975 // TODO(jmesserly): this is required so substituting for the |
| 976 // type formal will work. Investigate if there's a better solution. |
| 977 formal._bound = formal.bound |
| 978 .substitute2(TypeParameterTypeImpl.getTypes(results), formalTypes); |
| 979 } |
| 980 } |
| 981 return results; |
959 } | 982 } |
960 } | 983 } |
961 | 984 |
962 /** | 985 /** |
963 * A variable element defined in a parameterized type where the values of the | 986 * A variable element defined in a parameterized type where the values of the |
964 * type parameters are known. | 987 * type parameters are known. |
965 */ | 988 */ |
966 abstract class VariableMember extends Member implements VariableElement { | 989 abstract class VariableMember extends Member implements VariableElement { |
967 @override | 990 @override |
968 final DartType type; | 991 final DartType type; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1026 DartObject computeConstantValue() => baseElement.computeConstantValue(); | 1049 DartObject computeConstantValue() => baseElement.computeConstantValue(); |
1027 | 1050 |
1028 @override | 1051 @override |
1029 void visitChildren(ElementVisitor visitor) { | 1052 void visitChildren(ElementVisitor visitor) { |
1030 // TODO(brianwilkerson) We need to finish implementing the accessors used | 1053 // TODO(brianwilkerson) We need to finish implementing the accessors used |
1031 // below so that we can safely invoke them. | 1054 // below so that we can safely invoke them. |
1032 super.visitChildren(visitor); | 1055 super.visitChildren(visitor); |
1033 baseElement.initializer?.accept(visitor); | 1056 baseElement.initializer?.accept(visitor); |
1034 } | 1057 } |
1035 } | 1058 } |
OLD | NEW |