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

Side by Side Diff: pkg/analyzer/lib/src/dart/element/member.dart

Issue 2653873002: fix #28141, fix super generic method bounds check (Closed)
Patch Set: Created 3 years, 11 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 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
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 List<TypeParameterType> formalTypes =
957 bound.substitute2(argumentTypes, parameterTypes); 956 TypeParameterTypeImpl.getTypes(formals);
958 return new TypeParameterMember(parameter, definingType, substitutedBound); 957
958 // Create type formals with specialized bounds.
959 // For example `<U extends T>` where T comes from an outer scope.
960 var result = formals.toList(growable: false);
961 for (int i = 0; i < result.length; i++) {
962 var formal = formals[i];
963 DartType bound = formal?.bound;
964 if (bound != null) {
965 // substitute type arguments from the function.
966 bound = bound.substitute2(argumentTypes, parameterTypes);
967 var newTypeFormal =
968 new TypeParameterMember(formal, definingType, bound);
969 result[i] = newTypeFormal;
970 // recursive bounds are allowed too, so make sure these are updated
971 // to refer to any new TypeParameterMember we just made, rather than
972 // the original type parameter
973 // TODO(jmesserly): this is required so substituting for the
974 // typeFormal will work. Investigate if there's a better solution,
975 // e.g. TypeParameterMember.
976 newTypeFormal._bound = bound.substitute2(
Leaf 2017/01/24 19:10:05 Consider doing this in a separate loop afterwards
Jennifer Messerly 2017/01/24 22:44:00 excellent idea
977 TypeParameterTypeImpl.getTypes(result), formalTypes);
978 }
979 }
980 return result;
959 } 981 }
960 } 982 }
961 983
962 /** 984 /**
963 * A variable element defined in a parameterized type where the values of the 985 * A variable element defined in a parameterized type where the values of the
964 * type parameters are known. 986 * type parameters are known.
965 */ 987 */
966 abstract class VariableMember extends Member implements VariableElement { 988 abstract class VariableMember extends Member implements VariableElement {
967 @override 989 @override
968 final DartType type; 990 final DartType type;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 DartObject computeConstantValue() => baseElement.computeConstantValue(); 1048 DartObject computeConstantValue() => baseElement.computeConstantValue();
1027 1049
1028 @override 1050 @override
1029 void visitChildren(ElementVisitor visitor) { 1051 void visitChildren(ElementVisitor visitor) {
1030 // TODO(brianwilkerson) We need to finish implementing the accessors used 1052 // TODO(brianwilkerson) We need to finish implementing the accessors used
1031 // below so that we can safely invoke them. 1053 // below so that we can safely invoke them.
1032 super.visitChildren(visitor); 1054 super.visitChildren(visitor);
1033 baseElement.initializer?.accept(visitor); 1055 baseElement.initializer?.accept(visitor);
1034 } 1056 }
1035 } 1057 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/dart/element/type.dart » ('j') | pkg/analyzer/lib/src/generated/error_verifier.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698