| 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 library analyzer.src.generated.resolver; | 5 library analyzer.src.generated.resolver; |
| 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/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 * @param element some element to check for deprecated use of | 514 * @param element some element to check for deprecated use of |
| 515 * @param node the node use for the location of the error | 515 * @param node the node use for the location of the error |
| 516 * @return `true` if and only if a hint code is generated on the passed node | 516 * @return `true` if and only if a hint code is generated on the passed node |
| 517 * See [HintCode.DEPRECATED_MEMBER_USE]. | 517 * See [HintCode.DEPRECATED_MEMBER_USE]. |
| 518 */ | 518 */ |
| 519 void _checkForDeprecatedMemberUse(Element element, AstNode node) { | 519 void _checkForDeprecatedMemberUse(Element element, AstNode node) { |
| 520 bool isDeprecated(Element element) { | 520 bool isDeprecated(Element element) { |
| 521 if (element == null) { | 521 if (element == null) { |
| 522 return false; | 522 return false; |
| 523 } else if (element is PropertyAccessorElement && element.isSynthetic) { | 523 } else if (element is PropertyAccessorElement && element.isSynthetic) { |
| 524 element = (element as PropertyAccessorElement).variable; | 524 // TODO(brianwilkerson) Why isn't this the implementation for PropertyAc
cessorElement? |
| 525 if (element == null) { | 525 Element variable = element.variable; |
| 526 if (variable == null) { |
| 526 return false; | 527 return false; |
| 527 } | 528 } |
| 529 return variable.isDeprecated; |
| 528 } | 530 } |
| 529 return element.isDeprecated; | 531 return element.isDeprecated; |
| 530 } | 532 } |
| 531 if (!inDeprecatedMember && isDeprecated(element)) { | 533 if (!inDeprecatedMember && isDeprecated(element)) { |
| 532 String displayName = element.displayName; | 534 String displayName = element.displayName; |
| 533 if (element is ConstructorElement) { | 535 if (element is ConstructorElement) { |
| 534 // TODO(jwren) We should modify ConstructorElement.getDisplayName(), | 536 // TODO(jwren) We should modify ConstructorElement.getDisplayName(), |
| 535 // or have the logic centralized elsewhere, instead of doing this logic | 537 // or have the logic centralized elsewhere, instead of doing this logic |
| 536 // here. | 538 // here. |
| 537 ConstructorElement constructorElement = element; | 539 displayName = element.enclosingElement.displayName; |
| 538 displayName = constructorElement.enclosingElement.displayName; | 540 if (!element.displayName.isEmpty) { |
| 539 if (!constructorElement.displayName.isEmpty) { | 541 displayName = "$displayName.${element.displayName}"; |
| 540 displayName = "$displayName.${constructorElement.displayName}"; | |
| 541 } | 542 } |
| 542 } | 543 } |
| 543 _errorReporter.reportErrorForNode( | 544 _errorReporter.reportErrorForNode( |
| 544 HintCode.DEPRECATED_MEMBER_USE, node, [displayName]); | 545 HintCode.DEPRECATED_MEMBER_USE, node, [displayName]); |
| 545 } | 546 } |
| 546 } | 547 } |
| 547 | 548 |
| 548 /** | 549 /** |
| 549 * For [SimpleIdentifier]s, only call [checkForDeprecatedMemberUse] | 550 * For [SimpleIdentifier]s, only call [checkForDeprecatedMemberUse] |
| 550 * if the node is not in a declaration context. | 551 * if the node is not in a declaration context. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 // its static or propagated type | 592 // its static or propagated type |
| 592 MethodElement methodElement = node.bestElement; | 593 MethodElement methodElement = node.bestElement; |
| 593 if (methodElement == null) { | 594 if (methodElement == null) { |
| 594 return false; | 595 return false; |
| 595 } | 596 } |
| 596 LibraryElement libraryElement = methodElement.library; | 597 LibraryElement libraryElement = methodElement.library; |
| 597 if (libraryElement != null && !libraryElement.isDartCore) { | 598 if (libraryElement != null && !libraryElement.isDartCore) { |
| 598 return false; | 599 return false; |
| 599 } | 600 } |
| 600 // Report error if the (x/y) has toInt() invoked on it | 601 // Report error if the (x/y) has toInt() invoked on it |
| 601 if (node.parent is ParenthesizedExpression) { | 602 AstNode parent = node.parent; |
| 603 if (parent is ParenthesizedExpression) { |
| 602 ParenthesizedExpression parenthesizedExpression = | 604 ParenthesizedExpression parenthesizedExpression = |
| 603 _wrapParenthesizedExpression(node.parent as ParenthesizedExpression); | 605 _wrapParenthesizedExpression(parent); |
| 604 if (parenthesizedExpression.parent is MethodInvocation) { | 606 AstNode grandParent = parenthesizedExpression.parent; |
| 605 MethodInvocation methodInvocation = | 607 if (grandParent is MethodInvocation) { |
| 606 parenthesizedExpression.parent as MethodInvocation; | 608 if (_TO_INT_METHOD_NAME == grandParent.methodName.name && |
| 607 if (_TO_INT_METHOD_NAME == methodInvocation.methodName.name && | 609 grandParent.argumentList.arguments.isEmpty) { |
| 608 methodInvocation.argumentList.arguments.isEmpty) { | |
| 609 _errorReporter.reportErrorForNode( | 610 _errorReporter.reportErrorForNode( |
| 610 HintCode.DIVISION_OPTIMIZATION, methodInvocation); | 611 HintCode.DIVISION_OPTIMIZATION, grandParent); |
| 611 return true; | 612 return true; |
| 612 } | 613 } |
| 613 } | 614 } |
| 614 } | 615 } |
| 615 return false; | 616 return false; |
| 616 } | 617 } |
| 617 | 618 |
| 618 /** | 619 /** |
| 619 * This verifies that the passed left hand side and right hand side represent
a valid assignment. | 620 * This verifies that the passed left hand side and right hand side represent
a valid assignment. |
| 620 * | 621 * |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1022 * expression. | 1023 * expression. |
| 1023 * | 1024 * |
| 1024 * For example given the code `(((e)))`: `(e) -> (((e)))`. | 1025 * For example given the code `(((e)))`: `(e) -> (((e)))`. |
| 1025 * | 1026 * |
| 1026 * @param parenthesizedExpression some expression whose parent is a parenthesi
zed expression | 1027 * @param parenthesizedExpression some expression whose parent is a parenthesi
zed expression |
| 1027 * @return the first parent or grand-parent that is a parenthesized expression
, that does not have | 1028 * @return the first parent or grand-parent that is a parenthesized expression
, that does not have |
| 1028 * a parenthesized expression parent | 1029 * a parenthesized expression parent |
| 1029 */ | 1030 */ |
| 1030 static ParenthesizedExpression _wrapParenthesizedExpression( | 1031 static ParenthesizedExpression _wrapParenthesizedExpression( |
| 1031 ParenthesizedExpression parenthesizedExpression) { | 1032 ParenthesizedExpression parenthesizedExpression) { |
| 1032 if (parenthesizedExpression.parent is ParenthesizedExpression) { | 1033 AstNode parent = parenthesizedExpression.parent; |
| 1033 return _wrapParenthesizedExpression( | 1034 if (parent is ParenthesizedExpression) { |
| 1034 parenthesizedExpression.parent as ParenthesizedExpression); | 1035 return _wrapParenthesizedExpression(parent); |
| 1035 } | 1036 } |
| 1036 return parenthesizedExpression; | 1037 return parenthesizedExpression; |
| 1037 } | 1038 } |
| 1038 } | 1039 } |
| 1039 | 1040 |
| 1040 /** | 1041 /** |
| 1041 * Utilities for [LibraryElementImpl] building. | 1042 * Utilities for [LibraryElementImpl] building. |
| 1042 */ | 1043 */ |
| 1043 class BuildLibraryElementUtils { | 1044 class BuildLibraryElementUtils { |
| 1044 /** | 1045 /** |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1159 this._numType = _typeProvider.numType; | 1160 this._numType = _typeProvider.numType; |
| 1160 this._stringType = _typeProvider.stringType; | 1161 this._stringType = _typeProvider.stringType; |
| 1161 } | 1162 } |
| 1162 | 1163 |
| 1163 @override | 1164 @override |
| 1164 Object visitAnnotation(Annotation node) { | 1165 Object visitAnnotation(Annotation node) { |
| 1165 super.visitAnnotation(node); | 1166 super.visitAnnotation(node); |
| 1166 // check annotation creation | 1167 // check annotation creation |
| 1167 Element element = node.element; | 1168 Element element = node.element; |
| 1168 if (element is ConstructorElement) { | 1169 if (element is ConstructorElement) { |
| 1169 ConstructorElement constructorElement = element; | 1170 // should be 'const' constructor |
| 1170 // should 'const' constructor | 1171 if (!element.isConst) { |
| 1171 if (!constructorElement.isConst) { | |
| 1172 _errorReporter.reportErrorForNode( | 1172 _errorReporter.reportErrorForNode( |
| 1173 CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR, node); | 1173 CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR, node); |
| 1174 return null; | 1174 return null; |
| 1175 } | 1175 } |
| 1176 // should have arguments | 1176 // should have arguments |
| 1177 ArgumentList argumentList = node.arguments; | 1177 ArgumentList argumentList = node.arguments; |
| 1178 if (argumentList == null) { | 1178 if (argumentList == null) { |
| 1179 _errorReporter.reportErrorForNode( | 1179 _errorReporter.reportErrorForNode( |
| 1180 CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS, node); | 1180 CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS, node); |
| 1181 return null; | 1181 return null; |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1324 @override | 1324 @override |
| 1325 Object visitSwitchStatement(SwitchStatement node) { | 1325 Object visitSwitchStatement(SwitchStatement node) { |
| 1326 // TODO(paulberry): to minimize error messages, it would be nice to | 1326 // TODO(paulberry): to minimize error messages, it would be nice to |
| 1327 // compare all types with the most popular type rather than the first | 1327 // compare all types with the most popular type rather than the first |
| 1328 // type. | 1328 // type. |
| 1329 NodeList<SwitchMember> switchMembers = node.members; | 1329 NodeList<SwitchMember> switchMembers = node.members; |
| 1330 bool foundError = false; | 1330 bool foundError = false; |
| 1331 DartType firstType = null; | 1331 DartType firstType = null; |
| 1332 for (SwitchMember switchMember in switchMembers) { | 1332 for (SwitchMember switchMember in switchMembers) { |
| 1333 if (switchMember is SwitchCase) { | 1333 if (switchMember is SwitchCase) { |
| 1334 SwitchCase switchCase = switchMember; | 1334 Expression expression = switchMember.expression; |
| 1335 Expression expression = switchCase.expression; | |
| 1336 DartObjectImpl caseResult = _validate( | 1335 DartObjectImpl caseResult = _validate( |
| 1337 expression, CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION); | 1336 expression, CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION); |
| 1338 if (caseResult != null) { | 1337 if (caseResult != null) { |
| 1339 _reportErrorIfFromDeferredLibrary( | 1338 _reportErrorIfFromDeferredLibrary( |
| 1340 expression, | 1339 expression, |
| 1341 CompileTimeErrorCode | 1340 CompileTimeErrorCode |
| 1342 .NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY); | 1341 .NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY); |
| 1343 DartObject value = caseResult; | 1342 DartObject value = caseResult; |
| 1344 if (firstType == null) { | 1343 if (firstType == null) { |
| 1345 firstType = value.type; | 1344 firstType = value.type; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1513 return result; | 1512 return result; |
| 1514 } | 1513 } |
| 1515 | 1514 |
| 1516 /** | 1515 /** |
| 1517 * Validate that if the passed arguments are constant expressions. | 1516 * Validate that if the passed arguments are constant expressions. |
| 1518 * | 1517 * |
| 1519 * @param argumentList the argument list to evaluate | 1518 * @param argumentList the argument list to evaluate |
| 1520 */ | 1519 */ |
| 1521 void _validateConstantArguments(ArgumentList argumentList) { | 1520 void _validateConstantArguments(ArgumentList argumentList) { |
| 1522 for (Expression argument in argumentList.arguments) { | 1521 for (Expression argument in argumentList.arguments) { |
| 1523 if (argument is NamedExpression) { | 1522 Expression realArgument = |
| 1524 argument = (argument as NamedExpression).expression; | 1523 argument is NamedExpression ? argument.expression : argument; |
| 1525 } | |
| 1526 _validate( | 1524 _validate( |
| 1527 argument, CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT); | 1525 realArgument, CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT); |
| 1528 } | 1526 } |
| 1529 } | 1527 } |
| 1530 | 1528 |
| 1531 /** | 1529 /** |
| 1532 * Validates that the expressions of the given initializers (of a constant con
structor) are all | 1530 * Validates that the expressions of the given initializers (of a constant con
structor) are all |
| 1533 * compile time constants. | 1531 * compile time constants. |
| 1534 * | 1532 * |
| 1535 * @param constructor the constant constructor declaration to validate | 1533 * @param constructor the constant constructor declaration to validate |
| 1536 */ | 1534 */ |
| 1537 void _validateConstructorInitializers(ConstructorDeclaration constructor) { | 1535 void _validateConstructorInitializers(ConstructorDeclaration constructor) { |
| 1538 List<ParameterElement> parameterElements = | 1536 List<ParameterElement> parameterElements = |
| 1539 constructor.parameters.parameterElements; | 1537 constructor.parameters.parameterElements; |
| 1540 NodeList<ConstructorInitializer> initializers = constructor.initializers; | 1538 NodeList<ConstructorInitializer> initializers = constructor.initializers; |
| 1541 for (ConstructorInitializer initializer in initializers) { | 1539 for (ConstructorInitializer initializer in initializers) { |
| 1542 if (initializer is ConstructorFieldInitializer) { | 1540 if (initializer is ConstructorFieldInitializer) { |
| 1543 ConstructorFieldInitializer fieldInitializer = initializer; | |
| 1544 _validateInitializerExpression( | 1541 _validateInitializerExpression( |
| 1545 parameterElements, fieldInitializer.expression); | 1542 parameterElements, initializer.expression); |
| 1546 } | 1543 } |
| 1547 if (initializer is RedirectingConstructorInvocation) { | 1544 if (initializer is RedirectingConstructorInvocation) { |
| 1548 RedirectingConstructorInvocation invocation = initializer; | |
| 1549 _validateInitializerInvocationArguments( | 1545 _validateInitializerInvocationArguments( |
| 1550 parameterElements, invocation.argumentList); | 1546 parameterElements, initializer.argumentList); |
| 1551 } | 1547 } |
| 1552 if (initializer is SuperConstructorInvocation) { | 1548 if (initializer is SuperConstructorInvocation) { |
| 1553 SuperConstructorInvocation invocation = initializer; | |
| 1554 _validateInitializerInvocationArguments( | 1549 _validateInitializerInvocationArguments( |
| 1555 parameterElements, invocation.argumentList); | 1550 parameterElements, initializer.argumentList); |
| 1556 } | 1551 } |
| 1557 } | 1552 } |
| 1558 } | 1553 } |
| 1559 | 1554 |
| 1560 /** | 1555 /** |
| 1561 * Validate that the default value associated with each of the parameters in t
he given list is a | 1556 * Validate that the default value associated with each of the parameters in t
he given list is a |
| 1562 * compile time constant. | 1557 * compile time constant. |
| 1563 * | 1558 * |
| 1564 * @param parameters the list of parameters to be validated | 1559 * @param parameters the list of parameters to be validated |
| 1565 */ | 1560 */ |
| 1566 void _validateDefaultValues(FormalParameterList parameters) { | 1561 void _validateDefaultValues(FormalParameterList parameters) { |
| 1567 if (parameters == null) { | 1562 if (parameters == null) { |
| 1568 return; | 1563 return; |
| 1569 } | 1564 } |
| 1570 for (FormalParameter parameter in parameters.parameters) { | 1565 for (FormalParameter parameter in parameters.parameters) { |
| 1571 if (parameter is DefaultFormalParameter) { | 1566 if (parameter is DefaultFormalParameter) { |
| 1572 DefaultFormalParameter defaultParameter = parameter; | 1567 Expression defaultValue = parameter.defaultValue; |
| 1573 Expression defaultValue = defaultParameter.defaultValue; | |
| 1574 DartObjectImpl result; | 1568 DartObjectImpl result; |
| 1575 if (defaultValue == null) { | 1569 if (defaultValue == null) { |
| 1576 result = | 1570 result = |
| 1577 new DartObjectImpl(_typeProvider.nullType, NullState.NULL_STATE); | 1571 new DartObjectImpl(_typeProvider.nullType, NullState.NULL_STATE); |
| 1578 } else { | 1572 } else { |
| 1579 result = _validate( | 1573 result = _validate( |
| 1580 defaultValue, CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE); | 1574 defaultValue, CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE); |
| 1581 if (result != null) { | 1575 if (result != null) { |
| 1582 _reportErrorIfFromDeferredLibrary( | 1576 _reportErrorIfFromDeferredLibrary( |
| 1583 defaultValue, | 1577 defaultValue, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1596 * compile time constants. Since this is only required if the class has a cons
tant constructor, | 1590 * compile time constants. Since this is only required if the class has a cons
tant constructor, |
| 1597 * the error is reported at the constructor site. | 1591 * the error is reported at the constructor site. |
| 1598 * | 1592 * |
| 1599 * @param classDeclaration the class which should be validated | 1593 * @param classDeclaration the class which should be validated |
| 1600 * @param errorSite the site at which errors should be reported. | 1594 * @param errorSite the site at which errors should be reported. |
| 1601 */ | 1595 */ |
| 1602 void _validateFieldInitializers( | 1596 void _validateFieldInitializers( |
| 1603 ClassDeclaration classDeclaration, ConstructorDeclaration errorSite) { | 1597 ClassDeclaration classDeclaration, ConstructorDeclaration errorSite) { |
| 1604 NodeList<ClassMember> members = classDeclaration.members; | 1598 NodeList<ClassMember> members = classDeclaration.members; |
| 1605 for (ClassMember member in members) { | 1599 for (ClassMember member in members) { |
| 1606 if (member is FieldDeclaration) { | 1600 if (member is FieldDeclaration && !member.isStatic) { |
| 1607 FieldDeclaration fieldDeclaration = member; | 1601 for (VariableDeclaration variableDeclaration |
| 1608 if (!fieldDeclaration.isStatic) { | 1602 in member.fields.variables) { |
| 1609 for (VariableDeclaration variableDeclaration | 1603 Expression initializer = variableDeclaration.initializer; |
| 1610 in fieldDeclaration.fields.variables) { | 1604 if (initializer != null) { |
| 1611 Expression initializer = variableDeclaration.initializer; | 1605 // Ignore any errors produced during validation--if the constant |
| 1612 if (initializer != null) { | 1606 // can't be eavluated we'll just report a single error. |
| 1613 // Ignore any errors produced during validation--if the constant | 1607 AnalysisErrorListener errorListener = |
| 1614 // can't be eavluated we'll just report a single error. | 1608 AnalysisErrorListener.NULL_LISTENER; |
| 1615 AnalysisErrorListener errorListener = | 1609 ErrorReporter subErrorReporter = |
| 1616 AnalysisErrorListener.NULL_LISTENER; | 1610 new ErrorReporter(errorListener, _errorReporter.source); |
| 1617 ErrorReporter subErrorReporter = | 1611 DartObjectImpl result = initializer.accept(new ConstantVisitor( |
| 1618 new ErrorReporter(errorListener, _errorReporter.source); | 1612 new ConstantEvaluationEngine(_typeProvider, declaredVariables, |
| 1619 DartObjectImpl result = initializer.accept(new ConstantVisitor( | 1613 typeSystem: _typeSystem), |
| 1620 new ConstantEvaluationEngine(_typeProvider, declaredVariables, | 1614 subErrorReporter)); |
| 1621 typeSystem: _typeSystem), | 1615 if (result == null) { |
| 1622 subErrorReporter)); | 1616 _errorReporter.reportErrorForNode( |
| 1623 if (result == null) { | 1617 CompileTimeErrorCode |
| 1624 _errorReporter.reportErrorForNode( | 1618 .CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST, |
| 1625 CompileTimeErrorCode | 1619 errorSite, |
| 1626 .CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST, | 1620 [variableDeclaration.name.name]); |
| 1627 errorSite, | |
| 1628 [variableDeclaration.name.name]); | |
| 1629 } | |
| 1630 } | 1621 } |
| 1631 } | 1622 } |
| 1632 } | 1623 } |
| 1633 } | 1624 } |
| 1634 } | 1625 } |
| 1635 } | 1626 } |
| 1636 | 1627 |
| 1637 /** | 1628 /** |
| 1638 * Validates that the given expression is a compile time constant. | 1629 * Validates that the given expression is a compile time constant. |
| 1639 * | 1630 * |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2129 | 2120 |
| 2130 /** | 2121 /** |
| 2131 * Return `true` if and only if the passed expression is resolved to a constan
t variable. | 2122 * Return `true` if and only if the passed expression is resolved to a constan
t variable. |
| 2132 * | 2123 * |
| 2133 * @param expression some conditional expression | 2124 * @param expression some conditional expression |
| 2134 * @return `true` if and only if the passed expression is resolved to a consta
nt variable | 2125 * @return `true` if and only if the passed expression is resolved to a consta
nt variable |
| 2135 */ | 2126 */ |
| 2136 bool _isDebugConstant(Expression expression) { | 2127 bool _isDebugConstant(Expression expression) { |
| 2137 Element element = null; | 2128 Element element = null; |
| 2138 if (expression is Identifier) { | 2129 if (expression is Identifier) { |
| 2139 Identifier identifier = expression; | 2130 element = expression.staticElement; |
| 2140 element = identifier.staticElement; | |
| 2141 } else if (expression is PropertyAccess) { | 2131 } else if (expression is PropertyAccess) { |
| 2142 PropertyAccess propertyAccess = expression; | 2132 element = expression.propertyName.staticElement; |
| 2143 element = propertyAccess.propertyName.staticElement; | |
| 2144 } | 2133 } |
| 2145 if (element is PropertyAccessorElement) { | 2134 if (element is PropertyAccessorElement) { |
| 2146 PropertyInducingElement variable = element.variable; | 2135 PropertyInducingElement variable = element.variable; |
| 2147 return variable != null && variable.isConst; | 2136 return variable != null && variable.isConst; |
| 2148 } | 2137 } |
| 2149 return false; | 2138 return false; |
| 2150 } | 2139 } |
| 2151 } | 2140 } |
| 2152 | 2141 |
| 2153 /** | 2142 /** |
| (...skipping 1330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3484 Expression lhsExpression = node.leftOperand; | 3473 Expression lhsExpression = node.leftOperand; |
| 3485 Expression rhsExpression = node.rightOperand; | 3474 Expression rhsExpression = node.rightOperand; |
| 3486 TokenType operatorType = node.operator.type; | 3475 TokenType operatorType = node.operator.type; |
| 3487 // If the operator is ||, then only consider the RHS of the binary | 3476 // If the operator is ||, then only consider the RHS of the binary |
| 3488 // expression if the left hand side is the false literal. | 3477 // expression if the left hand side is the false literal. |
| 3489 // TODO(jwren) Do we want to take constant expressions into account, | 3478 // TODO(jwren) Do we want to take constant expressions into account, |
| 3490 // evaluate if(false) {} differently than if(<condition>), when <condition> | 3479 // evaluate if(false) {} differently than if(<condition>), when <condition> |
| 3491 // evaluates to a constant false value? | 3480 // evaluates to a constant false value? |
| 3492 if (operatorType == TokenType.BAR_BAR) { | 3481 if (operatorType == TokenType.BAR_BAR) { |
| 3493 if (lhsExpression is BooleanLiteral) { | 3482 if (lhsExpression is BooleanLiteral) { |
| 3494 BooleanLiteral booleanLiteral = lhsExpression; | 3483 if (!lhsExpression.value) { |
| 3495 if (!booleanLiteral.value) { | |
| 3496 return _nodeExits(rhsExpression); | 3484 return _nodeExits(rhsExpression); |
| 3497 } | 3485 } |
| 3498 } | 3486 } |
| 3499 return _nodeExits(lhsExpression); | 3487 return _nodeExits(lhsExpression); |
| 3500 } | 3488 } |
| 3501 // If the operator is &&, then only consider the RHS of the binary | 3489 // If the operator is &&, then only consider the RHS of the binary |
| 3502 // expression if the left hand side is the true literal. | 3490 // expression if the left hand side is the true literal. |
| 3503 if (operatorType == TokenType.AMPERSAND_AMPERSAND) { | 3491 if (operatorType == TokenType.AMPERSAND_AMPERSAND) { |
| 3504 if (lhsExpression is BooleanLiteral) { | 3492 if (lhsExpression is BooleanLiteral) { |
| 3505 BooleanLiteral booleanLiteral = lhsExpression; | 3493 if (lhsExpression.value) { |
| 3506 if (booleanLiteral.value) { | |
| 3507 return _nodeExits(rhsExpression); | 3494 return _nodeExits(rhsExpression); |
| 3508 } | 3495 } |
| 3509 } | 3496 } |
| 3510 return _nodeExits(lhsExpression); | 3497 return _nodeExits(lhsExpression); |
| 3511 } | 3498 } |
| 3512 // If the operator is ??, then don't consider the RHS of the binary | 3499 // If the operator is ??, then don't consider the RHS of the binary |
| 3513 // expression. | 3500 // expression. |
| 3514 if (operatorType == TokenType.QUESTION_QUESTION) { | 3501 if (operatorType == TokenType.QUESTION_QUESTION) { |
| 3515 return _nodeExits(lhsExpression); | 3502 return _nodeExits(lhsExpression); |
| 3516 } | 3503 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3557 bool visitDoStatement(DoStatement node) { | 3544 bool visitDoStatement(DoStatement node) { |
| 3558 bool outerBreakValue = _enclosingBlockContainsBreak; | 3545 bool outerBreakValue = _enclosingBlockContainsBreak; |
| 3559 _enclosingBlockContainsBreak = false; | 3546 _enclosingBlockContainsBreak = false; |
| 3560 try { | 3547 try { |
| 3561 Expression conditionExpression = node.condition; | 3548 Expression conditionExpression = node.condition; |
| 3562 if (_nodeExits(conditionExpression)) { | 3549 if (_nodeExits(conditionExpression)) { |
| 3563 return true; | 3550 return true; |
| 3564 } | 3551 } |
| 3565 // TODO(jwren) Do we want to take all constant expressions into account? | 3552 // TODO(jwren) Do we want to take all constant expressions into account? |
| 3566 if (conditionExpression is BooleanLiteral) { | 3553 if (conditionExpression is BooleanLiteral) { |
| 3567 BooleanLiteral booleanLiteral = conditionExpression; | |
| 3568 // If do {} while (true), and the body doesn't return or the body | 3554 // If do {} while (true), and the body doesn't return or the body |
| 3569 // doesn't have a break, then return true. | 3555 // doesn't have a break, then return true. |
| 3570 bool blockReturns = _nodeExits(node.body); | 3556 bool blockReturns = _nodeExits(node.body); |
| 3571 if (booleanLiteral.value && | 3557 if (conditionExpression.value && |
| 3572 (blockReturns || !_enclosingBlockContainsBreak)) { | 3558 (blockReturns || !_enclosingBlockContainsBreak)) { |
| 3573 return true; | 3559 return true; |
| 3574 } | 3560 } |
| 3575 } | 3561 } |
| 3576 return false; | 3562 return false; |
| 3577 } finally { | 3563 } finally { |
| 3578 _enclosingBlockContainsBreak = outerBreakValue; | 3564 _enclosingBlockContainsBreak = outerBreakValue; |
| 3579 } | 3565 } |
| 3580 } | 3566 } |
| 3581 | 3567 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3654 @override | 3640 @override |
| 3655 bool visitIfStatement(IfStatement node) { | 3641 bool visitIfStatement(IfStatement node) { |
| 3656 Expression conditionExpression = node.condition; | 3642 Expression conditionExpression = node.condition; |
| 3657 Statement thenStatement = node.thenStatement; | 3643 Statement thenStatement = node.thenStatement; |
| 3658 Statement elseStatement = node.elseStatement; | 3644 Statement elseStatement = node.elseStatement; |
| 3659 if (_nodeExits(conditionExpression)) { | 3645 if (_nodeExits(conditionExpression)) { |
| 3660 return true; | 3646 return true; |
| 3661 } | 3647 } |
| 3662 // TODO(jwren) Do we want to take all constant expressions into account? | 3648 // TODO(jwren) Do we want to take all constant expressions into account? |
| 3663 if (conditionExpression is BooleanLiteral) { | 3649 if (conditionExpression is BooleanLiteral) { |
| 3664 BooleanLiteral booleanLiteral = conditionExpression; | 3650 if (conditionExpression.value) { |
| 3665 if (booleanLiteral.value) { | |
| 3666 // if(true) ... | 3651 // if(true) ... |
| 3667 return _nodeExits(thenStatement); | 3652 return _nodeExits(thenStatement); |
| 3668 } else if (elseStatement != null) { | 3653 } else if (elseStatement != null) { |
| 3669 // if (false) ... | 3654 // if (false) ... |
| 3670 return _nodeExits(elseStatement); | 3655 return _nodeExits(elseStatement); |
| 3671 } | 3656 } |
| 3672 } | 3657 } |
| 3673 if (thenStatement == null || elseStatement == null) { | 3658 if (thenStatement == null || elseStatement == null) { |
| 3674 return false; | 3659 return false; |
| 3675 } | 3660 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3849 bool visitWhileStatement(WhileStatement node) { | 3834 bool visitWhileStatement(WhileStatement node) { |
| 3850 bool outerBreakValue = _enclosingBlockContainsBreak; | 3835 bool outerBreakValue = _enclosingBlockContainsBreak; |
| 3851 _enclosingBlockContainsBreak = false; | 3836 _enclosingBlockContainsBreak = false; |
| 3852 try { | 3837 try { |
| 3853 Expression conditionExpression = node.condition; | 3838 Expression conditionExpression = node.condition; |
| 3854 if (conditionExpression.accept(this)) { | 3839 if (conditionExpression.accept(this)) { |
| 3855 return true; | 3840 return true; |
| 3856 } | 3841 } |
| 3857 // TODO(jwren) Do we want to take all constant expressions into account? | 3842 // TODO(jwren) Do we want to take all constant expressions into account? |
| 3858 if (conditionExpression is BooleanLiteral) { | 3843 if (conditionExpression is BooleanLiteral) { |
| 3859 BooleanLiteral booleanLiteral = conditionExpression; | |
| 3860 // If while(true), and the body doesn't return or the body doesn't have | 3844 // If while(true), and the body doesn't return or the body doesn't have |
| 3861 // a break, then return true. | 3845 // a break, then return true. |
| 3862 bool blockReturns = node.body.accept(this); | 3846 bool blockReturns = node.body.accept(this); |
| 3863 if (booleanLiteral.value && | 3847 if (conditionExpression.value && |
| 3864 (blockReturns || !_enclosingBlockContainsBreak)) { | 3848 (blockReturns || !_enclosingBlockContainsBreak)) { |
| 3865 return true; | 3849 return true; |
| 3866 } | 3850 } |
| 3867 } | 3851 } |
| 3868 return false; | 3852 return false; |
| 3869 } finally { | 3853 } finally { |
| 3870 _enclosingBlockContainsBreak = outerBreakValue; | 3854 _enclosingBlockContainsBreak = outerBreakValue; |
| 3871 } | 3855 } |
| 3872 } | 3856 } |
| 3873 | 3857 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3981 directive.metadata.accept(this); | 3965 directive.metadata.accept(this); |
| 3982 } | 3966 } |
| 3983 | 3967 |
| 3984 void _visitIdentifier(SimpleIdentifier identifier, Element element) { | 3968 void _visitIdentifier(SimpleIdentifier identifier, Element element) { |
| 3985 if (element == null) { | 3969 if (element == null) { |
| 3986 return; | 3970 return; |
| 3987 } | 3971 } |
| 3988 // If the element is multiply defined then call this method recursively for | 3972 // If the element is multiply defined then call this method recursively for |
| 3989 // each of the conflicting elements. | 3973 // each of the conflicting elements. |
| 3990 if (element is MultiplyDefinedElement) { | 3974 if (element is MultiplyDefinedElement) { |
| 3991 MultiplyDefinedElement multiplyDefinedElement = element; | 3975 for (Element elt in element.conflictingElements) { |
| 3992 for (Element elt in multiplyDefinedElement.conflictingElements) { | |
| 3993 _visitIdentifier(identifier, elt); | 3976 _visitIdentifier(identifier, elt); |
| 3994 } | 3977 } |
| 3995 return; | 3978 return; |
| 3996 } | 3979 } |
| 3997 | 3980 |
| 3998 // Record `importPrefix.identifier` into 'prefixMap'. | 3981 // Record `importPrefix.identifier` into 'prefixMap'. |
| 3999 if (_recordPrefixMap(identifier, element)) { | 3982 if (_recordPrefixMap(identifier, element)) { |
| 4000 return; | 3983 return; |
| 4001 } | 3984 } |
| 4002 | 3985 |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4339 * unused shown elements. | 4322 * unused shown elements. |
| 4340 * | 4323 * |
| 4341 * See [ImportsVerifier.generateUnusedShownNameHints]. | 4324 * See [ImportsVerifier.generateUnusedShownNameHints]. |
| 4342 */ | 4325 */ |
| 4343 final HashMap<ImportDirective, List<SimpleIdentifier>> _unusedShownNamesMap = | 4326 final HashMap<ImportDirective, List<SimpleIdentifier>> _unusedShownNamesMap = |
| 4344 new HashMap<ImportDirective, List<SimpleIdentifier>>(); | 4327 new HashMap<ImportDirective, List<SimpleIdentifier>>(); |
| 4345 | 4328 |
| 4346 void addImports(CompilationUnit node) { | 4329 void addImports(CompilationUnit node) { |
| 4347 for (Directive directive in node.directives) { | 4330 for (Directive directive in node.directives) { |
| 4348 if (directive is ImportDirective) { | 4331 if (directive is ImportDirective) { |
| 4349 ImportDirective importDirective = directive; | 4332 LibraryElement libraryElement = directive.uriElement; |
| 4350 LibraryElement libraryElement = importDirective.uriElement; | |
| 4351 if (libraryElement == null) { | 4333 if (libraryElement == null) { |
| 4352 continue; | 4334 continue; |
| 4353 } | 4335 } |
| 4354 _unusedImports.add(importDirective); | 4336 _unusedImports.add(directive); |
| 4355 // | 4337 // |
| 4356 // Initialize prefixElementMap | 4338 // Initialize prefixElementMap |
| 4357 // | 4339 // |
| 4358 if (importDirective.asKeyword != null) { | 4340 if (directive.asKeyword != null) { |
| 4359 SimpleIdentifier prefixIdentifier = importDirective.prefix; | 4341 SimpleIdentifier prefixIdentifier = directive.prefix; |
| 4360 if (prefixIdentifier != null) { | 4342 if (prefixIdentifier != null) { |
| 4361 Element element = prefixIdentifier.staticElement; | 4343 Element element = prefixIdentifier.staticElement; |
| 4362 if (element is PrefixElement) { | 4344 if (element is PrefixElement) { |
| 4363 PrefixElement prefixElementKey = element; | 4345 List<ImportDirective> list = _prefixElementMap[element]; |
| 4364 List<ImportDirective> list = _prefixElementMap[prefixElementKey]; | |
| 4365 if (list == null) { | 4346 if (list == null) { |
| 4366 list = new List<ImportDirective>(); | 4347 list = new List<ImportDirective>(); |
| 4367 _prefixElementMap[prefixElementKey] = list; | 4348 _prefixElementMap[element] = list; |
| 4368 } | 4349 } |
| 4369 list.add(importDirective); | 4350 list.add(directive); |
| 4370 } | 4351 } |
| 4371 // TODO (jwren) Can the element ever not be a PrefixElement? | 4352 // TODO (jwren) Can the element ever not be a PrefixElement? |
| 4372 } | 4353 } |
| 4373 } | 4354 } |
| 4374 // | 4355 // |
| 4375 // Initialize libraryMap: libraryElement -> importDirective | 4356 // Initialize libraryMap: libraryElement -> importDirective |
| 4376 // | 4357 // |
| 4377 _putIntoLibraryMap(libraryElement, importDirective); | 4358 _putIntoLibraryMap(libraryElement, directive); |
| 4378 // | 4359 // |
| 4379 // For this new addition to the libraryMap, also recursively add any | 4360 // For this new addition to the libraryMap, also recursively add any |
| 4380 // exports from the libraryElement. | 4361 // exports from the libraryElement. |
| 4381 // | 4362 // |
| 4382 _addAdditionalLibrariesForExports( | 4363 _addAdditionalLibrariesForExports( |
| 4383 libraryElement, importDirective, new HashSet<LibraryElement>()); | 4364 libraryElement, directive, new HashSet<LibraryElement>()); |
| 4384 _addShownNames(importDirective); | 4365 _addShownNames(directive); |
| 4385 } | 4366 } |
| 4386 } | 4367 } |
| 4387 if (_unusedImports.length > 1) { | 4368 if (_unusedImports.length > 1) { |
| 4388 // order the list of unusedImports to find duplicates in faster than | 4369 // order the list of unusedImports to find duplicates in faster than |
| 4389 // O(n^2) time | 4370 // O(n^2) time |
| 4390 List<ImportDirective> importDirectiveArray = | 4371 List<ImportDirective> importDirectiveArray = |
| 4391 new List<ImportDirective>.from(_unusedImports); | 4372 new List<ImportDirective>.from(_unusedImports); |
| 4392 importDirectiveArray.sort(ImportDirective.COMPARATOR); | 4373 importDirectiveArray.sort(ImportDirective.COMPARATOR); |
| 4393 ImportDirective currentDirective = importDirectiveArray[0]; | 4374 ImportDirective currentDirective = importDirectiveArray[0]; |
| 4394 for (int i = 1; i < importDirectiveArray.length; i++) { | 4375 for (int i = 1; i < importDirectiveArray.length; i++) { |
| (...skipping 2541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6936 /** | 6917 /** |
| 6937 * The given expression is the expression used to compute the iterator for a | 6918 * The given expression is the expression used to compute the iterator for a |
| 6938 * for-each statement. Attempt to compute the type of objects that will be | 6919 * for-each statement. Attempt to compute the type of objects that will be |
| 6939 * assigned to the loop variable and return that type. Return `null` if the | 6920 * assigned to the loop variable and return that type. Return `null` if the |
| 6940 * type could not be determined. The [iteratorExpression] is the expression | 6921 * type could not be determined. The [iteratorExpression] is the expression |
| 6941 * that will return the Iterable being iterated over. | 6922 * that will return the Iterable being iterated over. |
| 6942 */ | 6923 */ |
| 6943 DartType _getIteratorElementType(Expression iteratorExpression) { | 6924 DartType _getIteratorElementType(Expression iteratorExpression) { |
| 6944 DartType expressionType = iteratorExpression.bestType; | 6925 DartType expressionType = iteratorExpression.bestType; |
| 6945 if (expressionType is InterfaceType) { | 6926 if (expressionType is InterfaceType) { |
| 6946 InterfaceType interfaceType = expressionType; | |
| 6947 PropertyAccessorElement iteratorFunction = | 6927 PropertyAccessorElement iteratorFunction = |
| 6948 interfaceType.lookUpInheritedGetter("iterator"); | 6928 expressionType.lookUpInheritedGetter("iterator"); |
| 6949 if (iteratorFunction == null) { | 6929 if (iteratorFunction == null) { |
| 6950 // TODO(brianwilkerson) Should we report this error? | 6930 // TODO(brianwilkerson) Should we report this error? |
| 6951 return null; | 6931 return null; |
| 6952 } | 6932 } |
| 6953 DartType iteratorType = iteratorFunction.returnType; | 6933 DartType iteratorType = iteratorFunction.returnType; |
| 6954 if (iteratorType is InterfaceType) { | 6934 if (iteratorType is InterfaceType) { |
| 6955 InterfaceType iteratorInterfaceType = iteratorType; | |
| 6956 PropertyAccessorElement currentFunction = | 6935 PropertyAccessorElement currentFunction = |
| 6957 iteratorInterfaceType.lookUpInheritedGetter("current"); | 6936 iteratorType.lookUpInheritedGetter("current"); |
| 6958 if (currentFunction == null) { | 6937 if (currentFunction == null) { |
| 6959 // TODO(brianwilkerson) Should we report this error? | 6938 // TODO(brianwilkerson) Should we report this error? |
| 6960 return null; | 6939 return null; |
| 6961 } | 6940 } |
| 6962 return currentFunction.returnType; | 6941 return currentFunction.returnType; |
| 6963 } | 6942 } |
| 6964 } | 6943 } |
| 6965 return null; | 6944 return null; |
| 6966 } | 6945 } |
| 6967 | 6946 |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7211 _promoteManager.setType(element, potentialType); | 7190 _promoteManager.setType(element, potentialType); |
| 7212 } | 7191 } |
| 7213 } | 7192 } |
| 7214 } | 7193 } |
| 7215 | 7194 |
| 7216 /** | 7195 /** |
| 7217 * Promotes type information using given condition. | 7196 * Promotes type information using given condition. |
| 7218 */ | 7197 */ |
| 7219 void _promoteTypes(Expression condition) { | 7198 void _promoteTypes(Expression condition) { |
| 7220 if (condition is BinaryExpression) { | 7199 if (condition is BinaryExpression) { |
| 7221 BinaryExpression binary = condition; | 7200 if (condition.operator.type == TokenType.AMPERSAND_AMPERSAND) { |
| 7222 if (binary.operator.type == TokenType.AMPERSAND_AMPERSAND) { | 7201 Expression left = condition.leftOperand; |
| 7223 Expression left = binary.leftOperand; | 7202 Expression right = condition.rightOperand; |
| 7224 Expression right = binary.rightOperand; | |
| 7225 _promoteTypes(left); | 7203 _promoteTypes(left); |
| 7226 _promoteTypes(right); | 7204 _promoteTypes(right); |
| 7227 _clearTypePromotionsIfPotentiallyMutatedIn(right); | 7205 _clearTypePromotionsIfPotentiallyMutatedIn(right); |
| 7228 } | 7206 } |
| 7229 } else if (condition is IsExpression) { | 7207 } else if (condition is IsExpression) { |
| 7230 IsExpression is2 = condition; | 7208 if (condition.notOperator == null) { |
| 7231 if (is2.notOperator == null) { | 7209 _promote(condition.expression, condition.type.type); |
| 7232 _promote(is2.expression, is2.type.type); | |
| 7233 } | 7210 } |
| 7234 } else if (condition is ParenthesizedExpression) { | 7211 } else if (condition is ParenthesizedExpression) { |
| 7235 _promoteTypes(condition.expression); | 7212 _promoteTypes(condition.expression); |
| 7236 } | 7213 } |
| 7237 } | 7214 } |
| 7238 | 7215 |
| 7239 /** | 7216 /** |
| 7240 * Propagate any type information that results from knowing that the given con
dition will have | 7217 * Propagate any type information that results from knowing that the given con
dition will have |
| 7241 * been evaluated to 'false'. | 7218 * been evaluated to 'false'. |
| 7242 * | 7219 * |
| 7243 * @param condition the condition that will have evaluated to 'false' | 7220 * @param condition the condition that will have evaluated to 'false' |
| 7244 */ | 7221 */ |
| 7245 void _propagateFalseState(Expression condition) { | 7222 void _propagateFalseState(Expression condition) { |
| 7246 if (condition is BinaryExpression) { | 7223 if (condition is BinaryExpression) { |
| 7247 BinaryExpression binary = condition; | 7224 if (condition.operator.type == TokenType.BAR_BAR) { |
| 7248 if (binary.operator.type == TokenType.BAR_BAR) { | 7225 _propagateFalseState(condition.leftOperand); |
| 7249 _propagateFalseState(binary.leftOperand); | 7226 _propagateFalseState(condition.rightOperand); |
| 7250 _propagateFalseState(binary.rightOperand); | |
| 7251 } | 7227 } |
| 7252 } else if (condition is IsExpression) { | 7228 } else if (condition is IsExpression) { |
| 7253 IsExpression is2 = condition; | 7229 if (condition.notOperator != null) { |
| 7254 if (is2.notOperator != null) { | |
| 7255 // Since an is-statement doesn't actually change the type, we don't | 7230 // Since an is-statement doesn't actually change the type, we don't |
| 7256 // let it affect the propagated type when it would result in a loss | 7231 // let it affect the propagated type when it would result in a loss |
| 7257 // of precision. | 7232 // of precision. |
| 7258 overrideExpression(is2.expression, is2.type.type, false, false); | 7233 overrideExpression( |
| 7234 condition.expression, condition.type.type, false, false); |
| 7259 } | 7235 } |
| 7260 } else if (condition is PrefixExpression) { | 7236 } else if (condition is PrefixExpression) { |
| 7261 PrefixExpression prefix = condition; | 7237 if (condition.operator.type == TokenType.BANG) { |
| 7262 if (prefix.operator.type == TokenType.BANG) { | 7238 _propagateTrueState(condition.operand); |
| 7263 _propagateTrueState(prefix.operand); | |
| 7264 } | 7239 } |
| 7265 } else if (condition is ParenthesizedExpression) { | 7240 } else if (condition is ParenthesizedExpression) { |
| 7266 _propagateFalseState(condition.expression); | 7241 _propagateFalseState(condition.expression); |
| 7267 } | 7242 } |
| 7268 } | 7243 } |
| 7269 | 7244 |
| 7270 /** | 7245 /** |
| 7271 * Propagate any type information that results from knowing that the given exp
ression will have | 7246 * Propagate any type information that results from knowing that the given exp
ression will have |
| 7272 * been evaluated without altering the flow of execution. | 7247 * been evaluated without altering the flow of execution. |
| 7273 * | 7248 * |
| 7274 * @param expression the expression that will have been evaluated | 7249 * @param expression the expression that will have been evaluated |
| 7275 */ | 7250 */ |
| 7276 void _propagateState(Expression expression) { | 7251 void _propagateState(Expression expression) { |
| 7277 // TODO(brianwilkerson) Implement this. | 7252 // TODO(brianwilkerson) Implement this. |
| 7278 } | 7253 } |
| 7279 | 7254 |
| 7280 /** | 7255 /** |
| 7281 * Propagate any type information that results from knowing that the given con
dition will have | 7256 * Propagate any type information that results from knowing that the given con
dition will have |
| 7282 * been evaluated to 'true'. | 7257 * been evaluated to 'true'. |
| 7283 * | 7258 * |
| 7284 * @param condition the condition that will have evaluated to 'true' | 7259 * @param condition the condition that will have evaluated to 'true' |
| 7285 */ | 7260 */ |
| 7286 void _propagateTrueState(Expression condition) { | 7261 void _propagateTrueState(Expression condition) { |
| 7287 if (condition is BinaryExpression) { | 7262 if (condition is BinaryExpression) { |
| 7288 BinaryExpression binary = condition; | 7263 if (condition.operator.type == TokenType.AMPERSAND_AMPERSAND) { |
| 7289 if (binary.operator.type == TokenType.AMPERSAND_AMPERSAND) { | 7264 _propagateTrueState(condition.leftOperand); |
| 7290 _propagateTrueState(binary.leftOperand); | 7265 _propagateTrueState(condition.rightOperand); |
| 7291 _propagateTrueState(binary.rightOperand); | |
| 7292 } | 7266 } |
| 7293 } else if (condition is IsExpression) { | 7267 } else if (condition is IsExpression) { |
| 7294 IsExpression is2 = condition; | 7268 if (condition.notOperator == null) { |
| 7295 if (is2.notOperator == null) { | |
| 7296 // Since an is-statement doesn't actually change the type, we don't | 7269 // Since an is-statement doesn't actually change the type, we don't |
| 7297 // let it affect the propagated type when it would result in a loss | 7270 // let it affect the propagated type when it would result in a loss |
| 7298 // of precision. | 7271 // of precision. |
| 7299 overrideExpression(is2.expression, is2.type.type, false, false); | 7272 overrideExpression( |
| 7273 condition.expression, condition.type.type, false, false); |
| 7300 } | 7274 } |
| 7301 } else if (condition is PrefixExpression) { | 7275 } else if (condition is PrefixExpression) { |
| 7302 PrefixExpression prefix = condition; | 7276 if (condition.operator.type == TokenType.BANG) { |
| 7303 if (prefix.operator.type == TokenType.BANG) { | 7277 _propagateFalseState(condition.operand); |
| 7304 _propagateFalseState(prefix.operand); | |
| 7305 } | 7278 } |
| 7306 } else if (condition is ParenthesizedExpression) { | 7279 } else if (condition is ParenthesizedExpression) { |
| 7307 _propagateTrueState(condition.expression); | 7280 _propagateTrueState(condition.expression); |
| 7308 } | 7281 } |
| 7309 } | 7282 } |
| 7310 | 7283 |
| 7311 /** | 7284 /** |
| 7312 * Given an [argumentList] and the [parameters] related to the element that | 7285 * Given an [argumentList] and the [parameters] related to the element that |
| 7313 * will be invoked using those arguments, compute the list of parameters that | 7286 * will be invoked using those arguments, compute the list of parameters that |
| 7314 * correspond to the list of arguments. | 7287 * correspond to the list of arguments. |
| (...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8084 * Marks the local declarations of the given [Block] hidden in the enclosing s
cope. | 8057 * Marks the local declarations of the given [Block] hidden in the enclosing s
cope. |
| 8085 * According to the scoping rules name is hidden if block defines it, but name
is defined after | 8058 * According to the scoping rules name is hidden if block defines it, but name
is defined after |
| 8086 * its declaration statement. | 8059 * its declaration statement. |
| 8087 */ | 8060 */ |
| 8088 void _hideNamesDefinedInBlock(EnclosedScope scope, Block block) { | 8061 void _hideNamesDefinedInBlock(EnclosedScope scope, Block block) { |
| 8089 NodeList<Statement> statements = block.statements; | 8062 NodeList<Statement> statements = block.statements; |
| 8090 int statementCount = statements.length; | 8063 int statementCount = statements.length; |
| 8091 for (int i = 0; i < statementCount; i++) { | 8064 for (int i = 0; i < statementCount; i++) { |
| 8092 Statement statement = statements[i]; | 8065 Statement statement = statements[i]; |
| 8093 if (statement is VariableDeclarationStatement) { | 8066 if (statement is VariableDeclarationStatement) { |
| 8094 VariableDeclarationStatement vds = statement; | 8067 NodeList<VariableDeclaration> variables = statement.variables.variables; |
| 8095 NodeList<VariableDeclaration> variables = vds.variables.variables; | |
| 8096 int variableCount = variables.length; | 8068 int variableCount = variables.length; |
| 8097 for (int j = 0; j < variableCount; j++) { | 8069 for (int j = 0; j < variableCount; j++) { |
| 8098 scope.hide(variables[j].element); | 8070 scope.hide(variables[j].element); |
| 8099 } | 8071 } |
| 8100 } else if (statement is FunctionDeclarationStatement) { | 8072 } else if (statement is FunctionDeclarationStatement) { |
| 8101 FunctionDeclarationStatement fds = statement; | 8073 scope.hide(statement.functionDeclaration.element); |
| 8102 scope.hide(fds.functionDeclaration.element); | |
| 8103 } | 8074 } |
| 8104 } | 8075 } |
| 8105 } | 8076 } |
| 8106 } | 8077 } |
| 8107 | 8078 |
| 8108 /** | 8079 /** |
| 8109 * Instances of this class manage the knowledge of what the set of subtypes are
for a given type. | 8080 * Instances of this class manage the knowledge of what the set of subtypes are
for a given type. |
| 8110 */ | 8081 */ |
| 8111 class SubtypeManager { | 8082 class SubtypeManager { |
| 8112 /** | 8083 /** |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8519 } | 8490 } |
| 8520 | 8491 |
| 8521 /** | 8492 /** |
| 8522 * Return the overridden type of the given element, or `null` if the type of t
he element | 8493 * Return the overridden type of the given element, or `null` if the type of t
he element |
| 8523 * has not been overridden. | 8494 * has not been overridden. |
| 8524 * | 8495 * |
| 8525 * @param element the element whose type might have been overridden | 8496 * @param element the element whose type might have been overridden |
| 8526 * @return the overridden type of the given element | 8497 * @return the overridden type of the given element |
| 8527 */ | 8498 */ |
| 8528 DartType getType(Element element) { | 8499 DartType getType(Element element) { |
| 8529 if (element is PropertyAccessorElement) { | 8500 Element nonAccessor = |
| 8530 element = (element as PropertyAccessorElement).variable; | 8501 element is PropertyAccessorElement ? element.variable : element; |
| 8531 } | 8502 DartType type = _overridenTypes[nonAccessor]; |
| 8532 DartType type = _overridenTypes[element]; | 8503 if (_overridenTypes.containsKey(nonAccessor)) { |
| 8533 if (_overridenTypes.containsKey(element)) { | |
| 8534 return type; | 8504 return type; |
| 8535 } | 8505 } |
| 8536 if (type != null) { | 8506 if (type != null) { |
| 8537 return type; | 8507 return type; |
| 8538 } else if (_outerScope != null) { | 8508 } else if (_outerScope != null) { |
| 8539 return _outerScope.getType(element); | 8509 return _outerScope.getType(nonAccessor); |
| 8540 } | 8510 } |
| 8541 return null; | 8511 return null; |
| 8542 } | 8512 } |
| 8543 | 8513 |
| 8544 /** | 8514 /** |
| 8545 * Clears the overridden type of the given [element]. | 8515 * Clears the overridden type of the given [element]. |
| 8546 */ | 8516 */ |
| 8547 void resetType(VariableElement element) { | 8517 void resetType(VariableElement element) { |
| 8548 _overridenTypes[element] = null; | 8518 _overridenTypes[element] = null; |
| 8549 } | 8519 } |
| (...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9363 LocalVariableElementImpl element = node.element as LocalVariableElementImpl; | 9333 LocalVariableElementImpl element = node.element as LocalVariableElementImpl; |
| 9364 element.type = declaredType; | 9334 element.type = declaredType; |
| 9365 return null; | 9335 return null; |
| 9366 } | 9336 } |
| 9367 | 9337 |
| 9368 @override | 9338 @override |
| 9369 Object visitFieldFormalParameter(FieldFormalParameter node) { | 9339 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 9370 super.visitFieldFormalParameter(node); | 9340 super.visitFieldFormalParameter(node); |
| 9371 Element element = node.identifier.staticElement; | 9341 Element element = node.identifier.staticElement; |
| 9372 if (element is ParameterElementImpl) { | 9342 if (element is ParameterElementImpl) { |
| 9373 ParameterElementImpl parameter = element; | |
| 9374 FormalParameterList parameterList = node.parameters; | 9343 FormalParameterList parameterList = node.parameters; |
| 9375 if (parameterList == null) { | 9344 if (parameterList == null) { |
| 9376 DartType type; | 9345 DartType type; |
| 9377 TypeName typeName = node.type; | 9346 TypeName typeName = node.type; |
| 9378 if (typeName == null) { | 9347 if (typeName == null) { |
| 9379 element.hasImplicitType = true; | 9348 element.hasImplicitType = true; |
| 9380 type = _dynamicType; | 9349 type = _dynamicType; |
| 9381 if (parameter is FieldFormalParameterElement) { | 9350 if (element is FieldFormalParameterElement) { |
| 9382 FieldElement fieldElement = | 9351 FieldElement fieldElement = |
| 9383 (parameter as FieldFormalParameterElement).field; | 9352 (element as FieldFormalParameterElement).field; |
| 9384 if (fieldElement != null) { | 9353 if (fieldElement != null) { |
| 9385 type = fieldElement.type; | 9354 type = fieldElement.type; |
| 9386 } | 9355 } |
| 9387 } | 9356 } |
| 9388 } else { | 9357 } else { |
| 9389 type = _getType(typeName); | 9358 type = _getType(typeName); |
| 9390 } | 9359 } |
| 9391 parameter.type = type; | 9360 element.type = type; |
| 9392 } else { | 9361 } else { |
| 9393 _setFunctionTypedParameterType(parameter, node.type, node.parameters); | 9362 _setFunctionTypedParameterType(element, node.type, node.parameters); |
| 9394 } | 9363 } |
| 9395 } else { | 9364 } else { |
| 9396 // TODO(brianwilkerson) Report this internal error | 9365 // TODO(brianwilkerson) Report this internal error |
| 9397 } | 9366 } |
| 9398 return null; | 9367 return null; |
| 9399 } | 9368 } |
| 9400 | 9369 |
| 9401 @override | 9370 @override |
| 9402 Object visitFunctionDeclaration(FunctionDeclaration node) { | 9371 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 9403 super.visitFunctionDeclaration(node); | 9372 super.visitFunctionDeclaration(node); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9484 Object visitSimpleFormalParameter(SimpleFormalParameter node) { | 9453 Object visitSimpleFormalParameter(SimpleFormalParameter node) { |
| 9485 super.visitSimpleFormalParameter(node); | 9454 super.visitSimpleFormalParameter(node); |
| 9486 DartType declaredType; | 9455 DartType declaredType; |
| 9487 TypeName typeName = node.type; | 9456 TypeName typeName = node.type; |
| 9488 if (typeName == null) { | 9457 if (typeName == null) { |
| 9489 declaredType = _dynamicType; | 9458 declaredType = _dynamicType; |
| 9490 } else { | 9459 } else { |
| 9491 declaredType = _getType(typeName); | 9460 declaredType = _getType(typeName); |
| 9492 } | 9461 } |
| 9493 Element element = node.identifier.staticElement; | 9462 Element element = node.identifier.staticElement; |
| 9494 if (element is ParameterElement) { | 9463 if (element is ParameterElementImpl) { |
| 9495 (element as ParameterElementImpl).type = declaredType; | 9464 element.type = declaredType; |
| 9496 } else { | 9465 } else { |
| 9497 // TODO(brianwilkerson) Report the internal error. | 9466 // TODO(brianwilkerson) Report the internal error. |
| 9498 } | 9467 } |
| 9499 return null; | 9468 return null; |
| 9500 } | 9469 } |
| 9501 | 9470 |
| 9502 @override | 9471 @override |
| 9503 Object visitSuperExpression(SuperExpression node) { | 9472 Object visitSuperExpression(SuperExpression node) { |
| 9504 _hasReferenceToSuper = true; | 9473 _hasReferenceToSuper = true; |
| 9505 return super.visitSuperExpression(node); | 9474 return super.visitSuperExpression(node); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9778 TypeName typeName = (node.parent as VariableDeclarationList).type; | 9747 TypeName typeName = (node.parent as VariableDeclarationList).type; |
| 9779 if (typeName == null) { | 9748 if (typeName == null) { |
| 9780 declaredType = _dynamicType; | 9749 declaredType = _dynamicType; |
| 9781 } else { | 9750 } else { |
| 9782 declaredType = _getType(typeName); | 9751 declaredType = _getType(typeName); |
| 9783 } | 9752 } |
| 9784 Element element = node.name.staticElement; | 9753 Element element = node.name.staticElement; |
| 9785 if (element is VariableElement) { | 9754 if (element is VariableElement) { |
| 9786 (element as VariableElementImpl).type = declaredType; | 9755 (element as VariableElementImpl).type = declaredType; |
| 9787 if (element is PropertyInducingElement) { | 9756 if (element is PropertyInducingElement) { |
| 9788 PropertyInducingElement variableElement = element; | |
| 9789 PropertyAccessorElementImpl getter = | 9757 PropertyAccessorElementImpl getter = |
| 9790 variableElement.getter as PropertyAccessorElementImpl; | 9758 element.getter as PropertyAccessorElementImpl; |
| 9791 getter.returnType = declaredType; | 9759 getter.returnType = declaredType; |
| 9792 getter.type = new FunctionTypeImpl(getter); | 9760 getter.type = new FunctionTypeImpl(getter); |
| 9793 PropertyAccessorElementImpl setter = | 9761 PropertyAccessorElementImpl setter = |
| 9794 variableElement.setter as PropertyAccessorElementImpl; | 9762 element.setter as PropertyAccessorElementImpl; |
| 9795 if (setter != null) { | 9763 if (setter != null) { |
| 9796 List<ParameterElement> parameters = setter.parameters; | 9764 List<ParameterElement> parameters = setter.parameters; |
| 9797 if (parameters.length > 0) { | 9765 if (parameters.length > 0) { |
| 9798 (parameters[0] as ParameterElementImpl).type = declaredType; | 9766 (parameters[0] as ParameterElementImpl).type = declaredType; |
| 9799 } | 9767 } |
| 9800 setter.returnType = VoidTypeImpl.instance; | 9768 setter.returnType = VoidTypeImpl.instance; |
| 9801 setter.type = new FunctionTypeImpl(setter); | 9769 setter.type = new FunctionTypeImpl(setter); |
| 9802 } | 9770 } |
| 9803 } | 9771 } |
| 9804 } else { | 9772 } else { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9893 /** | 9861 /** |
| 9894 * Checks if the given type name is the target in a redirected constructor. | 9862 * Checks if the given type name is the target in a redirected constructor. |
| 9895 * | 9863 * |
| 9896 * @param typeName the type name to analyze | 9864 * @param typeName the type name to analyze |
| 9897 * @return some [RedirectingConstructorKind] if the given type name is used as
the type in a | 9865 * @return some [RedirectingConstructorKind] if the given type name is used as
the type in a |
| 9898 * redirected constructor, or `null` otherwise | 9866 * redirected constructor, or `null` otherwise |
| 9899 */ | 9867 */ |
| 9900 RedirectingConstructorKind _getRedirectingConstructorKind(TypeName typeName) { | 9868 RedirectingConstructorKind _getRedirectingConstructorKind(TypeName typeName) { |
| 9901 AstNode parent = typeName.parent; | 9869 AstNode parent = typeName.parent; |
| 9902 if (parent is ConstructorName) { | 9870 if (parent is ConstructorName) { |
| 9903 ConstructorName constructorName = parent as ConstructorName; | 9871 AstNode grandParent = parent.parent; |
| 9904 parent = constructorName.parent; | 9872 if (grandParent is ConstructorDeclaration) { |
| 9905 if (parent is ConstructorDeclaration) { | 9873 if (identical(grandParent.redirectedConstructor, parent)) { |
| 9906 if (identical(parent.redirectedConstructor, constructorName)) { | 9874 if (grandParent.constKeyword != null) { |
| 9907 if (parent.constKeyword != null) { | |
| 9908 return RedirectingConstructorKind.CONST; | 9875 return RedirectingConstructorKind.CONST; |
| 9909 } | 9876 } |
| 9910 return RedirectingConstructorKind.NORMAL; | 9877 return RedirectingConstructorKind.NORMAL; |
| 9911 } | 9878 } |
| 9912 } | 9879 } |
| 9913 } | 9880 } |
| 9914 return null; | 9881 return null; |
| 9915 } | 9882 } |
| 9916 | 9883 |
| 9917 /** | 9884 /** |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9978 | 9945 |
| 9979 /** | 9946 /** |
| 9980 * Checks if the given type name is used as the type in an as expression. | 9947 * Checks if the given type name is used as the type in an as expression. |
| 9981 * | 9948 * |
| 9982 * @param typeName the type name to analyzer | 9949 * @param typeName the type name to analyzer |
| 9983 * @return `true` if the given type name is used as the type in an as expressi
on | 9950 * @return `true` if the given type name is used as the type in an as expressi
on |
| 9984 */ | 9951 */ |
| 9985 bool _isTypeNameInAsExpression(TypeName typeName) { | 9952 bool _isTypeNameInAsExpression(TypeName typeName) { |
| 9986 AstNode parent = typeName.parent; | 9953 AstNode parent = typeName.parent; |
| 9987 if (parent is AsExpression) { | 9954 if (parent is AsExpression) { |
| 9988 AsExpression asExpression = parent; | 9955 return identical(parent.type, typeName); |
| 9989 return identical(asExpression.type, typeName); | |
| 9990 } | 9956 } |
| 9991 return false; | 9957 return false; |
| 9992 } | 9958 } |
| 9993 | 9959 |
| 9994 /** | 9960 /** |
| 9995 * Checks if the given type name is used as the exception type in a catch clau
se. | 9961 * Checks if the given type name is used as the exception type in a catch clau
se. |
| 9996 * | 9962 * |
| 9997 * @param typeName the type name to analyzer | 9963 * @param typeName the type name to analyzer |
| 9998 * @return `true` if the given type name is used as the exception type in a ca
tch clause | 9964 * @return `true` if the given type name is used as the exception type in a ca
tch clause |
| 9999 */ | 9965 */ |
| 10000 bool _isTypeNameInCatchClause(TypeName typeName) { | 9966 bool _isTypeNameInCatchClause(TypeName typeName) { |
| 10001 AstNode parent = typeName.parent; | 9967 AstNode parent = typeName.parent; |
| 10002 if (parent is CatchClause) { | 9968 if (parent is CatchClause) { |
| 10003 CatchClause catchClause = parent; | 9969 return identical(parent.exceptionType, typeName); |
| 10004 return identical(catchClause.exceptionType, typeName); | |
| 10005 } | 9970 } |
| 10006 return false; | 9971 return false; |
| 10007 } | 9972 } |
| 10008 | 9973 |
| 10009 /** | 9974 /** |
| 10010 * Checks if the given type name is used as the type in an instance creation e
xpression. | 9975 * Checks if the given type name is used as the type in an instance creation e
xpression. |
| 10011 * | 9976 * |
| 10012 * @param typeName the type name to analyzer | 9977 * @param typeName the type name to analyzer |
| 10013 * @return `true` if the given type name is used as the type in an instance cr
eation | 9978 * @return `true` if the given type name is used as the type in an instance cr
eation |
| 10014 * expression | 9979 * expression |
| 10015 */ | 9980 */ |
| 10016 bool _isTypeNameInInstanceCreationExpression(TypeName typeName) { | 9981 bool _isTypeNameInInstanceCreationExpression(TypeName typeName) { |
| 10017 AstNode parent = typeName.parent; | 9982 AstNode parent = typeName.parent; |
| 10018 if (parent is ConstructorName && | 9983 if (parent is ConstructorName && |
| 10019 parent.parent is InstanceCreationExpression) { | 9984 parent.parent is InstanceCreationExpression) { |
| 10020 ConstructorName constructorName = parent; | 9985 return parent != null && identical(parent.type, typeName); |
| 10021 return constructorName != null && | |
| 10022 identical(constructorName.type, typeName); | |
| 10023 } | 9986 } |
| 10024 return false; | 9987 return false; |
| 10025 } | 9988 } |
| 10026 | 9989 |
| 10027 /** | 9990 /** |
| 10028 * Checks if the given type name is used as the type in an is expression. | 9991 * Checks if the given type name is used as the type in an is expression. |
| 10029 * | 9992 * |
| 10030 * @param typeName the type name to analyzer | 9993 * @param typeName the type name to analyzer |
| 10031 * @return `true` if the given type name is used as the type in an is expressi
on | 9994 * @return `true` if the given type name is used as the type in an is expressi
on |
| 10032 */ | 9995 */ |
| 10033 bool _isTypeNameInIsExpression(TypeName typeName) { | 9996 bool _isTypeNameInIsExpression(TypeName typeName) { |
| 10034 AstNode parent = typeName.parent; | 9997 AstNode parent = typeName.parent; |
| 10035 if (parent is IsExpression) { | 9998 if (parent is IsExpression) { |
| 10036 IsExpression isExpression = parent; | 9999 return identical(parent.type, typeName); |
| 10037 return identical(isExpression.type, typeName); | |
| 10038 } | 10000 } |
| 10039 return false; | 10001 return false; |
| 10040 } | 10002 } |
| 10041 | 10003 |
| 10042 /** | 10004 /** |
| 10043 * Checks if the given type name used in a type argument list. | 10005 * Checks if the given type name used in a type argument list. |
| 10044 * | 10006 * |
| 10045 * @param typeName the type name to analyzer | 10007 * @param typeName the type name to analyzer |
| 10046 * @return `true` if the given type name is in a type argument list | 10008 * @return `true` if the given type name is in a type argument list |
| 10047 */ | 10009 */ |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10224 return token.type == TokenType.KEYWORD; | 10186 return token.type == TokenType.KEYWORD; |
| 10225 } | 10187 } |
| 10226 | 10188 |
| 10227 /** | 10189 /** |
| 10228 * @return `true` if given [TypeName] is used as a type annotation. | 10190 * @return `true` if given [TypeName] is used as a type annotation. |
| 10229 */ | 10191 */ |
| 10230 static bool _isTypeAnnotation(TypeName node) { | 10192 static bool _isTypeAnnotation(TypeName node) { |
| 10231 AstNode parent = node.parent; | 10193 AstNode parent = node.parent; |
| 10232 if (parent is VariableDeclarationList) { | 10194 if (parent is VariableDeclarationList) { |
| 10233 return identical(parent.type, node); | 10195 return identical(parent.type, node); |
| 10234 } | 10196 } else if (parent is FieldFormalParameter) { |
| 10235 if (parent is FieldFormalParameter) { | |
| 10236 return identical(parent.type, node); | 10197 return identical(parent.type, node); |
| 10237 } | 10198 } else if (parent is SimpleFormalParameter) { |
| 10238 if (parent is SimpleFormalParameter) { | |
| 10239 return identical(parent.type, node); | 10199 return identical(parent.type, node); |
| 10240 } | 10200 } |
| 10241 return false; | 10201 return false; |
| 10242 } | 10202 } |
| 10243 } | 10203 } |
| 10244 | 10204 |
| 10245 /** | 10205 /** |
| 10246 * Instances of the class [UnusedLocalElementsVerifier] traverse an element | 10206 * Instances of the class [UnusedLocalElementsVerifier] traverse an element |
| 10247 * structure looking for cases of [HintCode.UNUSED_ELEMENT], | 10207 * structure looking for cases of [HintCode.UNUSED_ELEMENT], |
| 10248 * [HintCode.UNUSED_FIELD], [HintCode.UNUSED_LOCAL_VARIABLE], etc. | 10208 * [HintCode.UNUSED_FIELD], [HintCode.UNUSED_LOCAL_VARIABLE], etc. |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10776 return null; | 10736 return null; |
| 10777 } | 10737 } |
| 10778 if (identical(node.staticElement, variable)) { | 10738 if (identical(node.staticElement, variable)) { |
| 10779 if (node.inSetterContext()) { | 10739 if (node.inSetterContext()) { |
| 10780 result = true; | 10740 result = true; |
| 10781 } | 10741 } |
| 10782 } | 10742 } |
| 10783 return null; | 10743 return null; |
| 10784 } | 10744 } |
| 10785 } | 10745 } |
| OLD | NEW |