Flow analysis is not available outside of function bodies and initializers.
This fixes a group of crashes during fuzz testing.
FAILURE: z({=?[
[NoSuchMethodError: The getter 'flow' was called on null.
Receiver: null
Tried calling: flow
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 ResolverVisitor.startNullAwareIndexExpression (package:analyzer/src/generated/resolver.dart:743:21)
#2 ResolverVisitor.visitIndexExpression (package:analyzer/src/generated/resolver.dart:1552:5)
#3 IndexExpressionImpl.accept (package:analyzer/src/dart/ast/ast.dart:5993:49)
#4 AstResolver.resolve (package:analyzer/src/summary2/ast_resolver.dart:85:10)
#5 DefaultValueResolver._parameter (package:analyzer/src/summary2/default_value_resolver.dart:107:18)
#6 DefaultValueResolver._parameters (package:analyzer/src/summary2/default_value_resolver.dart:121:7)
#7 DefaultValueResolver._function (package:analyzer/src/summary2/default_value_resolver.dart:89:5)
#8 DefaultValueResolver.resolve (package:analyzer/src/summary2/default_value_resolver.dart:47:9)
#9 LibraryBuilder.resolveDefaultValues (package:analyzer/src/summary2/library_builder.dart:313:43)
#10 Linker._resolveDefaultValues (package:analyzer/src/summary2/link.dart:230:15)
#11 Linker._buildOutlines (package:analyzer/src/summary2/link.dart:89:5)
#12 Linker.link (package:analyzer/src/summary2/link.dart:69:5)
#13 link (package:analyzer/src/summary2/link.dart:33:10)
Change-Id: I6145a1f728d432be8d0fa55235858e091030461c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175187
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 6fbe5f2..21b7d76 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -739,7 +739,7 @@
void startNullAwareIndexExpression(IndexExpression node) {
if (_migratableAstInfoProvider.isIndexExpressionNullAware(node) &&
- _isNonNullableByDefault) {
+ _flowAnalysis != null) {
_flowAnalysis.flow.nullAwareAccess_rightBegin(
node.target, node.realTarget.staticType ?? typeProvider.dynamicType);
_unfinishedNullShorts.add(node.nullShortingTermination);
@@ -750,7 +750,7 @@
PropertyAccess node,
) {
if (_migratableAstInfoProvider.isPropertyAccessNullAware(node) &&
- _isNonNullableByDefault) {
+ _flowAnalysis != null) {
var target = node.target;
if (target is SimpleIdentifier && target.staticElement is ClassElement) {
// `?.` to access static methods is equivalent to `.`, so do nothing.
@@ -948,7 +948,7 @@
InferenceContext.setTypeFromNode(node.target, node);
node.target.accept(this);
- if (node.isNullAware && _isNonNullableByDefault) {
+ if (node.isNullAware && _flowAnalysis != null) {
_flowAnalysis.flow.nullAwareAccess_rightBegin(
node.target, node.target.staticType ?? typeProvider.dynamicType);
_unfinishedNullShorts.add(node.nullShortingTermination);
@@ -1652,7 +1652,7 @@
target?.accept(this);
if (_migratableAstInfoProvider.isMethodInvocationNullAware(node) &&
- _isNonNullableByDefault) {
+ _flowAnalysis != null) {
if (target is SimpleIdentifier && target.staticElement is ClassElement) {
// `?.` to access static methods is equivalent to `.`, so do nothing.
} else {
diff --git a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
index 9652773..fc67be62 100644
--- a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
@@ -16,6 +16,19 @@
@reflectiveTest
class IndexExpressionTest extends PubPackageResolutionTest {
+ test_invalid_inDefaultValue_nullAware() async {
+ await assertInvalidTestCode(r'''
+void f({a = b?[0]}) {}
+''');
+
+ assertIndexExpression(
+ findNode.index('[0]'),
+ readElement: null,
+ writeElement: null,
+ type: 'dynamic',
+ );
+ }
+
test_read() async {
await assertNoErrorsInCode(r'''
class A {
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index c1ff99b..92450fb 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -1703,6 +1703,20 @@
assertSuperExpression(invocation.target);
}
+ test_invalid_inDefaultValue_nullAware() async {
+ await assertInvalidTestCode('''
+void f({a = b?.foo()}) {}
+''');
+
+ assertMethodInvocation2(
+ findNode.methodInvocation('?.foo()'),
+ element: null,
+ typeArgumentTypes: [],
+ invokeType: 'dynamic',
+ type: 'dynamic',
+ );
+ }
+
test_namedArgument() async {
var question = typeToStringWithNullability ? '?' : '';
await assertNoErrorsInCode('''
diff --git a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
index 313cd97..645d77a 100644
--- a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
@@ -238,6 +238,30 @@
}
}
+ test_invalid_inDefaultValue_nullAware() async {
+ await assertInvalidTestCode('''
+void f({a = b?.foo}) {}
+''');
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('?.foo'),
+ element: null,
+ type: 'dynamic',
+ );
+ }
+
+ test_invalid_inDefaultValue_nullAware_cascade() async {
+ await assertInvalidTestCode('''
+void f({a = b?..foo}) {}
+''');
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('?..foo'),
+ element: null,
+ type: 'dynamic',
+ );
+ }
+
test_ofExtension_read() async {
await assertNoErrorsInCode('''
class A {}
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index b91cab9..5e7e81c 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -448,6 +448,13 @@
expectedPrefix: expectedPrefix);
}
+ /// Resolve the [code], and ensure that it can be resolved without a crash,
+ /// and is invalid, i.e. produces a diagnostic.
+ Future<void> assertInvalidTestCode(String code) async {
+ await resolveTestCode(code);
+ assertHasTestErrors();
+ }
+
void assertInvokeType(Expression node, String expected) {
DartType actual;
if (node is BinaryExpression) {