Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be | 5 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be |
| 6 // refactored to fit into analyzer. | 6 // refactored to fit into analyzer. |
| 7 library analyzer.src.task.strong.checker; | 7 library analyzer.src.task.strong.checker; |
| 8 | 8 |
| 9 import 'package:analyzer/analyzer.dart'; | 9 import 'package:analyzer/analyzer.dart'; |
| 10 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 334 node.visitChildren(this); | 334 node.visitChildren(this); |
| 335 } | 335 } |
| 336 | 336 |
| 337 @override | 337 @override |
| 338 void visitExpressionFunctionBody(ExpressionFunctionBody node) { | 338 void visitExpressionFunctionBody(ExpressionFunctionBody node) { |
| 339 _checkReturnOrYield(node.expression, node); | 339 _checkReturnOrYield(node.expression, node); |
| 340 node.visitChildren(this); | 340 node.visitChildren(this); |
| 341 } | 341 } |
| 342 | 342 |
| 343 @override | 343 @override |
| 344 void visitFieldDeclaration(FieldDeclaration node) { | |
| 345 _checkForNonNullNotInitialized(node.fields); | |
| 346 super.visitFieldDeclaration(node); | |
| 347 } | |
| 348 | |
| 349 @override | |
| 344 void visitFieldFormalParameter(FieldFormalParameter node) { | 350 void visitFieldFormalParameter(FieldFormalParameter node) { |
| 345 var element = node.element; | 351 var element = node.element; |
| 346 var typeName = node.type; | 352 var typeName = node.type; |
| 347 if (typeName != null) { | 353 if (typeName != null) { |
| 348 var type = _elementType(element); | 354 var type = _elementType(element); |
| 349 var fieldElement = | 355 var fieldElement = |
| 350 node.identifier.staticElement as FieldFormalParameterElement; | 356 node.identifier.staticElement as FieldFormalParameterElement; |
| 351 var fieldType = _elementType(fieldElement.field); | 357 var fieldType = _elementType(fieldElement.field); |
| 352 if (!rules.isSubtypeOf(type, fieldType)) { | 358 if (!rules.isSubtypeOf(type, fieldType)) { |
| 353 _recordMessage(node, StrongModeCode.INVALID_PARAMETER_DECLARATION, | 359 _recordMessage(node, StrongModeCode.INVALID_PARAMETER_DECLARATION, |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 595 void visitSuperConstructorInvocation(SuperConstructorInvocation node) { | 601 void visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
| 596 var element = node.staticElement; | 602 var element = node.staticElement; |
| 597 if (element != null) { | 603 if (element != null) { |
| 598 var type = node.staticElement.type; | 604 var type = node.staticElement.type; |
| 599 checkArgumentList(node.argumentList, type); | 605 checkArgumentList(node.argumentList, type); |
| 600 } | 606 } |
| 601 node.visitChildren(this); | 607 node.visitChildren(this); |
| 602 } | 608 } |
| 603 | 609 |
| 604 @override | 610 @override |
| 611 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { | |
| 612 _checkForNonNullNotInitialized(node.variables); | |
| 613 return super.visitTopLevelVariableDeclaration(node); | |
| 614 } | |
| 615 | |
| 616 @override | |
| 605 void visitSwitchStatement(SwitchStatement node) { | 617 void visitSwitchStatement(SwitchStatement node) { |
| 606 // SwitchStatement defines a boolean conversion to check the result of the | 618 // SwitchStatement defines a boolean conversion to check the result of the |
| 607 // case value == the switch value, but in dev_compiler we require a boolean | 619 // case value == the switch value, but in dev_compiler we require a boolean |
| 608 // return type from an overridden == operator (because Object.==), so | 620 // return type from an overridden == operator (because Object.==), so |
| 609 // checking in SwitchStatement shouldn't be necessary. | 621 // checking in SwitchStatement shouldn't be necessary. |
| 610 node.visitChildren(this); | 622 node.visitChildren(this); |
| 611 } | 623 } |
| 612 | 624 |
| 613 @override | 625 @override |
| 614 void visitVariableDeclarationList(VariableDeclarationList node) { | 626 void visitVariableDeclarationList(VariableDeclarationList node) { |
| 615 TypeName type = node.type; | 627 TypeName type = node.type; |
| 616 if (type == null) { | 628 if (type == null) { |
| 617 // No checks are needed when the type is var. Although internally the | 629 // No checks are needed when the type is var. Although internally the |
| 618 // typing rules may have inferred a more precise type for the variable | 630 // typing rules may have inferred a more precise type for the variable |
| 619 // based on the initializer. | 631 // based on the initializer. |
| 620 } else { | 632 } else { |
| 621 for (VariableDeclaration variable in node.variables) { | 633 for (VariableDeclaration variable in node.variables) { |
| 622 var initializer = variable.initializer; | 634 var initializer = variable.initializer; |
| 623 if (initializer != null) { | 635 if (initializer != null) { |
| 624 checkAssignment(initializer, type.type); | 636 checkAssignment(initializer, type.type); |
| 625 } | 637 } |
| 626 } | 638 } |
| 627 } | 639 } |
| 628 node.visitChildren(this); | 640 node.visitChildren(this); |
| 629 } | 641 } |
| 630 | 642 |
| 631 @override | 643 @override |
| 644 Object visitVariableDeclarationStatement(VariableDeclarationStatement node) { | |
| 645 _checkForNonNullNotInitialized(node.variables); | |
| 646 return super.visitVariableDeclarationStatement(node); | |
| 647 } | |
| 648 | |
| 649 @override | |
| 632 void visitWhileStatement(WhileStatement node) { | 650 void visitWhileStatement(WhileStatement node) { |
| 633 checkBoolean(node.condition); | 651 checkBoolean(node.condition); |
| 634 node.visitChildren(this); | 652 node.visitChildren(this); |
| 635 } | 653 } |
| 636 | 654 |
| 637 @override | 655 @override |
| 638 void visitYieldStatement(YieldStatement node) { | 656 void visitYieldStatement(YieldStatement node) { |
| 639 _checkReturnOrYield(node.expression, node, yieldStar: node.star != null); | 657 _checkReturnOrYield(node.expression, node, yieldStar: node.star != null); |
| 640 node.visitChildren(this); | 658 node.visitChildren(this); |
| 641 } | 659 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 738 | 756 |
| 739 void _checkFieldAccess(AstNode node, AstNode target, SimpleIdentifier field) { | 757 void _checkFieldAccess(AstNode node, AstNode target, SimpleIdentifier field) { |
| 740 if ((_isDynamicTarget(target) || field.staticElement == null) && | 758 if ((_isDynamicTarget(target) || field.staticElement == null) && |
| 741 !_isObjectProperty(target, field)) { | 759 !_isObjectProperty(target, field)) { |
| 742 _recordDynamicInvoke(node, target); | 760 _recordDynamicInvoke(node, target); |
| 743 } | 761 } |
| 744 node.visitChildren(this); | 762 node.visitChildren(this); |
| 745 } | 763 } |
| 746 | 764 |
| 747 /** | 765 /** |
| 766 * | |
|
Jennifer Messerly
2016/08/05 17:39:31
missing doc comment here?
| |
| 767 */ | |
| 768 void _checkForNonNullNotInitialized(VariableDeclarationList list) { | |
|
Jennifer Messerly
2016/08/05 17:39:31
you might be able to put this logic in visitVariab
stanm
2016/08/05 18:06:52
Awesome! Thanks!
| |
| 769 NodeList<VariableDeclaration> variables = list.variables; | |
| 770 for (VariableDeclaration variable in variables) { | |
| 771 if (!list.isConst && | |
| 772 !list.isFinal && | |
| 773 variable.initializer == null && | |
| 774 rules.isNonNullableType(list?.type?.type)) { | |
| 775 _recordMessage( | |
| 776 variable, | |
| 777 StaticTypeWarningCode.NON_NULLABLE_FIELD_NOT_INITIALIZED, | |
| 778 [variable.name, list?.type?.type]); | |
| 779 } | |
| 780 } | |
| 781 } | |
| 782 | |
| 783 /** | |
| 748 * Check if the closure [node] is unsafe due to dartbug.com/26947. If so, | 784 * Check if the closure [node] is unsafe due to dartbug.com/26947. If so, |
| 749 * issue a warning. | 785 * issue a warning. |
| 750 * | 786 * |
| 751 * TODO(paulberry): eliminate this once dartbug.com/26947 is fixed. | 787 * TODO(paulberry): eliminate this once dartbug.com/26947 is fixed. |
| 752 */ | 788 */ |
| 753 void _checkForUnsafeBlockClosureInference(FunctionExpression node) { | 789 void _checkForUnsafeBlockClosureInference(FunctionExpression node) { |
| 754 if (node.body is! BlockFunctionBody) { | 790 if (node.body is! BlockFunctionBody) { |
| 755 return; | 791 return; |
| 756 } | 792 } |
| 757 if (node.element.returnType.isDynamic) { | 793 if (node.element.returnType.isDynamic) { |
| (...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1489 var visited = new Set<InterfaceType>(); | 1525 var visited = new Set<InterfaceType>(); |
| 1490 do { | 1526 do { |
| 1491 visited.add(current); | 1527 visited.add(current); |
| 1492 current.mixins.reversed.forEach( | 1528 current.mixins.reversed.forEach( |
| 1493 (m) => _checkIndividualOverridesFromClass(node, m, seen, true)); | 1529 (m) => _checkIndividualOverridesFromClass(node, m, seen, true)); |
| 1494 _checkIndividualOverridesFromClass(node, current.superclass, seen, true); | 1530 _checkIndividualOverridesFromClass(node, current.superclass, seen, true); |
| 1495 current = current.superclass; | 1531 current = current.superclass; |
| 1496 } while (!current.isObject && !visited.contains(current)); | 1532 } while (!current.isObject && !visited.contains(current)); |
| 1497 } | 1533 } |
| 1498 } | 1534 } |
| OLD | NEW |