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 |