Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be | 5 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be |
| 6 // refactored to fit into analyzer. | 6 // refactored to fit into analyzer. |
| 7 library analyzer.src.task.strong.checker; | 7 library analyzer.src.task.strong.checker; |
| 8 | 8 |
| 9 import 'dart:collection'; | 9 import 'dart:collection'; |
| 10 import 'package:analyzer/analyzer.dart'; | 10 import 'package:analyzer/analyzer.dart'; |
| (...skipping 892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 903 } | 903 } |
| 904 | 904 |
| 905 // Get the lower bound of the declared return type (e.g. `F<Null>`) and | 905 // Get the lower bound of the declared return type (e.g. `F<Null>`) and |
| 906 // see if it can be assigned to the expected type (e.g. `F<Object>`). | 906 // see if it can be assigned to the expected type (e.g. `F<Object>`). |
| 907 // | 907 // |
| 908 // That way we can tell if any lower `T` will work or not. | 908 // That way we can tell if any lower `T` will work or not. |
| 909 var classType = targetType.element.type; | 909 var classType = targetType.element.type; |
| 910 var classLowerBound = classType.instantiate(new List.filled( | 910 var classLowerBound = classType.instantiate(new List.filled( |
| 911 classType.typeParameters.length, typeProvider.nullType)); | 911 classType.typeParameters.length, typeProvider.nullType)); |
| 912 var memberLowerBound = _lookUpMember(classLowerBound, member).type; | 912 var memberLowerBound = _lookUpMember(classLowerBound, member).type; |
| 913 var expectedType = member.returnType; | 913 var expectedType = member.returnType; |
|
Jennifer Messerly
2017/08/11 22:06:07
If we wanted to fix other covariant tearoffs by ca
| |
| 914 | 914 |
| 915 if (!rules.isSubtypeOf(memberLowerBound.returnType, expectedType)) { | 915 if (!rules.isSubtypeOf(memberLowerBound.returnType, expectedType)) { |
| 916 if (node is MethodInvocation && member is! MethodElement) { | 916 var isMethod = member is MethodElement; |
| 917 // If `o.m` is not a method, we need to cast `o.m` before the call: | 917 var isCall = node is MethodInvocation; |
| 918 // `(o.m as expectedType)(args)`. | 918 |
| 919 if (isMethod && !isCall) { | |
| 920 // If `o.m` is a method tearoff, cast to the method type. | |
| 921 setImplicitCast(node, member.type); | |
| 922 } else if (!isMethod && isCall) { | |
| 923 // If `o.g()` is calling a field/getter `g`, we need to cast `o.g` | |
| 924 // before the call: `(o.g as expectedType)(args)`. | |
| 919 // This cannot be represented by an `as` node without changing the | 925 // This cannot be represented by an `as` node without changing the |
| 920 // Dart AST structure, so we record it as a special cast. | 926 // Dart AST structure, so we record it as a special cast. |
| 921 setImplicitOperationCast(node, expectedType); | 927 setImplicitOperationCast(node, expectedType); |
| 922 } else { | 928 } else { |
| 929 // For method calls `o.m()` or getters `o.g`, simply cast the result. | |
| 923 setImplicitCast(node, expectedType); | 930 setImplicitCast(node, expectedType); |
| 924 } | 931 } |
| 925 _hasImplicitCasts = true; | 932 _hasImplicitCasts = true; |
| 926 } | 933 } |
| 927 } | 934 } |
| 928 } | 935 } |
| 929 | 936 |
| 930 /// Returns true if we can safely skip the covariance checks because [target] | 937 /// Returns true if we can safely skip the covariance checks because [target] |
| 931 /// has known type arguments, such as `this` `super` or a non-factory `new`. | 938 /// has known type arguments, such as `this` `super` or a non-factory `new`. |
| 932 /// | 939 /// |
| (...skipping 1041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1974 } | 1981 } |
| 1975 | 1982 |
| 1976 /// If node is a [ClassDeclaration] returns its members, otherwise if node is | 1983 /// If node is a [ClassDeclaration] returns its members, otherwise if node is |
| 1977 /// a [ClassTypeAlias] this returns an empty list. | 1984 /// a [ClassTypeAlias] this returns an empty list. |
| 1978 WithClause _withClause(Declaration node) { | 1985 WithClause _withClause(Declaration node) { |
| 1979 return node is ClassDeclaration | 1986 return node is ClassDeclaration |
| 1980 ? node.withClause | 1987 ? node.withClause |
| 1981 : (node as ClassTypeAlias).withClause; | 1988 : (node as ClassTypeAlias).withClause; |
| 1982 } | 1989 } |
| 1983 } | 1990 } |
| OLD | NEW |