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

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: split loops and merge 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
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/dart/element/type.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/dart/element/type.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698