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

Side by Side Diff: pkg/analyzer/lib/src/task/strong_mode.dart

Issue 2336503003: fix #25578, implement @covariant parameter overrides (Closed)
Patch Set: fix comments, format Created 4 years, 3 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) 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 library analyzer.src.task.strong_mode; 5 library analyzer.src.task.strong_mode;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'package:analyzer/dart/ast/ast.dart'; 9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/ast/visitor.dart'; 10 import 'package:analyzer/dart/ast/visitor.dart';
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 * At the moment, this method will only return a type other than 'dynamic' if 114 * At the moment, this method will only return a type other than 'dynamic' if
115 * the types of all of the parameters are the same. In the future we might 115 * the types of all of the parameters are the same. In the future we might
116 * want to be smarter about it, such as by returning the least upper bound of 116 * want to be smarter about it, such as by returning the least upper bound of
117 * the parameter types. 117 * the parameter types.
118 */ 118 */
119 DartType _computeParameterType(ParameterElement parameter, int index, 119 DartType _computeParameterType(ParameterElement parameter, int index,
120 List<FunctionType> overriddenTypes) { 120 List<FunctionType> overriddenTypes) {
121 DartType parameterType = null; 121 DartType parameterType = null;
122 int length = overriddenTypes.length; 122 int length = overriddenTypes.length;
123 for (int i = 0; i < length; i++) { 123 for (int i = 0; i < length; i++) {
124 DartType type = _getTypeOfCorrespondingParameter( 124 ParameterElement matchingParam = _getCorrespondingParameter(
125 parameter, index, overriddenTypes[i].parameters); 125 parameter, index, overriddenTypes[i].parameters);
126 var type = matchingParam?.type ?? typeProvider.dynamicType;
126 if (parameterType == null) { 127 if (parameterType == null) {
127 parameterType = type; 128 parameterType = type;
128 } else if (parameterType != type) { 129 } else if (parameterType != type) {
129 return typeProvider.dynamicType; 130 return typeProvider.dynamicType;
130 } 131 }
131 } 132 }
132 return parameterType ?? typeProvider.dynamicType; 133 return parameterType ?? typeProvider.dynamicType;
133 } 134 }
134 135
135 /** 136 /**
(...skipping 13 matching lines...) Expand all
149 if (returnType == null) { 150 if (returnType == null) {
150 returnType = type; 151 returnType = type;
151 } else if (returnType != type) { 152 } else if (returnType != type) {
152 return typeProvider.dynamicType; 153 return typeProvider.dynamicType;
153 } 154 }
154 } 155 }
155 return returnType ?? typeProvider.dynamicType; 156 return returnType ?? typeProvider.dynamicType;
156 } 157 }
157 158
158 /** 159 /**
159 * Given a method, return the type of the parameter in the method that 160 * Given a method, return the parameter in the method that corresponds to the
160 * corresponds to the given [parameter]. If the parameter is positional, then 161 * given [parameter]. If the parameter is positional, then
161 * it appears at the given [index] in its enclosing element's list of 162 * it appears at the given [index] in its enclosing element's list of
162 * parameters. 163 * parameters.
163 */ 164 */
164 DartType _getTypeOfCorrespondingParameter(ParameterElement parameter, 165 ParameterElement _getCorrespondingParameter(ParameterElement parameter,
165 int index, List<ParameterElement> methodParameters) { 166 int index, List<ParameterElement> methodParameters) {
166 // 167 //
167 // Find the corresponding parameter. 168 // Find the corresponding parameter.
168 // 169 //
169 ParameterElement matchingParameter = null;
170 if (parameter.parameterKind == ParameterKind.NAMED) { 170 if (parameter.parameterKind == ParameterKind.NAMED) {
171 // 171 //
172 // If we're looking for a named parameter, only a named parameter with 172 // If we're looking for a named parameter, only a named parameter with
173 // the same name will be matched. 173 // the same name will be matched.
174 // 174 //
175 matchingParameter = methodParameters.lastWhere( 175 return methodParameters.lastWhere(
176 (ParameterElement methodParameter) => 176 (ParameterElement methodParameter) =>
177 methodParameter.parameterKind == ParameterKind.NAMED && 177 methodParameter.parameterKind == ParameterKind.NAMED &&
178 methodParameter.name == parameter.name, 178 methodParameter.name == parameter.name,
179 orElse: () => null); 179 orElse: () => null);
180 } else { 180 }
181 // 181 //
182 // If we're looking for a positional parameter we ignore the difference 182 // If we're looking for a positional parameter we ignore the difference
183 // between required and optional parameters. 183 // between required and optional parameters.
184 // 184 //
185 if (index < methodParameters.length) { 185 if (index < methodParameters.length) {
186 matchingParameter = methodParameters[index]; 186 var matchingParameter = methodParameters[index];
187 if (matchingParameter.parameterKind == ParameterKind.NAMED) { 187 if (matchingParameter.parameterKind != ParameterKind.NAMED) {
188 matchingParameter = null; 188 return matchingParameter;
189 }
190 } 189 }
191 } 190 }
192 // 191 return null;
193 // Then return the type of the parameter.
194 //
195 return matchingParameter == null
196 ? typeProvider.dynamicType
197 : matchingParameter.type;
198 } 192 }
199 193
200 /** 194 /**
201 * Infer type information for all of the instance members in the given 195 * Infer type information for all of the instance members in the given
202 * [classElement]. 196 * [classElement].
203 */ 197 */
204 void _inferClass(ClassElement classElement) { 198 void _inferClass(ClassElement classElement) {
205 if (classElement is ClassElementImpl) { 199 if (classElement is ClassElementImpl) {
206 if (classElement.hasBeenInferred) { 200 if (classElement.hasBeenInferred) {
207 return; 201 return;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 _updateSyntheticVariableType(element); 298 _updateSyntheticVariableType(element);
305 } 299 }
306 } 300 }
307 // 301 //
308 // Infer the parameter types. 302 // Infer the parameter types.
309 // 303 //
310 List<ParameterElement> parameters = element.parameters; 304 List<ParameterElement> parameters = element.parameters;
311 int length = parameters.length; 305 int length = parameters.length;
312 for (int i = 0; i < length; ++i) { 306 for (int i = 0; i < length; ++i) {
313 ParameterElement parameter = parameters[i]; 307 ParameterElement parameter = parameters[i];
314 if (parameter is ParameterElementImpl && parameter.hasImplicitType) { 308 if (parameter is ParameterElementImpl) {
315 parameter.type = _computeParameterType(parameter, i, overriddenTypes); 309 // If a parameter is covariant, any parameters that override it are too.
316 if (element is PropertyAccessorElement) { 310 parameter.inheritsCovariant = overriddenTypes.any((f) {
317 _updateSyntheticVariableType(element); 311 var param = _getCorrespondingParameter(parameter, i, f.parameters);
312 return param != null && param.isCovariant;
313 });
314
315 if (parameter.hasImplicitType) {
316 parameter.type = _computeParameterType(parameter, i, overriddenTypes);
317 if (element is PropertyAccessorElement) {
318 _updateSyntheticVariableType(element);
319 }
318 } 320 }
319 } 321 }
320 } 322 }
321 } 323 }
322 324
323 /** 325 /**
324 * If the given [fieldElement] represents a non-synthetic instance field for 326 * If the given [fieldElement] represents a non-synthetic instance field for
325 * which no type was provided, infer the type of the field. 327 * which no type was provided, infer the type of the field.
326 */ 328 */
327 void _inferField(FieldElement fieldElement) { 329 void _inferField(FieldElement fieldElement) {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 results.add(element); 480 results.add(element);
479 } 481 }
480 } 482 }
481 } 483 }
482 } 484 }
483 485
484 /** 486 /**
485 * A class of exception that is not used anywhere else. 487 * A class of exception that is not used anywhere else.
486 */ 488 */
487 class _CycleException implements Exception {} 489 class _CycleException implements Exception {}
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/task/strong/checker.dart ('k') | pkg/analyzer/test/src/context/mock_sdk.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698