| 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 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'; |
| 11 import 'package:analyzer/dart/element/element.dart'; | 11 import 'package:analyzer/dart/element/element.dart'; |
| 12 import 'package:analyzer/dart/element/type.dart'; | 12 import 'package:analyzer/dart/element/type.dart'; |
| 13 import 'package:analyzer/src/dart/element/element.dart'; | 13 import 'package:analyzer/src/dart/element/element.dart'; |
| 14 import 'package:analyzer/src/dart/element/type.dart'; | 14 import 'package:analyzer/src/dart/element/type.dart'; |
| 15 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; | 15 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; |
| 16 import 'package:analyzer/src/generated/resolver.dart' | 16 import 'package:analyzer/src/generated/resolver.dart' |
| 17 show TypeProvider, InheritanceManager; | 17 show TypeProvider, InheritanceManager; |
| 18 import 'package:analyzer/src/generated/type_system.dart'; | 18 import 'package:analyzer/src/generated/type_system.dart'; |
| 19 import 'package:analyzer/src/generated/utilities_dart.dart'; | 19 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 20 import 'package:analyzer/src/summary/format.dart'; | 20 import 'package:analyzer/src/summary/format.dart'; |
| 21 import 'package:analyzer/src/summary/idl.dart'; | 21 import 'package:analyzer/src/summary/idl.dart'; |
| 22 import 'package:analyzer/src/summary/link.dart' | 22 import 'package:analyzer/src/summary/link.dart' |
| 23 show FieldElementForLink_ClassField, ParameterElementForLink; | 23 show FieldElementForLink_ClassField, ParameterElementForLink; |
| 24 | 24 |
| 25 /** | 25 /** |
| 26 * Return `true` if the given [expression] is an immediately-evident expression, | |
| 27 * so can be used to infer the type for a top-level variable or a class field. | |
| 28 */ | |
| 29 bool isValidForTypeInference(Expression expression) { | |
| 30 var visitor = new _IsValidForTypeInferenceVisitor(); | |
| 31 expression.accept(visitor); | |
| 32 return visitor.isValid; | |
| 33 } | |
| 34 | |
| 35 /** | |
| 36 * Sets the type of the field. The types in implicit accessors are updated | 26 * Sets the type of the field. The types in implicit accessors are updated |
| 37 * implicitly, and the types of explicit accessors should be updated separately. | 27 * implicitly, and the types of explicit accessors should be updated separately. |
| 38 */ | 28 */ |
| 39 void setFieldType(VariableElement field, DartType newType) { | 29 void setFieldType(VariableElement field, DartType newType) { |
| 40 (field as VariableElementImpl).type = newType; | 30 (field as VariableElementImpl).type = newType; |
| 41 } | 31 } |
| 42 | 32 |
| 43 /** | 33 /** |
| 44 * A function that return the [InheritanceManager] for the class [element]. | 34 * A function that return the [InheritanceManager] for the class [element]. |
| 45 */ | 35 */ |
| (...skipping 18 matching lines...) Expand all Loading... |
| 64 * The type system used to compute the least upper bound of types. | 54 * The type system used to compute the least upper bound of types. |
| 65 */ | 55 */ |
| 66 TypeSystem typeSystem; | 56 TypeSystem typeSystem; |
| 67 | 57 |
| 68 /** | 58 /** |
| 69 * The provider for inheritance managers used to find overridden method. | 59 * The provider for inheritance managers used to find overridden method. |
| 70 */ | 60 */ |
| 71 final InheritanceManagerProvider inheritanceManagerProvider; | 61 final InheritanceManagerProvider inheritanceManagerProvider; |
| 72 | 62 |
| 73 /** | 63 /** |
| 74 * The set of fields for which type inference from initializer should be | |
| 75 * disabled, because their initializers are not immediately-evident | |
| 76 * expressions. | |
| 77 */ | |
| 78 final Set<FieldElement> fieldsWithDisabledInitializerInference; | |
| 79 | |
| 80 /** | |
| 81 * The classes that have been visited while attempting to infer the types of | 64 * The classes that have been visited while attempting to infer the types of |
| 82 * instance members of some base class. | 65 * instance members of some base class. |
| 83 */ | 66 */ |
| 84 HashSet<ClassElementImpl> elementsBeingInferred = | 67 HashSet<ClassElementImpl> elementsBeingInferred = |
| 85 new HashSet<ClassElementImpl>(); | 68 new HashSet<ClassElementImpl>(); |
| 86 | 69 |
| 87 /** | 70 /** |
| 88 * Initialize a newly create inferrer. | 71 * Initialize a newly create inferrer. |
| 89 */ | 72 */ |
| 90 InstanceMemberInferrer( | 73 InstanceMemberInferrer( |
| 91 TypeProvider typeProvider, | 74 TypeProvider typeProvider, this.inheritanceManagerProvider, |
| 92 this.inheritanceManagerProvider, | |
| 93 this.fieldsWithDisabledInitializerInference, | |
| 94 {TypeSystem typeSystem}) | 75 {TypeSystem typeSystem}) |
| 95 : typeSystem = (typeSystem != null) | 76 : typeSystem = (typeSystem != null) |
| 96 ? typeSystem | 77 ? typeSystem |
| 97 : new TypeSystemImpl(typeProvider), | 78 : new TypeSystemImpl(typeProvider), |
| 98 this.typeProvider = typeProvider; | 79 this.typeProvider = typeProvider; |
| 99 | 80 |
| 100 /** | 81 /** |
| 101 * Infer type information for all of the instance members in the given | 82 * Infer type information for all of the instance members in the given |
| 102 * compilation [unit]. | 83 * compilation [unit]. |
| 103 */ | 84 */ |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 if (typeResult.isError) { | 404 if (typeResult.isError) { |
| 424 if (field is FieldElementForLink_ClassField) { | 405 if (field is FieldElementForLink_ClassField) { |
| 425 field.setInferenceError(new TopLevelInferenceErrorBuilder( | 406 field.setInferenceError(new TopLevelInferenceErrorBuilder( |
| 426 kind: TopLevelInferenceErrorKind.overrideConflictFieldType)); | 407 kind: TopLevelInferenceErrorKind.overrideConflictFieldType)); |
| 427 } | 408 } |
| 428 return; | 409 return; |
| 429 } | 410 } |
| 430 | 411 |
| 431 if (field.hasImplicitType) { | 412 if (field.hasImplicitType) { |
| 432 DartType newType = typeResult.type; | 413 DartType newType = typeResult.type; |
| 433 if (newType == null && | 414 if (newType == null && field.initializer != null) { |
| 434 field.initializer != null && | |
| 435 !fieldsWithDisabledInitializerInference.contains(field)) { | |
| 436 newType = field.initializer.returnType; | 415 newType = field.initializer.returnType; |
| 437 } | 416 } |
| 438 | 417 |
| 439 if (newType == null || newType.isBottom || newType.isDartCoreNull) { | 418 if (newType == null || newType.isBottom || newType.isDartCoreNull) { |
| 440 newType = typeProvider.dynamicType; | 419 newType = typeProvider.dynamicType; |
| 441 } | 420 } |
| 442 | 421 |
| 443 setFieldType(field, newType); | 422 setFieldType(field, newType); |
| 444 } | 423 } |
| 445 | 424 |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 /** | 580 /** |
| 602 * The result of field type inference. | 581 * The result of field type inference. |
| 603 */ | 582 */ |
| 604 class _FieldOverrideInferenceResult { | 583 class _FieldOverrideInferenceResult { |
| 605 final bool isCovariant; | 584 final bool isCovariant; |
| 606 final DartType type; | 585 final DartType type; |
| 607 final bool isError; | 586 final bool isError; |
| 608 | 587 |
| 609 _FieldOverrideInferenceResult(this.isCovariant, this.type, this.isError); | 588 _FieldOverrideInferenceResult(this.isCovariant, this.type, this.isError); |
| 610 } | 589 } |
| 611 | |
| 612 /** | |
| 613 * The visitor for [isValidForTypeInference]. | |
| 614 */ | |
| 615 class _IsValidForTypeInferenceVisitor extends RecursiveAstVisitor { | |
| 616 bool isValid = true; | |
| 617 | |
| 618 @override | |
| 619 void visitAssignmentExpression(AssignmentExpression node) { | |
| 620 isValid = false; | |
| 621 } | |
| 622 | |
| 623 @override | |
| 624 void visitCascadeExpression(CascadeExpression node) { | |
| 625 node.target.accept(this); | |
| 626 } | |
| 627 | |
| 628 @override | |
| 629 void visitFunctionExpression(FunctionExpression node) { | |
| 630 FunctionBody body = node.body; | |
| 631 if (body is ExpressionFunctionBody) { | |
| 632 body.accept(this); | |
| 633 } else { | |
| 634 isValid = false; | |
| 635 } | |
| 636 } | |
| 637 | |
| 638 @override | |
| 639 void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | |
| 640 node.function?.accept(this); | |
| 641 } | |
| 642 | |
| 643 @override | |
| 644 void visitIndexExpression(IndexExpression node) { | |
| 645 isValid = false; | |
| 646 } | |
| 647 | |
| 648 @override | |
| 649 void visitInstanceCreationExpression(InstanceCreationExpression node) { | |
| 650 ConstructorElement constructor = node.staticElement; | |
| 651 if (constructor != null) { | |
| 652 ClassElement clazz = constructor?.enclosingElement; | |
| 653 if (clazz.typeParameters.isNotEmpty && | |
| 654 node.constructorName.type.typeArguments == null) { | |
| 655 isValid = false; | |
| 656 return; | |
| 657 } | |
| 658 } | |
| 659 } | |
| 660 | |
| 661 @override | |
| 662 void visitListLiteral(ListLiteral node) { | |
| 663 if (node.typeArguments == null) { | |
| 664 super.visitListLiteral(node); | |
| 665 } | |
| 666 } | |
| 667 | |
| 668 @override | |
| 669 void visitMapLiteral(MapLiteral node) { | |
| 670 if (node.typeArguments == null) { | |
| 671 super.visitMapLiteral(node); | |
| 672 } | |
| 673 } | |
| 674 | |
| 675 @override | |
| 676 void visitMethodInvocation(MethodInvocation node) { | |
| 677 Element element = node.methodName.staticElement; | |
| 678 if (element is ExecutableElement) { | |
| 679 if (element.type.typeFormals.isNotEmpty && node.typeArguments == null) { | |
| 680 isValid = false; | |
| 681 return; | |
| 682 } | |
| 683 } | |
| 684 node.target?.accept(this); | |
| 685 } | |
| 686 | |
| 687 @override | |
| 688 void visitSimpleIdentifier(SimpleIdentifier node) { | |
| 689 Element element = node.staticElement; | |
| 690 if (element == null) { | |
| 691 AstNode parent = node.parent; | |
| 692 if (parent is PropertyAccess && parent.propertyName == node || | |
| 693 parent is PrefixedIdentifier && parent.identifier == node) { | |
| 694 isValid = false; | |
| 695 } | |
| 696 } else if (element is PropertyAccessorElement && !element.isStatic) { | |
| 697 isValid = false; | |
| 698 } | |
| 699 } | |
| 700 } | |
| OLD | NEW |