Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: pkg/analyzer/lib/src/task/strong/checker.dart

Issue 2219653005: Disallow uninitialized non-nullable variables (Closed) Base URL: https://github.com/dart-lang/sdk@master
Patch Set: Fix build break Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/error.dart ('k') | pkg/analyzer/test/src/task/strong/non_null_checker_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698