Support for parameters of constructors and methods.
R=brianwilkerson@google.com, paulberry@google.com
Change-Id: I836978414ce765269a8482f1649c400b2d4c960c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107193
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
index d2a5827..da6af12 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -327,16 +327,12 @@
_FunctionBodyAccess(node),
);
- var function = node.parent;
- if (function is FunctionExpression) {
- var parameters = function.parameters;
- if (parameters != null) {
- for (var parameter in parameters?.parameters) {
- flow.add(parameter.declaredElement, assigned: true);
- }
+ var parameters = _enclosingExecutableParameters(node);
+ if (parameters != null) {
+ for (var parameter in parameters.parameters) {
+ flow.add(parameter.declaredElement, assigned: true);
}
}
- // TODO(scheglov) Methods and constructors.
super.visitBlockFunctionBody(node);
@@ -703,6 +699,20 @@
unreachableNodes.add(node);
}
+ FormalParameterList _enclosingExecutableParameters(FunctionBody node) {
+ var parent = node.parent;
+ if (parent is ConstructorDeclaration) {
+ return parent.parameters;
+ }
+ if (parent is FunctionExpression) {
+ return parent.parameters;
+ }
+ if (parent is MethodDeclaration) {
+ return parent.parameters;
+ }
+ return null;
+ }
+
/// Return the target of the `break` or `continue` statement with the
/// [element] label. The [element] might be `null` (when the statement does
/// not specify a label), so the default enclosing target is returned.
diff --git a/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart b/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
index 77ad390..f9cb0c4 100644
--- a/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
@@ -1489,6 +1489,38 @@
assertNonNullable('x; // 2');
}
+ test_method_if_then_else() async {
+ await trackCode(r'''
+class C {
+ void f(int x) {
+ if (x == null) {
+ x; // 1
+ } else {
+ x; // 2
+ }
+ }
+}
+''');
+ assertNullable('x; // 1');
+ assertNonNullable('x; // 2');
+ }
+
+ test_constructor_if_then_else() async {
+ await trackCode(r'''
+class C {
+ C(int x) {
+ if (x == null) {
+ x; // 1
+ } else {
+ x; // 2
+ }
+ }
+}
+''');
+ assertNullable('x; // 1');
+ assertNonNullable('x; // 2');
+ }
+
test_potentiallyMutatedInClosure() async {
await trackCode(r'''
f(int a, int b) {