| 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 |