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

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

Issue 1524893002: Fix imports within the analyzer package (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years 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 | « pkg/analyzer/lib/src/task/strong/info.dart ('k') | pkg/analyzer/lib/task/dart.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) 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/element/element.dart';
10 import 'package:analyzer/dart/element/type.dart';
11 import 'package:analyzer/src/dart/element/element.dart';
12 import 'package:analyzer/src/dart/element/type.dart';
9 import 'package:analyzer/src/generated/ast.dart'; 13 import 'package:analyzer/src/generated/ast.dart';
10 import 'package:analyzer/src/generated/element.dart';
11 import 'package:analyzer/src/generated/resolver.dart' 14 import 'package:analyzer/src/generated/resolver.dart'
12 show TypeProvider, InheritanceManager; 15 show TypeProvider, InheritanceManager;
13 import 'package:analyzer/src/generated/type_system.dart'; 16 import 'package:analyzer/src/generated/type_system.dart';
14 import 'package:analyzer/src/generated/utilities_dart.dart'; 17 import 'package:analyzer/src/generated/utilities_dart.dart';
15 18
16 /** 19 /**
17 * Set the type of the sole parameter of the given [element] to the given [type] . 20 * Set the type of the sole parameter of the given [element] to the given [type] .
18 */ 21 */
19 void setParameterType(PropertyAccessorElement element, DartType type) { 22 void setParameterType(PropertyAccessorElement element, DartType type) {
20 if (element is PropertyAccessorElementImpl) { 23 if (element is PropertyAccessorElementImpl) {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 try { 133 try {
131 _inferClass(classElement); 134 _inferClass(classElement);
132 } on _CycleException { 135 } on _CycleException {
133 // This is a short circuit return to prevent types that inherit from 136 // This is a short circuit return to prevent types that inherit from
134 // types containing a circular reference from being inferred. 137 // types containing a circular reference from being inferred.
135 } 138 }
136 }); 139 });
137 } 140 }
138 141
139 /** 142 /**
143 * Return `true` if the list of [elements] contains only methods.
144 */
145 bool _allSameElementKind(
146 ExecutableElement element, List<ExecutableElement> elements) {
147 return elements.every((e) => e.kind == element.kind);
148 }
149
150 /**
140 * Compute the best type for the [parameter] at the given [index] that must be 151 * Compute the best type for the [parameter] at the given [index] that must be
141 * compatible with the types of the corresponding parameters of the given 152 * compatible with the types of the corresponding parameters of the given
142 * [overriddenMethods]. 153 * [overriddenMethods].
143 * 154 *
144 * At the moment, this method will only return a type other than 'dynamic' if 155 * At the moment, this method will only return a type other than 'dynamic' if
145 * the types of all of the parameters are the same. In the future we might 156 * the types of all of the parameters are the same. In the future we might
146 * want to be smarter about it, such as by returning the least upper bound of 157 * want to be smarter about it, such as by returning the least upper bound of
147 * the parameter types. 158 * the parameter types.
148 */ 159 */
149 DartType _computeParameterType(ParameterElement parameter, int index, 160 DartType _computeParameterType(ParameterElement parameter, int index,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 List<ParameterElement> methodParameters = method.parameters; 217 List<ParameterElement> methodParameters = method.parameters;
207 ParameterElement matchingParameter = null; 218 ParameterElement matchingParameter = null;
208 if (parameter.parameterKind == ParameterKind.NAMED) { 219 if (parameter.parameterKind == ParameterKind.NAMED) {
209 // 220 //
210 // If we're looking for a named parameter, only a named parameter with 221 // If we're looking for a named parameter, only a named parameter with
211 // the same name will be matched. 222 // the same name will be matched.
212 // 223 //
213 matchingParameter = methodParameters.lastWhere( 224 matchingParameter = methodParameters.lastWhere(
214 (ParameterElement methodParameter) => 225 (ParameterElement methodParameter) =>
215 methodParameter.parameterKind == ParameterKind.NAMED && 226 methodParameter.parameterKind == ParameterKind.NAMED &&
216 methodParameter.name == parameter.name, 227 methodParameter.name == parameter.name,
217 orElse: () => null); 228 orElse: () => null);
218 } else { 229 } else {
219 // 230 //
220 // If we're looking for a positional parameter we ignore the difference 231 // If we're looking for a positional parameter we ignore the difference
221 // between required and optional parameters. 232 // between required and optional parameters.
222 // 233 //
223 if (index < methodParameters.length) { 234 if (index < methodParameters.length) {
224 matchingParameter = methodParameters[index]; 235 matchingParameter = methodParameters[index];
225 if (matchingParameter.parameterKind == ParameterKind.NAMED) { 236 if (matchingParameter.parameterKind == ParameterKind.NAMED) {
226 matchingParameter = null; 237 matchingParameter = null;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 // field types are inferred. 282 // field types are inferred.
272 // 283 //
273 classElement.constructors.forEach(_inferConstructorFieldFormals); 284 classElement.constructors.forEach(_inferConstructorFieldFormals);
274 classElement.hasBeenInferred = true; 285 classElement.hasBeenInferred = true;
275 } finally { 286 } finally {
276 elementsBeingInferred.remove(classElement); 287 elementsBeingInferred.remove(classElement);
277 } 288 }
278 } 289 }
279 } 290 }
280 291
281 /** 292 void _inferConstructorFieldFormals(ConstructorElement element) {
282 * If the given [fieldElement] represents a non-synthetic instance field for 293 for (ParameterElement p in element.parameters) {
283 * which no type was provided, infer the type of the field. 294 if (p is FieldFormalParameterElement) {
284 */ 295 _inferFieldFormalParameter(p);
285 void _inferField(FieldElement fieldElement) {
286 if (!fieldElement.isSynthetic &&
287 !fieldElement.isStatic &&
288 fieldElement.hasImplicitType) {
289 //
290 // First look for overridden getters with the same name as the field.
291 //
292 List<ExecutableElement> overriddenGetters = inheritanceManager
293 .lookupOverrides(fieldElement.enclosingElement, fieldElement.name);
294 DartType newType = null;
295 if (overriddenGetters.isNotEmpty && _onlyGetters(overriddenGetters)) {
296 newType = _computeReturnType(overriddenGetters);
297 List<ExecutableElement> overriddenSetters = inheritanceManager
298 .lookupOverrides(
299 fieldElement.enclosingElement, fieldElement.name + '=');
300 if (!_isCompatible(newType, overriddenSetters)) {
301 newType = null;
302 }
303 }
304 //
305 // If there is no overridden getter or if the overridden getter's type is
306 // dynamic, then we can infer the type from the initialization expression
307 // without breaking subtype rules. We could potentially infer a consistent
308 // return type even if the overridden getter's type was not dynamic, but
309 // choose not to for simplicity. The field is required to be final to
310 // prevent choosing a type that is inconsistent with assignments we cannot
311 // analyze.
312 //
313 if (newType == null || newType.isDynamic) {
314 if (fieldElement.initializer != null &&
315 (fieldElement.isFinal || overriddenGetters.isEmpty)) {
316 newType = fieldElement.initializer.returnType;
317 }
318 }
319 if (newType == null || newType.isBottom) {
320 newType = typeProvider.dynamicType;
321 }
322 (fieldElement as FieldElementImpl).type = newType;
323 setReturnType(fieldElement.getter, newType);
324 if (!fieldElement.isFinal && !fieldElement.isConst) {
325 setParameterType(fieldElement.setter, newType);
326 } 296 }
327 } 297 }
328 } 298 }
329 299
330 /** 300 /**
331 * If the given [element] represents a non-synthetic instance method, 301 * If the given [element] represents a non-synthetic instance method,
332 * getter or setter, infer the return type and any parameter type(s) where 302 * getter or setter, infer the return type and any parameter type(s) where
333 * they were not provided. 303 * they were not provided.
334 */ 304 */
335 void _inferExecutable(ExecutableElement element) { 305 void _inferExecutable(ExecutableElement element) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 } 340 }
371 parameter.type = _computeParameterType(parameter, i, overriddenMethods); 341 parameter.type = _computeParameterType(parameter, i, overriddenMethods);
372 if (element is PropertyAccessorElement) { 342 if (element is PropertyAccessorElement) {
373 _updateSyntheticVariableType(element); 343 _updateSyntheticVariableType(element);
374 } 344 }
375 } 345 }
376 } 346 }
377 } 347 }
378 348
379 /** 349 /**
380 * If the given [element] is a non-synthetic getter or setter, update its 350 * If the given [fieldElement] represents a non-synthetic instance field for
381 * synthetic variable's type to match the getter's return type, or if no 351 * which no type was provided, infer the type of the field.
382 * corresponding getter exists, use the setter's parameter type.
383 *
384 * In general, the type of the synthetic variable should not be used, because
385 * getters and setters are independent methods. But this logic matches what
386 * `TypeResolverVisitor.visitMethodDeclaration` would fill in there.
387 */ 352 */
388 void _updateSyntheticVariableType(PropertyAccessorElement element) { 353 void _inferField(FieldElement fieldElement) {
389 assert(!element.isSynthetic); 354 if (!fieldElement.isSynthetic &&
390 PropertyAccessorElement getter = element; 355 !fieldElement.isStatic &&
391 if (element.isSetter) { 356 fieldElement.hasImplicitType) {
392 // See if we can find any getter. 357 //
393 getter = element.correspondingGetter; 358 // First look for overridden getters with the same name as the field.
394 } 359 //
395 DartType newType; 360 List<ExecutableElement> overriddenGetters = inheritanceManager
396 if (getter != null) { 361 .lookupOverrides(fieldElement.enclosingElement, fieldElement.name);
397 newType = getter.returnType; 362 DartType newType = null;
398 } else if (element.isSetter && element.parameters.isNotEmpty) { 363 if (overriddenGetters.isNotEmpty && _onlyGetters(overriddenGetters)) {
399 newType = element.parameters[0].type; 364 newType = _computeReturnType(overriddenGetters);
400 } 365 List<ExecutableElement> overriddenSetters =
401 if (newType != null) { 366 inheritanceManager.lookupOverrides(
402 (element.variable as VariableElementImpl).type = newType; 367 fieldElement.enclosingElement, fieldElement.name + '=');
368 if (!_isCompatible(newType, overriddenSetters)) {
369 newType = null;
370 }
371 }
372 //
373 // If there is no overridden getter or if the overridden getter's type is
374 // dynamic, then we can infer the type from the initialization expression
375 // without breaking subtype rules. We could potentially infer a consistent
376 // return type even if the overridden getter's type was not dynamic, but
377 // choose not to for simplicity. The field is required to be final to
378 // prevent choosing a type that is inconsistent with assignments we cannot
379 // analyze.
380 //
381 if (newType == null || newType.isDynamic) {
382 if (fieldElement.initializer != null &&
383 (fieldElement.isFinal || overriddenGetters.isEmpty)) {
384 newType = fieldElement.initializer.returnType;
385 }
386 }
387 if (newType == null || newType.isBottom) {
388 newType = typeProvider.dynamicType;
389 }
390 (fieldElement as FieldElementImpl).type = newType;
391 setReturnType(fieldElement.getter, newType);
392 if (!fieldElement.isFinal && !fieldElement.isConst) {
393 setParameterType(fieldElement.setter, newType);
394 }
403 } 395 }
404 } 396 }
405 397
398 void _inferFieldFormalParameter(FieldFormalParameterElement element) {
399 FieldElement field = element.field;
400 if (field != null && element.hasImplicitType) {
401 (element as FieldFormalParameterElementImpl).type = field.type;
402 }
403 }
404
406 /** 405 /**
407 * Infer type information for all of the instance members in the given 406 * Infer type information for all of the instance members in the given
408 * interface [type]. 407 * interface [type].
409 */ 408 */
410 void _inferType(InterfaceType type) { 409 void _inferType(InterfaceType type) {
411 if (type != null) { 410 if (type != null) {
412 ClassElement element = type.element; 411 ClassElement element = type.element;
413 if (element != null) { 412 if (element != null) {
414 _inferClass(element); 413 _inferClass(element);
415 } 414 }
(...skipping 20 matching lines...) Expand all
436 bool _onlyGetters(List<ExecutableElement> elements) { 435 bool _onlyGetters(List<ExecutableElement> elements) {
437 for (ExecutableElement element in elements) { 436 for (ExecutableElement element in elements) {
438 if (!(element is PropertyAccessorElement && element.isGetter)) { 437 if (!(element is PropertyAccessorElement && element.isGetter)) {
439 return false; 438 return false;
440 } 439 }
441 } 440 }
442 return true; 441 return true;
443 } 442 }
444 443
445 /** 444 /**
446 * Return `true` if the list of [elements] contains only methods. 445 * If the given [element] is a non-synthetic getter or setter, update its
446 * synthetic variable's type to match the getter's return type, or if no
447 * corresponding getter exists, use the setter's parameter type.
448 *
449 * In general, the type of the synthetic variable should not be used, because
450 * getters and setters are independent methods. But this logic matches what
451 * `TypeResolverVisitor.visitMethodDeclaration` would fill in there.
447 */ 452 */
448 bool _allSameElementKind( 453 void _updateSyntheticVariableType(PropertyAccessorElement element) {
449 ExecutableElement element, List<ExecutableElement> elements) { 454 assert(!element.isSynthetic);
450 return elements.every((e) => e.kind == element.kind); 455 PropertyAccessorElement getter = element;
451 } 456 if (element.isSetter) {
452 457 // See if we can find any getter.
453 void _inferConstructorFieldFormals(ConstructorElement element) { 458 getter = element.correspondingGetter;
454 for (ParameterElement p in element.parameters) {
455 if (p is FieldFormalParameterElement) {
456 _inferFieldFormalParameter(p);
457 }
458 } 459 }
459 } 460 DartType newType;
460 461 if (getter != null) {
461 void _inferFieldFormalParameter(FieldFormalParameterElement element) { 462 newType = getter.returnType;
462 FieldElement field = element.field; 463 } else if (element.isSetter && element.parameters.isNotEmpty) {
463 if (field != null && element.hasImplicitType) { 464 newType = element.parameters[0].type;
464 (element as FieldFormalParameterElementImpl).type = field.type; 465 }
466 if (newType != null) {
467 (element.variable as VariableElementImpl).type = newType;
465 } 468 }
466 } 469 }
467 } 470 }
468 471
469 /** 472 /**
470 * A visitor that will gather all of the variables referenced within a given 473 * A visitor that will gather all of the variables referenced within a given
471 * AST structure. The collection can be restricted to contain only those 474 * AST structure. The collection can be restricted to contain only those
472 * variables that pass a specified filter. 475 * variables that pass a specified filter.
473 */ 476 */
474 class VariableGatherer extends RecursiveAstVisitor { 477 class VariableGatherer extends RecursiveAstVisitor {
(...skipping 25 matching lines...) Expand all
500 results.add(element); 503 results.add(element);
501 } 504 }
502 } 505 }
503 } 506 }
504 } 507 }
505 508
506 /** 509 /**
507 * A class of exception that is not used anywhere else. 510 * A class of exception that is not used anywhere else.
508 */ 511 */
509 class _CycleException implements Exception {} 512 class _CycleException implements Exception {}
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/task/strong/info.dart ('k') | pkg/analyzer/lib/task/dart.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698