| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 // This code was auto-generated, is not intended to be edited, and is subject to | 5 // This code was auto-generated, is not intended to be edited, and is subject to |
| 6 // significant change. Please see the README file for more information. | 6 // significant change. Please see the README file for more information. |
| 7 | 7 |
| 8 library engine.resolver; | 8 library engine.resolver; |
| 9 | 9 |
| 10 import 'dart:collection'; | 10 import 'dart:collection'; |
| (...skipping 1566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1577 } else if (type == _typeProvider.doubleType) { | 1577 } else if (type == _typeProvider.doubleType) { |
| 1578 return true; | 1578 return true; |
| 1579 } | 1579 } |
| 1580 // prepare ClassElement | 1580 // prepare ClassElement |
| 1581 Element element = type.element; | 1581 Element element = type.element; |
| 1582 if (element is! ClassElement) { | 1582 if (element is! ClassElement) { |
| 1583 return false; | 1583 return false; |
| 1584 } | 1584 } |
| 1585 ClassElement classElement = element as ClassElement; | 1585 ClassElement classElement = element as ClassElement; |
| 1586 // lookup for == | 1586 // lookup for == |
| 1587 MethodElement method = classElement.lookUpMethod("==", _currentLibrary); | 1587 MethodElement method = classElement.lookUpConcreteMethod("==", _currentLibra
ry); |
| 1588 while (method != null && method.isAbstract) { | |
| 1589 ClassElement definingClass = method.enclosingElement; | |
| 1590 if (definingClass == null) { | |
| 1591 return false; | |
| 1592 } | |
| 1593 method = definingClass.lookUpInheritedMethod("==", _currentLibrary); | |
| 1594 } | |
| 1595 if (method == null || method.enclosingElement.type.isObject) { | 1588 if (method == null || method.enclosingElement.type.isObject) { |
| 1596 return false; | 1589 return false; |
| 1597 } | 1590 } |
| 1598 // there is == that we don't like | 1591 // there is == that we don't like |
| 1599 return true; | 1592 return true; |
| 1600 } | 1593 } |
| 1601 | 1594 |
| 1602 /** | 1595 /** |
| 1603 * Given some computed [Expression], this method generates the passed [ErrorCo
de] on | 1596 * Given some computed [Expression], this method generates the passed [ErrorCo
de] on |
| 1604 * the node if its' value consists of information from a deferred library. | 1597 * the node if its' value consists of information from a deferred library. |
| (...skipping 3892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5497 // TODO(brianwilkerson) Consider the possibility of re-writing the AST. | 5490 // TODO(brianwilkerson) Consider the possibility of re-writing the AST. |
| 5498 FunctionType getterType = element.type; | 5491 FunctionType getterType = element.type; |
| 5499 if (getterType != null) { | 5492 if (getterType != null) { |
| 5500 DartType returnType = getterType.returnType; | 5493 DartType returnType = getterType.returnType; |
| 5501 if (!_isExecutableType(returnType)) { | 5494 if (!_isExecutableType(returnType)) { |
| 5502 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; | 5495 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; |
| 5503 } | 5496 } |
| 5504 } | 5497 } |
| 5505 } else if (element is ExecutableElement) { | 5498 } else if (element is ExecutableElement) { |
| 5506 return null; | 5499 return null; |
| 5500 } else if (element is MultiplyDefinedElement) { |
| 5501 // The error has already been reported |
| 5502 return null; |
| 5507 } else if (element == null && target is SuperExpression) { | 5503 } else if (element == null && target is SuperExpression) { |
| 5508 // TODO(jwren) We should split the UNDEFINED_METHOD into two error codes,
this one, and | 5504 // TODO(jwren) We should split the UNDEFINED_METHOD into two error codes,
this one, and |
| 5509 // a code that describes the situation where the method was found, but it
was not | 5505 // a code that describes the situation where the method was found, but it
was not |
| 5510 // accessible from the current library. | 5506 // accessible from the current library. |
| 5511 return StaticTypeWarningCode.UNDEFINED_SUPER_METHOD; | 5507 return StaticTypeWarningCode.UNDEFINED_SUPER_METHOD; |
| 5512 } else { | 5508 } else { |
| 5513 // | 5509 // |
| 5514 // This is really a function expression invocation. | 5510 // This is really a function expression invocation. |
| 5515 // | 5511 // |
| 5516 // TODO(brianwilkerson) Consider the possibility of re-writing the AST. | 5512 // TODO(brianwilkerson) Consider the possibility of re-writing the AST. |
| (...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6721 } | 6717 } |
| 6722 } else if (propertyName.inGetterContext()) { | 6718 } else if (propertyName.inGetterContext()) { |
| 6723 if (isStaticProperty) { | 6719 if (isStaticProperty) { |
| 6724 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarn
ingCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER); | 6720 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarn
ingCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER); |
| 6725 if (_doesClassElementHaveProxy(staticOrPropagatedEnclosingElt)) { | 6721 if (_doesClassElementHaveProxy(staticOrPropagatedEnclosingElt)) { |
| 6726 _resolver.reportErrorForNode(errorCode, propertyName, [ | 6722 _resolver.reportErrorForNode(errorCode, propertyName, [ |
| 6727 propertyName.name, | 6723 propertyName.name, |
| 6728 staticOrPropagatedEnclosingElt.displayName]); | 6724 staticOrPropagatedEnclosingElt.displayName]); |
| 6729 } | 6725 } |
| 6730 } else { | 6726 } else { |
| 6727 if (staticOrPropagatedEnclosingElt is ClassElement) { |
| 6728 InterfaceType targetType = staticOrPropagatedEnclosingElt.type; |
| 6729 if (targetType != null && targetType.isDartCoreFunction && propert
yName.name == FunctionElement.CALL_METHOD_NAME) { |
| 6730 // TODO(brianwilkerson) Can we ever resolve the function being i
nvoked? |
| 6731 //resolveArgumentsToParameters(node.getArgumentList(), invokedFu
nction); |
| 6732 return; |
| 6733 } |
| 6734 } |
| 6731 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticType
WarningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER); | 6735 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticType
WarningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER); |
| 6732 if (_doesClassElementHaveProxy(staticOrPropagatedEnclosingElt)) { | 6736 if (_doesClassElementHaveProxy(staticOrPropagatedEnclosingElt)) { |
| 6733 _resolver.reportErrorForNode(errorCode, propertyName, [ | 6737 _resolver.reportErrorForNode(errorCode, propertyName, [ |
| 6734 propertyName.name, | 6738 propertyName.name, |
| 6735 staticOrPropagatedEnclosingElt.displayName]); | 6739 staticOrPropagatedEnclosingElt.displayName]); |
| 6736 } | 6740 } |
| 6737 } | 6741 } |
| 6738 } else { | 6742 } else { |
| 6739 if (_doesClassElementHaveProxy(staticOrPropagatedEnclosingElt)) { | 6743 if (_doesClassElementHaveProxy(staticOrPropagatedEnclosingElt)) { |
| 6740 _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_IDENTIFIER,
propertyName, [propertyName.name]); | 6744 _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_IDENTIFIER,
propertyName, [propertyName.name]); |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7405 ClassElement outerClassElement = _enclosingClass; | 7409 ClassElement outerClassElement = _enclosingClass; |
| 7406 try { | 7410 try { |
| 7407 _enclosingClass = node.element; | 7411 _enclosingClass = node.element; |
| 7408 ImplementsClause implementsClause = node.implementsClause; | 7412 ImplementsClause implementsClause = node.implementsClause; |
| 7409 // Only check for all of the inheritance logic around clauses if there isn
't an error code | 7413 // Only check for all of the inheritance logic around clauses if there isn
't an error code |
| 7410 // such as "Cannot extend double" already on the class. | 7414 // such as "Cannot extend double" already on the class. |
| 7411 if (!_checkForExtendsDisallowedClassInTypeAlias(node) && !_checkForImpleme
ntsDisallowedClass(implementsClause) && !_checkForAllMixinErrorCodes(node.withCl
ause)) { | 7415 if (!_checkForExtendsDisallowedClassInTypeAlias(node) && !_checkForImpleme
ntsDisallowedClass(implementsClause) && !_checkForAllMixinErrorCodes(node.withCl
ause)) { |
| 7412 _checkForExtendsDeferredClassInTypeAlias(node); | 7416 _checkForExtendsDeferredClassInTypeAlias(node); |
| 7413 _checkForImplementsDeferredClass(implementsClause); | 7417 _checkForImplementsDeferredClass(implementsClause); |
| 7414 _checkForRecursiveInterfaceInheritance(_enclosingClass); | 7418 _checkForRecursiveInterfaceInheritance(_enclosingClass); |
| 7415 _checkForTypeAliasCannotReferenceItself_mixin(node); | |
| 7416 _checkForNonAbstractClassInheritsAbstractMember(node.name); | 7419 _checkForNonAbstractClassInheritsAbstractMember(node.name); |
| 7417 } | 7420 } |
| 7418 } finally { | 7421 } finally { |
| 7419 _enclosingClass = outerClassElement; | 7422 _enclosingClass = outerClassElement; |
| 7420 } | 7423 } |
| 7421 return super.visitClassTypeAlias(node); | 7424 return super.visitClassTypeAlias(node); |
| 7422 } | 7425 } |
| 7423 | 7426 |
| 7424 @override | 7427 @override |
| 7425 Object visitComment(Comment node) { | 7428 Object visitComment(Comment node) { |
| (...skipping 1454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8880 /** | 8883 /** |
| 8881 * This verifies that the passed method declaration is abstract only if the en
closing class is | 8884 * This verifies that the passed method declaration is abstract only if the en
closing class is |
| 8882 * also abstract. | 8885 * also abstract. |
| 8883 * | 8886 * |
| 8884 * @param node the method declaration to evaluate | 8887 * @param node the method declaration to evaluate |
| 8885 * @return `true` if and only if an error code is generated on the passed node | 8888 * @return `true` if and only if an error code is generated on the passed node |
| 8886 * @see StaticWarningCode#CONCRETE_CLASS_WITH_ABSTRACT_MEMBER | 8889 * @see StaticWarningCode#CONCRETE_CLASS_WITH_ABSTRACT_MEMBER |
| 8887 */ | 8890 */ |
| 8888 bool _checkForConcreteClassWithAbstractMember(MethodDeclaration node) { | 8891 bool _checkForConcreteClassWithAbstractMember(MethodDeclaration node) { |
| 8889 if (node.isAbstract && _enclosingClass != null && !_enclosingClass.isAbstrac
t) { | 8892 if (node.isAbstract && _enclosingClass != null && !_enclosingClass.isAbstrac
t) { |
| 8890 SimpleIdentifier methodName = node.name; | 8893 SimpleIdentifier nameNode = node.name; |
| 8891 _errorReporter.reportErrorForNode(StaticWarningCode.CONCRETE_CLASS_WITH_AB
STRACT_MEMBER, methodName, [methodName.name, _enclosingClass.displayName]); | 8894 String memberName = nameNode.name; |
| 8892 return true; | 8895 ExecutableElement overriddenMember; |
| 8896 if (node.isGetter) { |
| 8897 overriddenMember = _enclosingClass.lookUpInheritedConcreteGetter(memberN
ame, _currentLibrary); |
| 8898 } else if (node.isSetter) { |
| 8899 overriddenMember = _enclosingClass.lookUpInheritedConcreteSetter(memberN
ame, _currentLibrary); |
| 8900 } else { |
| 8901 overriddenMember = _enclosingClass.lookUpInheritedConcreteMethod(memberN
ame, _currentLibrary); |
| 8902 } |
| 8903 if (overriddenMember == null) { |
| 8904 _errorReporter.reportErrorForNode(StaticWarningCode.CONCRETE_CLASS_WITH_
ABSTRACT_MEMBER, nameNode, [memberName, _enclosingClass.displayName]); |
| 8905 return true; |
| 8906 } |
| 8893 } | 8907 } |
| 8894 return false; | 8908 return false; |
| 8895 } | 8909 } |
| 8896 | 8910 |
| 8897 /** | 8911 /** |
| 8898 * This verifies all possible conflicts of the constructor name with other con
structors and | 8912 * This verifies all possible conflicts of the constructor name with other con
structors and |
| 8899 * members of the same class. | 8913 * members of the same class. |
| 8900 * | 8914 * |
| 8901 * @param node the constructor declaration to evaluate | 8915 * @param node the constructor declaration to evaluate |
| 8902 * @param constructorElement the constructor element | 8916 * @param constructorElement the constructor element |
| (...skipping 2462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11365 bool _checkForTypeAliasCannotReferenceItself_function(FunctionTypeAlias node)
{ | 11379 bool _checkForTypeAliasCannotReferenceItself_function(FunctionTypeAlias node)
{ |
| 11366 FunctionTypeAliasElement element = node.element; | 11380 FunctionTypeAliasElement element = node.element; |
| 11367 if (!_hasTypedefSelfReference(element)) { | 11381 if (!_hasTypedefSelfReference(element)) { |
| 11368 return false; | 11382 return false; |
| 11369 } | 11383 } |
| 11370 _errorReporter.reportErrorForNode(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REF
ERENCE_ITSELF, node, []); | 11384 _errorReporter.reportErrorForNode(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REF
ERENCE_ITSELF, node, []); |
| 11371 return true; | 11385 return true; |
| 11372 } | 11386 } |
| 11373 | 11387 |
| 11374 /** | 11388 /** |
| 11375 * This verifies that the given class type alias does not reference itself. | |
| 11376 * | |
| 11377 * @return `true` if and only if an error code is generated on the passed node | |
| 11378 * @see CompileTimeErrorCode#TYPE_ALIAS_CANNOT_REFERENCE_ITSELF | |
| 11379 */ | |
| 11380 bool _checkForTypeAliasCannotReferenceItself_mixin(ClassTypeAlias node) { | |
| 11381 ClassElement element = node.element; | |
| 11382 if (!_hasTypedefSelfReference(element)) { | |
| 11383 return false; | |
| 11384 } | |
| 11385 _errorReporter.reportErrorForNode(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REF
ERENCE_ITSELF, node, []); | |
| 11386 return true; | |
| 11387 } | |
| 11388 | |
| 11389 /** | |
| 11390 * This verifies that the passed type name is not a deferred type. | 11389 * This verifies that the passed type name is not a deferred type. |
| 11391 * | 11390 * |
| 11392 * @param expression the expression to evaluate | 11391 * @param expression the expression to evaluate |
| 11393 * @return `true` if and only if an error code is generated on the passed node | 11392 * @return `true` if and only if an error code is generated on the passed node |
| 11394 * @see StaticWarningCode#TYPE_ANNOTATION_DEFERRED_CLASS | 11393 * @see StaticWarningCode#TYPE_ANNOTATION_DEFERRED_CLASS |
| 11395 */ | 11394 */ |
| 11396 bool _checkForTypeAnnotationDeferredClass(TypeName node) { | 11395 bool _checkForTypeAnnotationDeferredClass(TypeName node) { |
| 11397 if (node != null && node.isDeferred) { | 11396 if (node != null && node.isDeferred) { |
| 11398 _errorReporter.reportErrorForNode(StaticWarningCode.TYPE_ANNOTATION_DEFERR
ED_CLASS, node, [node.name]); | 11397 _errorReporter.reportErrorForNode(StaticWarningCode.TYPE_ANNOTATION_DEFERR
ED_CLASS, node, [node.name]); |
| 11399 } | 11398 } |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11753 if (interfaceNode.type == superType) { | 11752 if (interfaceNode.type == superType) { |
| 11754 hasProblem = true; | 11753 hasProblem = true; |
| 11755 _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPLEMENTS_SUPER_
CLASS, interfaceNode, [superType.displayName]); | 11754 _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPLEMENTS_SUPER_
CLASS, interfaceNode, [superType.displayName]); |
| 11756 } | 11755 } |
| 11757 } | 11756 } |
| 11758 // done | 11757 // done |
| 11759 return hasProblem; | 11758 return hasProblem; |
| 11760 } | 11759 } |
| 11761 | 11760 |
| 11762 /** | 11761 /** |
| 11762 * Return the error code that should be used when the given class references i
tself directly. |
| 11763 * |
| 11764 * @param classElt the class that references itself |
| 11765 * @return the error code that should be used |
| 11766 */ |
| 11767 ErrorCode _getBaseCaseErrorCode(ClassElement classElt) { |
| 11768 InterfaceType supertype = classElt.supertype; |
| 11769 if (supertype != null && _enclosingClass == supertype.element) { |
| 11770 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTE
NDS; |
| 11771 } |
| 11772 List<InterfaceType> mixins = classElt.mixins; |
| 11773 for (int i = 0; i < mixins.length; i++) { |
| 11774 if (_enclosingClass == mixins[i].element) { |
| 11775 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WI
TH; |
| 11776 } |
| 11777 } |
| 11778 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEM
ENTS; |
| 11779 } |
| 11780 |
| 11781 /** |
| 11763 * Returns the Type (return type) for a given getter. | 11782 * Returns the Type (return type) for a given getter. |
| 11764 * | 11783 * |
| 11765 * @param propertyAccessorElement | 11784 * @param propertyAccessorElement |
| 11766 * @return The type of the given getter. | 11785 * @return The type of the given getter. |
| 11767 */ | 11786 */ |
| 11768 DartType _getGetterType(PropertyAccessorElement propertyAccessorElement) { | 11787 DartType _getGetterType(PropertyAccessorElement propertyAccessorElement) { |
| 11769 FunctionType functionType = propertyAccessorElement.type; | 11788 FunctionType functionType = propertyAccessorElement.type; |
| 11770 if (functionType != null) { | 11789 if (functionType != null) { |
| 11771 return functionType.returnType; | 11790 return functionType.returnType; |
| 11772 } else { | 11791 } else { |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11993 | 12012 |
| 11994 /** | 12013 /** |
| 11995 * This checks the class declaration is not a superinterface to itself. | 12014 * This checks the class declaration is not a superinterface to itself. |
| 11996 * | 12015 * |
| 11997 * @param classElt the class element to test | 12016 * @param classElt the class element to test |
| 11998 * @param path a list containing the potentially cyclic implements path | 12017 * @param path a list containing the potentially cyclic implements path |
| 11999 * @return `true` if and only if an error code is generated on the passed elem
ent | 12018 * @return `true` if and only if an error code is generated on the passed elem
ent |
| 12000 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE | 12019 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE |
| 12001 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS | 12020 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS |
| 12002 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEME
NTS | 12021 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEME
NTS |
| 12022 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH |
| 12003 */ | 12023 */ |
| 12004 bool _safeCheckForRecursiveInterfaceInheritance(ClassElement classElt, List<Cl
assElement> path) { | 12024 bool _safeCheckForRecursiveInterfaceInheritance(ClassElement classElt, List<Cl
assElement> path) { |
| 12005 // Detect error condition. | 12025 // Detect error condition. |
| 12006 int size = path.length; | 12026 int size = path.length; |
| 12007 // If this is not the base case (size > 0), and the enclosing class is the p
assed class | 12027 // If this is not the base case (size > 0), and the enclosing class is the p
assed class |
| 12008 // element then an error an error. | 12028 // element then an error an error. |
| 12009 if (size > 0 && _enclosingClass == classElt) { | 12029 if (size > 0 && _enclosingClass == classElt) { |
| 12010 String enclosingClassName = _enclosingClass.displayName; | 12030 String enclosingClassName = _enclosingClass.displayName; |
| 12011 if (size > 1) { | 12031 if (size > 1) { |
| 12012 // Construct a string showing the cyclic implements path: "A, B, C, D, A
" | 12032 // Construct a string showing the cyclic implements path: "A, B, C, D, A
" |
| 12013 String separator = ", "; | 12033 String separator = ", "; |
| 12014 JavaStringBuilder builder = new JavaStringBuilder(); | 12034 JavaStringBuilder builder = new JavaStringBuilder(); |
| 12015 for (int i = 0; i < size; i++) { | 12035 for (int i = 0; i < size; i++) { |
| 12016 builder.append(path[i].displayName); | 12036 builder.append(path[i].displayName); |
| 12017 builder.append(separator); | 12037 builder.append(separator); |
| 12018 } | 12038 } |
| 12019 builder.append(classElt.displayName); | 12039 builder.append(classElt.displayName); |
| 12020 _errorReporter.reportErrorForOffset(CompileTimeErrorCode.RECURSIVE_INTER
FACE_INHERITANCE, _enclosingClass.nameOffset, enclosingClassName.length, [enclos
ingClassName, builder.toString()]); | 12040 _errorReporter.reportErrorForOffset(CompileTimeErrorCode.RECURSIVE_INTER
FACE_INHERITANCE, _enclosingClass.nameOffset, enclosingClassName.length, [enclos
ingClassName, builder.toString()]); |
| 12021 return true; | 12041 return true; |
| 12022 } else { | 12042 } else { |
| 12023 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or RECURSIVE_INT
ERFACE_INHERITANCE_BASE_CASE_EXTENDS | 12043 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS or |
| 12024 InterfaceType supertype = classElt.supertype; | 12044 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or |
| 12025 ErrorCode errorCode = (supertype != null && _enclosingClass == supertype
.element ? CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTEND
S : CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS); | 12045 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH |
| 12026 _errorReporter.reportErrorForOffset(errorCode, _enclosingClass.nameOffse
t, enclosingClassName.length, [enclosingClassName]); | 12046 _errorReporter.reportErrorForOffset(_getBaseCaseErrorCode(classElt), _en
closingClass.nameOffset, enclosingClassName.length, [enclosingClassName]); |
| 12027 return true; | 12047 return true; |
| 12028 } | 12048 } |
| 12029 } | 12049 } |
| 12030 if (path.indexOf(classElt) > 0) { | 12050 if (path.indexOf(classElt) > 0) { |
| 12031 return false; | 12051 return false; |
| 12032 } | 12052 } |
| 12033 path.add(classElt); | 12053 path.add(classElt); |
| 12034 // n-case | 12054 // n-case |
| 12035 InterfaceType supertype = classElt.supertype; | 12055 InterfaceType supertype = classElt.supertype; |
| 12036 if (supertype != null && _safeCheckForRecursiveInterfaceInheritance(supertyp
e.element, path)) { | 12056 if (supertype != null && _safeCheckForRecursiveInterfaceInheritance(supertyp
e.element, path)) { |
| 12037 return true; | 12057 return true; |
| 12038 } | 12058 } |
| 12039 List<InterfaceType> interfaceTypes = classElt.interfaces; | 12059 List<InterfaceType> interfaceTypes = classElt.interfaces; |
| 12040 for (InterfaceType interfaceType in interfaceTypes) { | 12060 for (InterfaceType interfaceType in interfaceTypes) { |
| 12041 if (_safeCheckForRecursiveInterfaceInheritance(interfaceType.element, path
)) { | 12061 if (_safeCheckForRecursiveInterfaceInheritance(interfaceType.element, path
)) { |
| 12042 return true; | 12062 return true; |
| 12043 } | 12063 } |
| 12044 } | 12064 } |
| 12065 List<InterfaceType> mixinTypes = classElt.mixins; |
| 12066 for (InterfaceType mixinType in mixinTypes) { |
| 12067 if (_safeCheckForRecursiveInterfaceInheritance(mixinType.element, path)) { |
| 12068 return true; |
| 12069 } |
| 12070 } |
| 12045 path.removeAt(path.length - 1); | 12071 path.removeAt(path.length - 1); |
| 12046 return false; | 12072 return false; |
| 12047 } | 12073 } |
| 12048 } | 12074 } |
| 12049 | 12075 |
| 12050 /** | 12076 /** |
| 12051 * Instances of the class `ExitDetector` determine whether the visited AST node
is guaranteed | 12077 * Instances of the class `ExitDetector` determine whether the visited AST node
is guaranteed |
| 12052 * to terminate by executing a `return` statement, `throw` expression, `rethrow` | 12078 * to terminate by executing a `return` statement, `throw` expression, `rethrow` |
| 12053 * expression, or simple infinite loop such as `while(true)`. | 12079 * expression, or simple infinite loop such as `while(true)`. |
| 12054 */ | 12080 */ |
| (...skipping 999 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13054 | 13080 |
| 13055 /** | 13081 /** |
| 13056 * In cases where there is more than one import directive per library element,
this mapping is | 13082 * In cases where there is more than one import directive per library element,
this mapping is |
| 13057 * used to determine which of the multiple import directives are used by gener
ating a | 13083 * used to determine which of the multiple import directives are used by gener
ating a |
| 13058 * [Namespace] for each of the imports to do lookups in the same way that they
are done from | 13084 * [Namespace] for each of the imports to do lookups in the same way that they
are done from |
| 13059 * the [ElementResolver]. | 13085 * the [ElementResolver]. |
| 13060 */ | 13086 */ |
| 13061 Map<ImportDirective, Namespace> _namespaceMap; | 13087 Map<ImportDirective, Namespace> _namespaceMap; |
| 13062 | 13088 |
| 13063 /** | 13089 /** |
| 13064 * This is a map between prefix elements and the import directive from which t
hey are derived. In | 13090 * This is a map between prefix elements and the import directives from which
they are derived. In |
| 13065 * cases where a type is referenced via a prefix element, the import directive
can be marked as | 13091 * cases where a type is referenced via a prefix element, the import directive
can be marked as |
| 13066 * used (removed from the unusedImports) by looking at the resolved `lib` in `
lib.X`, | 13092 * used (removed from the unusedImports) by looking at the resolved `lib` in `
lib.X`, |
| 13067 * instead of looking at which library the `lib.X` resolves. | 13093 * instead of looking at which library the `lib.X` resolves. |
| 13094 * |
| 13095 * TODO (jwren) Since multiple [ImportDirective]s can share the same [PrefixEl
ement], |
| 13096 * it is possible to have an unreported unused import in situations where two
imports use the same |
| 13097 * prefix and at least one import directive is used. |
| 13068 */ | 13098 */ |
| 13069 Map<PrefixElement, ImportDirective> _prefixElementMap; | 13099 Map<PrefixElement, List<ImportDirective>> _prefixElementMap; |
| 13070 | 13100 |
| 13071 /** | 13101 /** |
| 13072 * Create a new instance of the [ImportsVerifier]. | 13102 * Create a new instance of the [ImportsVerifier]. |
| 13073 * | 13103 * |
| 13074 * @param errorReporter the error reporter | 13104 * @param errorReporter the error reporter |
| 13075 */ | 13105 */ |
| 13076 ImportsVerifier(LibraryElement library) { | 13106 ImportsVerifier(LibraryElement library) { |
| 13077 this._currentLibrary = library; | 13107 this._currentLibrary = library; |
| 13078 this._unusedImports = new List<ImportDirective>(); | 13108 this._unusedImports = new List<ImportDirective>(); |
| 13079 this._duplicateImports = new List<ImportDirective>(); | 13109 this._duplicateImports = new List<ImportDirective>(); |
| 13080 this._libraryMap = new Map<LibraryElement, List<ImportDirective>>(); | 13110 this._libraryMap = new Map<LibraryElement, List<ImportDirective>>(); |
| 13081 this._namespaceMap = new Map<ImportDirective, Namespace>(); | 13111 this._namespaceMap = new Map<ImportDirective, Namespace>(); |
| 13082 this._prefixElementMap = new Map<PrefixElement, ImportDirective>(); | 13112 this._prefixElementMap = new Map<PrefixElement, List<ImportDirective>>(); |
| 13083 } | 13113 } |
| 13084 | 13114 |
| 13085 /** | 13115 /** |
| 13086 * Any time after the defining compilation unit has been visited by this visit
or, this method can | 13116 * Any time after the defining compilation unit has been visited by this visit
or, this method can |
| 13087 * be called to report an [HintCode#DUPLICATE_IMPORT] hint for each of the imp
ort directives | 13117 * be called to report an [HintCode#DUPLICATE_IMPORT] hint for each of the imp
ort directives |
| 13088 * in the [duplicateImports] list. | 13118 * in the [duplicateImports] list. |
| 13089 * | 13119 * |
| 13090 * @param errorReporter the error reporter to report the set of [HintCode#DUPL
ICATE_IMPORT] | 13120 * @param errorReporter the error reporter to report the set of [HintCode#DUPL
ICATE_IMPORT] |
| 13091 * hints to | 13121 * hints to |
| 13092 */ | 13122 */ |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13130 _unusedImports.add(importDirective); | 13160 _unusedImports.add(importDirective); |
| 13131 // | 13161 // |
| 13132 // Initialize prefixElementMap | 13162 // Initialize prefixElementMap |
| 13133 // | 13163 // |
| 13134 if (importDirective.asToken != null) { | 13164 if (importDirective.asToken != null) { |
| 13135 SimpleIdentifier prefixIdentifier = importDirective.prefix; | 13165 SimpleIdentifier prefixIdentifier = importDirective.prefix; |
| 13136 if (prefixIdentifier != null) { | 13166 if (prefixIdentifier != null) { |
| 13137 Element element = prefixIdentifier.staticElement; | 13167 Element element = prefixIdentifier.staticElement; |
| 13138 if (element is PrefixElement) { | 13168 if (element is PrefixElement) { |
| 13139 PrefixElement prefixElementKey = element; | 13169 PrefixElement prefixElementKey = element; |
| 13140 _prefixElementMap[prefixElementKey] = importDirective; | 13170 List<ImportDirective> list = _prefixElementMap[prefixElementKe
y]; |
| 13171 if (list == null) { |
| 13172 list = new List<ImportDirective>(); |
| 13173 _prefixElementMap[prefixElementKey] = list; |
| 13174 } |
| 13175 list.add(importDirective); |
| 13141 } | 13176 } |
| 13142 } | 13177 } |
| 13143 } | 13178 } |
| 13144 // | 13179 // |
| 13145 // Initialize libraryMap: libraryElement -> importDirective | 13180 // Initialize libraryMap: libraryElement -> importDirective |
| 13146 // | 13181 // |
| 13147 _putIntoLibraryMap(libraryElement, importDirective); | 13182 _putIntoLibraryMap(libraryElement, importDirective); |
| 13148 // | 13183 // |
| 13149 // For this new addition to the libraryMap, also recursively add any
exports from the | 13184 // For this new addition to the libraryMap, also recursively add any
exports from the |
| 13150 // libraryElement | 13185 // libraryElement |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13203 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 13238 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 13204 if (_unusedImports.isEmpty) { | 13239 if (_unusedImports.isEmpty) { |
| 13205 return null; | 13240 return null; |
| 13206 } | 13241 } |
| 13207 // If the prefixed identifier references some A.B, where A is a library pref
ix, then we can | 13242 // If the prefixed identifier references some A.B, where A is a library pref
ix, then we can |
| 13208 // lookup the associated ImportDirective in prefixElementMap and remove it f
rom the | 13243 // lookup the associated ImportDirective in prefixElementMap and remove it f
rom the |
| 13209 // unusedImports list. | 13244 // unusedImports list. |
| 13210 SimpleIdentifier prefixIdentifier = node.prefix; | 13245 SimpleIdentifier prefixIdentifier = node.prefix; |
| 13211 Element element = prefixIdentifier.staticElement; | 13246 Element element = prefixIdentifier.staticElement; |
| 13212 if (element is PrefixElement) { | 13247 if (element is PrefixElement) { |
| 13213 _unusedImports.remove(_prefixElementMap[element]); | 13248 List<ImportDirective> importDirectives = _prefixElementMap[element]; |
| 13249 for (ImportDirective importDirective in importDirectives) { |
| 13250 _unusedImports.remove(importDirective); |
| 13251 } |
| 13214 return null; | 13252 return null; |
| 13215 } | 13253 } |
| 13216 // Otherwise, pass the prefixed identifier element and name onto visitIdenti
fier. | 13254 // Otherwise, pass the prefixed identifier element and name onto visitIdenti
fier. |
| 13217 return _visitIdentifier(element, prefixIdentifier.name); | 13255 return _visitIdentifier(element, prefixIdentifier.name); |
| 13218 } | 13256 } |
| 13219 | 13257 |
| 13220 @override | 13258 @override |
| 13221 Object visitSimpleIdentifier(SimpleIdentifier node) { | 13259 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 13222 if (_unusedImports.isEmpty) { | 13260 if (_unusedImports.isEmpty) { |
| 13223 return null; | 13261 return null; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13285 return null; | 13323 return null; |
| 13286 } | 13324 } |
| 13287 // If the element is multiply defined then call this method recursively for
each of the conflicting elements. | 13325 // If the element is multiply defined then call this method recursively for
each of the conflicting elements. |
| 13288 if (element is MultiplyDefinedElement) { | 13326 if (element is MultiplyDefinedElement) { |
| 13289 MultiplyDefinedElement multiplyDefinedElement = element; | 13327 MultiplyDefinedElement multiplyDefinedElement = element; |
| 13290 for (Element elt in multiplyDefinedElement.conflictingElements) { | 13328 for (Element elt in multiplyDefinedElement.conflictingElements) { |
| 13291 _visitIdentifier(elt, name); | 13329 _visitIdentifier(elt, name); |
| 13292 } | 13330 } |
| 13293 return null; | 13331 return null; |
| 13294 } else if (element is PrefixElement) { | 13332 } else if (element is PrefixElement) { |
| 13295 _unusedImports.remove(_prefixElementMap[element]); | 13333 List<ImportDirective> importDirectives = _prefixElementMap[element]; |
| 13334 for (ImportDirective importDirective in importDirectives) { |
| 13335 _unusedImports.remove(importDirective); |
| 13336 } |
| 13296 return null; | 13337 return null; |
| 13297 } else if (element.enclosingElement is! CompilationUnitElement) { | 13338 } else if (element.enclosingElement is! CompilationUnitElement) { |
| 13298 // Identifiers that aren't a prefix element and whose enclosing element is
n't a | 13339 // Identifiers that aren't a prefix element and whose enclosing element is
n't a |
| 13299 // CompilationUnit are ignored- this covers the case the identifier is a r
elative-reference, | 13340 // CompilationUnit are ignored- this covers the case the identifier is a r
elative-reference, |
| 13300 // a reference to an identifier not imported by this library. | 13341 // a reference to an identifier not imported by this library. |
| 13301 return null; | 13342 return null; |
| 13302 } | 13343 } |
| 13303 LibraryElement containingLibrary = element.library; | 13344 LibraryElement containingLibrary = element.library; |
| 13304 if (containingLibrary == null) { | 13345 if (containingLibrary == null) { |
| 13305 return null; | 13346 return null; |
| (...skipping 1763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15069 foundElement = MultiplyDefinedElementImpl.fromElements(_definingLibrar
y.context, foundElement, element); | 15110 foundElement = MultiplyDefinedElementImpl.fromElements(_definingLibrar
y.context, foundElement, element); |
| 15070 } | 15111 } |
| 15071 } | 15112 } |
| 15072 } | 15113 } |
| 15073 if (foundElement is MultiplyDefinedElementImpl) { | 15114 if (foundElement is MultiplyDefinedElementImpl) { |
| 15074 foundElement = _removeSdkElements(identifier, name, foundElement as Multip
lyDefinedElementImpl); | 15115 foundElement = _removeSdkElements(identifier, name, foundElement as Multip
lyDefinedElementImpl); |
| 15075 } | 15116 } |
| 15076 if (foundElement is MultiplyDefinedElementImpl) { | 15117 if (foundElement is MultiplyDefinedElementImpl) { |
| 15077 String foundEltName = foundElement.displayName; | 15118 String foundEltName = foundElement.displayName; |
| 15078 List<Element> conflictingMembers = (foundElement as MultiplyDefinedElement
Impl).conflictingElements; | 15119 List<Element> conflictingMembers = (foundElement as MultiplyDefinedElement
Impl).conflictingElements; |
| 15079 String libName1 = _getLibraryName(conflictingMembers[0], ""); | 15120 int count = conflictingMembers.length; |
| 15080 String libName2 = _getLibraryName(conflictingMembers[1], ""); | 15121 List<String> libraryNames = new List<String>(count); |
| 15081 // TODO (jwren) Change the error message to include a list of all library
names instead of | 15122 for (int i = 0; i < count; i++) { |
| 15082 // just the first two | 15123 libraryNames[i] = _getLibraryName(conflictingMembers[i], ""); |
| 15083 errorListener.onError(new AnalysisError.con2(getSource(identifier), identi
fier.offset, identifier.length, StaticWarningCode.AMBIGUOUS_IMPORT, [foundEltNam
e, libName1, libName2])); | 15124 } |
| 15125 libraryNames.sort(); |
| 15126 errorListener.onError(new AnalysisError.con2(getSource(identifier), identi
fier.offset, identifier.length, StaticWarningCode.AMBIGUOUS_IMPORT, [ |
| 15127 foundEltName, |
| 15128 StringUtilities.printListOfQuotedNames(libraryNames)])); |
| 15084 return foundElement; | 15129 return foundElement; |
| 15085 } | 15130 } |
| 15086 if (foundElement != null) { | 15131 if (foundElement != null) { |
| 15087 defineNameWithoutChecking(name, foundElement); | 15132 defineNameWithoutChecking(name, foundElement); |
| 15088 } | 15133 } |
| 15089 return foundElement; | 15134 return foundElement; |
| 15090 } | 15135 } |
| 15091 | 15136 |
| 15092 /** | 15137 /** |
| 15093 * Create all of the namespaces associated with the libraries imported into th
is library. The | 15138 * Create all of the namespaces associated with the libraries imported into th
is library. The |
| (...skipping 2613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17707 */ | 17752 */ |
| 17708 ClassElement _enclosingClass = null; | 17753 ClassElement _enclosingClass = null; |
| 17709 | 17754 |
| 17710 /** | 17755 /** |
| 17711 * The class declaration representing the class containing the current node, o
r `null` if | 17756 * The class declaration representing the class containing the current node, o
r `null` if |
| 17712 * the current node is not contained in a class. | 17757 * the current node is not contained in a class. |
| 17713 */ | 17758 */ |
| 17714 ClassDeclaration _enclosingClassDeclaration = null; | 17759 ClassDeclaration _enclosingClassDeclaration = null; |
| 17715 | 17760 |
| 17716 /** | 17761 /** |
| 17762 * The function type alias representing the function type containing the curre
nt node, or |
| 17763 * `null` if the current node is not contained in a function type alias. |
| 17764 */ |
| 17765 FunctionTypeAlias _enclosingFunctionTypeAlias = null; |
| 17766 |
| 17767 /** |
| 17717 * The element representing the function containing the current node, or `null
` if the | 17768 * The element representing the function containing the current node, or `null
` if the |
| 17718 * current node is not contained in a function. | 17769 * current node is not contained in a function. |
| 17719 */ | 17770 */ |
| 17720 ExecutableElement _enclosingFunction = null; | 17771 ExecutableElement _enclosingFunction = null; |
| 17721 | 17772 |
| 17722 /** | 17773 /** |
| 17723 * The [Comment] before a [FunctionDeclaration] or a [MethodDeclaration] that | 17774 * The [Comment] before a [FunctionDeclaration] or a [MethodDeclaration] that |
| 17724 * cannot be resolved where we visited it, because it should be resolved in th
e scope of the body. | 17775 * cannot be resolved where we visited it, because it should be resolved in th
e scope of the body. |
| 17725 */ | 17776 */ |
| 17726 Comment _commentBeforeFunction = null; | 17777 Comment _commentBeforeFunction = null; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17802 | 17853 |
| 17803 /** | 17854 /** |
| 17804 * Return the object keeping track of which elements have had their types prom
oted. | 17855 * Return the object keeping track of which elements have had their types prom
oted. |
| 17805 * | 17856 * |
| 17806 * @return the object keeping track of which elements have had their types pro
moted | 17857 * @return the object keeping track of which elements have had their types pro
moted |
| 17807 */ | 17858 */ |
| 17808 TypePromotionManager get promoteManager => _promoteManager; | 17859 TypePromotionManager get promoteManager => _promoteManager; |
| 17809 | 17860 |
| 17810 @override | 17861 @override |
| 17811 Object visitAnnotation(Annotation node) { | 17862 Object visitAnnotation(Annotation node) { |
| 17812 if (identical(node.parent, _enclosingClassDeclaration)) { | 17863 AstNode parent = node.parent; |
| 17864 if (identical(parent, _enclosingClassDeclaration) || identical(parent, _encl
osingFunctionTypeAlias)) { |
| 17813 return null; | 17865 return null; |
| 17814 } | 17866 } |
| 17815 return super.visitAnnotation(node); | 17867 return super.visitAnnotation(node); |
| 17816 } | 17868 } |
| 17817 | 17869 |
| 17818 @override | 17870 @override |
| 17819 Object visitAsExpression(AsExpression node) { | 17871 Object visitAsExpression(AsExpression node) { |
| 17820 super.visitAsExpression(node); | 17872 super.visitAsExpression(node); |
| 17821 overrideExpression(node.expression, node.type.type); | 17873 overrideExpression(node.expression, node.type.type); |
| 17822 return null; | 17874 return null; |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18174 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 18226 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| 18175 safelyVisit(node.function); | 18227 safelyVisit(node.function); |
| 18176 node.accept(_elementResolver); | 18228 node.accept(_elementResolver); |
| 18177 _inferFunctionExpressionsParametersTypes(node.argumentList); | 18229 _inferFunctionExpressionsParametersTypes(node.argumentList); |
| 18178 safelyVisit(node.argumentList); | 18230 safelyVisit(node.argumentList); |
| 18179 node.accept(_typeAnalyzer); | 18231 node.accept(_typeAnalyzer); |
| 18180 return null; | 18232 return null; |
| 18181 } | 18233 } |
| 18182 | 18234 |
| 18183 @override | 18235 @override |
| 18236 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 18237 // Resolve the metadata in the library scope. |
| 18238 if (node.metadata != null) { |
| 18239 node.metadata.accept(this); |
| 18240 } |
| 18241 FunctionTypeAlias outerAlias = _enclosingFunctionTypeAlias; |
| 18242 _enclosingFunctionTypeAlias = node; |
| 18243 try { |
| 18244 super.visitFunctionTypeAlias(node); |
| 18245 } finally { |
| 18246 _enclosingFunctionTypeAlias = outerAlias; |
| 18247 } |
| 18248 return null; |
| 18249 } |
| 18250 |
| 18251 @override |
| 18184 Object visitHideCombinator(HideCombinator node) => null; | 18252 Object visitHideCombinator(HideCombinator node) => null; |
| 18185 | 18253 |
| 18186 @override | 18254 @override |
| 18187 Object visitIfStatement(IfStatement node) { | 18255 Object visitIfStatement(IfStatement node) { |
| 18188 Expression condition = node.condition; | 18256 Expression condition = node.condition; |
| 18189 safelyVisit(condition); | 18257 safelyVisit(condition); |
| 18190 Map<Element, DartType> thenOverrides = null; | 18258 Map<Element, DartType> thenOverrides = null; |
| 18191 Statement thenStatement = node.thenStatement; | 18259 Statement thenStatement = node.thenStatement; |
| 18192 if (thenStatement != null) { | 18260 if (thenStatement != null) { |
| 18193 _overrideManager.enterScope(); | 18261 _overrideManager.enterScope(); |
| (...skipping 2321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20515 } | 20583 } |
| 20516 } | 20584 } |
| 20517 // Record static return type of the static element. | 20585 // Record static return type of the static element. |
| 20518 DartType staticStaticType = _computeStaticReturnType(staticMethodElement); | 20586 DartType staticStaticType = _computeStaticReturnType(staticMethodElement); |
| 20519 _recordStaticType(node, staticStaticType); | 20587 _recordStaticType(node, staticStaticType); |
| 20520 // Record propagated return type of the static element. | 20588 // Record propagated return type of the static element. |
| 20521 DartType staticPropagatedType = _computePropagatedReturnType(staticMethodEle
ment); | 20589 DartType staticPropagatedType = _computePropagatedReturnType(staticMethodEle
ment); |
| 20522 if (staticPropagatedType != null && (staticStaticType == null || staticPropa
gatedType.isMoreSpecificThan(staticStaticType))) { | 20590 if (staticPropagatedType != null && (staticStaticType == null || staticPropa
gatedType.isMoreSpecificThan(staticStaticType))) { |
| 20523 _recordPropagatedType(node, staticPropagatedType); | 20591 _recordPropagatedType(node, staticPropagatedType); |
| 20524 } | 20592 } |
| 20593 bool needPropagatedType = true; |
| 20525 String methodName = methodNameNode.name; | 20594 String methodName = methodNameNode.name; |
| 20526 // Future.then(closure) return type is: | |
| 20527 // 1) the returned Future type, if the closure returns a Future; | |
| 20528 // 2) Future<valueType>, if the closure returns a value. | |
| 20529 if (methodName == "then") { | 20595 if (methodName == "then") { |
| 20530 Expression target = node.realTarget; | 20596 Expression target = node.realTarget; |
| 20531 DartType targetType = target == null ? null : target.bestType; | 20597 if (target != null) { |
| 20532 if (_isAsyncFutureType(targetType)) { | 20598 DartType targetType = target.bestType; |
| 20533 NodeList<Expression> arguments = node.argumentList.arguments; | 20599 if (_isAsyncFutureType(targetType)) { |
| 20534 if (arguments.length == 1) { | 20600 // Future.then(closure) return type is: |
| 20535 // TODO(brianwilkerson) Handle the case where both arguments are provi
ded. | 20601 // 1) the returned Future type, if the closure returns a Future; |
| 20536 Expression closureArg = arguments[0]; | 20602 // 2) Future<valueType>, if the closure returns a value. |
| 20537 if (closureArg is FunctionExpression) { | 20603 NodeList<Expression> arguments = node.argumentList.arguments; |
| 20538 FunctionExpression closureExpr = closureArg; | 20604 if (arguments.length == 1) { |
| 20539 DartType returnType = _computePropagatedReturnType(closureExpr.eleme
nt); | 20605 // TODO(brianwilkerson) Handle the case where both arguments are pro
vided. |
| 20540 if (returnType != null) { | 20606 Expression closureArg = arguments[0]; |
| 20541 // prepare the type of the returned Future | 20607 if (closureArg is FunctionExpression) { |
| 20542 InterfaceTypeImpl newFutureType; | 20608 FunctionExpression closureExpr = closureArg; |
| 20543 if (_isAsyncFutureType(returnType)) { | 20609 DartType returnType = _computePropagatedReturnType(closureExpr.ele
ment); |
| 20544 newFutureType = returnType as InterfaceTypeImpl; | 20610 if (returnType != null) { |
| 20545 } else { | 20611 // prepare the type of the returned Future |
| 20546 InterfaceType futureType = targetType as InterfaceType; | 20612 InterfaceTypeImpl newFutureType; |
| 20547 newFutureType = new InterfaceTypeImpl.con1(futureType.element); | 20613 if (_isAsyncFutureType(returnType)) { |
| 20548 newFutureType.typeArguments = <DartType> [returnType]; | 20614 newFutureType = returnType as InterfaceTypeImpl; |
| 20615 } else { |
| 20616 InterfaceType futureType = targetType as InterfaceType; |
| 20617 newFutureType = new InterfaceTypeImpl.con1(futureType.element)
; |
| 20618 newFutureType.typeArguments = <DartType> [returnType]; |
| 20619 } |
| 20620 // set the 'then' invocation type |
| 20621 _recordPropagatedType(node, newFutureType); |
| 20622 needPropagatedType = false; |
| 20623 return null; |
| 20549 } | 20624 } |
| 20550 // set the 'then' invocation type | |
| 20551 _recordPropagatedType(node, newFutureType); | |
| 20552 return null; | |
| 20553 } | 20625 } |
| 20554 } | 20626 } |
| 20555 } | 20627 } |
| 20556 } | 20628 } |
| 20557 } | 20629 } else if (methodName == "\$dom_createEvent") { |
| 20558 if (methodName == "\$dom_createEvent") { | |
| 20559 Expression target = node.realTarget; | 20630 Expression target = node.realTarget; |
| 20560 if (target != null) { | 20631 if (target != null) { |
| 20561 DartType targetType = target.bestType; | 20632 DartType targetType = target.bestType; |
| 20562 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" ||
targetType.name == "Document")) { | 20633 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" ||
targetType.name == "Document")) { |
| 20563 LibraryElement library = targetType.element.library; | 20634 LibraryElement library = targetType.element.library; |
| 20564 if (_isHtmlLibrary(library)) { | 20635 if (_isHtmlLibrary(library)) { |
| 20565 DartType returnType = _getFirstArgumentAsType(library, node.argument
List); | 20636 DartType returnType = _getFirstArgumentAsType(library, node.argument
List); |
| 20566 if (returnType != null) { | 20637 if (returnType != null) { |
| 20567 _recordPropagatedType(node, returnType); | 20638 _recordPropagatedType(node, returnType); |
| 20639 needPropagatedType = false; |
| 20568 } | 20640 } |
| 20569 } | 20641 } |
| 20570 } | 20642 } |
| 20571 } | 20643 } |
| 20572 } else if (methodName == "query") { | 20644 } else if (methodName == "query") { |
| 20573 Expression target = node.realTarget; | 20645 Expression target = node.realTarget; |
| 20574 if (target == null) { | 20646 if (target == null) { |
| 20575 Element methodElement = methodNameNode.bestElement; | 20647 Element methodElement = methodNameNode.bestElement; |
| 20576 if (methodElement != null) { | 20648 if (methodElement != null) { |
| 20577 LibraryElement library = methodElement.library; | 20649 LibraryElement library = methodElement.library; |
| 20578 if (_isHtmlLibrary(library)) { | 20650 if (_isHtmlLibrary(library)) { |
| 20579 DartType returnType = _getFirstArgumentAsQuery(library, node.argumen
tList); | 20651 DartType returnType = _getFirstArgumentAsQuery(library, node.argumen
tList); |
| 20580 if (returnType != null) { | 20652 if (returnType != null) { |
| 20581 _recordPropagatedType(node, returnType); | 20653 _recordPropagatedType(node, returnType); |
| 20654 needPropagatedType = false; |
| 20582 } | 20655 } |
| 20583 } | 20656 } |
| 20584 } | 20657 } |
| 20585 } else { | 20658 } else { |
| 20586 DartType targetType = target.bestType; | 20659 DartType targetType = target.bestType; |
| 20587 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" ||
targetType.name == "Document")) { | 20660 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" ||
targetType.name == "Document")) { |
| 20588 LibraryElement library = targetType.element.library; | 20661 LibraryElement library = targetType.element.library; |
| 20589 if (_isHtmlLibrary(library)) { | 20662 if (_isHtmlLibrary(library)) { |
| 20590 DartType returnType = _getFirstArgumentAsQuery(library, node.argumen
tList); | 20663 DartType returnType = _getFirstArgumentAsQuery(library, node.argumen
tList); |
| 20591 if (returnType != null) { | 20664 if (returnType != null) { |
| 20592 _recordPropagatedType(node, returnType); | 20665 _recordPropagatedType(node, returnType); |
| 20666 needPropagatedType = false; |
| 20593 } | 20667 } |
| 20594 } | 20668 } |
| 20595 } | 20669 } |
| 20596 } | 20670 } |
| 20597 } else if (methodName == "\$dom_createElement") { | 20671 } else if (methodName == "\$dom_createElement") { |
| 20598 Expression target = node.realTarget; | 20672 Expression target = node.realTarget; |
| 20599 DartType targetType = target.bestType; | 20673 if (target != null) { |
| 20600 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || t
argetType.name == "Document")) { | 20674 DartType targetType = target.bestType; |
| 20601 LibraryElement library = targetType.element.library; | 20675 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" ||
targetType.name == "Document")) { |
| 20602 if (_isHtmlLibrary(library)) { | 20676 LibraryElement library = targetType.element.library; |
| 20603 DartType returnType = _getFirstArgumentAsQuery(library, node.argumentL
ist); | 20677 if (_isHtmlLibrary(library)) { |
| 20604 if (returnType != null) { | 20678 DartType returnType = _getFirstArgumentAsQuery(library, node.argumen
tList); |
| 20605 _recordPropagatedType(node, returnType); | 20679 if (returnType != null) { |
| 20680 _recordPropagatedType(node, returnType); |
| 20681 needPropagatedType = false; |
| 20682 } |
| 20606 } | 20683 } |
| 20607 } | 20684 } |
| 20608 } | 20685 } |
| 20609 } else if (methodName == "JS") { | 20686 } else if (methodName == "JS") { |
| 20610 DartType returnType = _getFirstArgumentAsType(_typeProvider.objectType.ele
ment.library, node.argumentList); | 20687 DartType returnType = _getFirstArgumentAsType(_typeProvider.objectType.ele
ment.library, node.argumentList); |
| 20611 if (returnType != null) { | 20688 if (returnType != null) { |
| 20612 _recordPropagatedType(node, returnType); | 20689 _recordPropagatedType(node, returnType); |
| 20690 needPropagatedType = false; |
| 20613 } | 20691 } |
| 20614 } else { | 20692 } else if (methodName == "getContext") { |
| 20693 Expression target = node.realTarget; |
| 20694 if (target != null) { |
| 20695 DartType targetType = target.bestType; |
| 20696 if (targetType is InterfaceType && (targetType.name == "CanvasElement"))
{ |
| 20697 NodeList<Expression> arguments = node.argumentList.arguments; |
| 20698 if (arguments.length == 1) { |
| 20699 Expression argument = arguments[0]; |
| 20700 if (argument is StringLiteral) { |
| 20701 String value = argument.stringValue; |
| 20702 if ("2d" == value) { |
| 20703 PropertyAccessorElement getter = targetType.element.getGetter("c
ontext2D"); |
| 20704 if (getter != null) { |
| 20705 DartType returnType = getter.returnType; |
| 20706 if (returnType != null) { |
| 20707 _recordPropagatedType(node, returnType); |
| 20708 needPropagatedType = false; |
| 20709 } |
| 20710 } |
| 20711 } |
| 20712 } |
| 20713 } |
| 20714 } |
| 20715 } |
| 20716 } |
| 20717 if (needPropagatedType) { |
| 20615 Element propagatedElement = methodNameNode.propagatedElement; | 20718 Element propagatedElement = methodNameNode.propagatedElement; |
| 20616 if (!identical(propagatedElement, staticMethodElement)) { | 20719 if (!identical(propagatedElement, staticMethodElement)) { |
| 20617 // Record static return type of the propagated element. | 20720 // Record static return type of the propagated element. |
| 20618 DartType propagatedStaticType = _computeStaticReturnType(propagatedEleme
nt); | 20721 DartType propagatedStaticType = _computeStaticReturnType(propagatedEleme
nt); |
| 20619 if (propagatedStaticType != null && (staticStaticType == null || propaga
tedStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType ==
null || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) { | 20722 if (propagatedStaticType != null && (staticStaticType == null || propaga
tedStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType ==
null || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) { |
| 20620 _recordPropagatedType(node, propagatedStaticType); | 20723 _recordPropagatedType(node, propagatedStaticType); |
| 20621 } | 20724 } |
| 20622 // Record propagated return type of the propagated element. | 20725 // Record propagated return type of the propagated element. |
| 20623 DartType propagatedPropagatedType = _computePropagatedReturnType(propaga
tedElement); | 20726 DartType propagatedPropagatedType = _computePropagatedReturnType(propaga
tedElement); |
| 20624 if (propagatedPropagatedType != null && (staticStaticType == null || pro
pagatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagated
Type == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType
)) && (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificTh
an(propagatedStaticType))) { | 20727 if (propagatedPropagatedType != null && (staticStaticType == null || pro
pagatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagated
Type == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType
)) && (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificTh
an(propagatedStaticType))) { |
| (...skipping 2935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 23560 parameterImpl.markPotentiallyMutatedInScope(); | 23663 parameterImpl.markPotentiallyMutatedInScope(); |
| 23561 // If we are in some closure, check if it is not the same as where varia
ble is declared. | 23664 // If we are in some closure, check if it is not the same as where varia
ble is declared. |
| 23562 if (_enclosingFunction != null && (element.enclosingElement != _enclosin
gFunction)) { | 23665 if (_enclosingFunction != null && (element.enclosingElement != _enclosin
gFunction)) { |
| 23563 parameterImpl.markPotentiallyMutatedInClosure(); | 23666 parameterImpl.markPotentiallyMutatedInClosure(); |
| 23564 } | 23667 } |
| 23565 } | 23668 } |
| 23566 } | 23669 } |
| 23567 return null; | 23670 return null; |
| 23568 } | 23671 } |
| 23569 } | 23672 } |
| OLD | NEW |