Skip to content

Commit 4895185

Browse files
bwilkersoncommit-bot@chromium.org
authored andcommitted
Fix NPE when extension override is invoked without a call method (issue 38505)
Change-Id: Ia2ad1168441cf07e379184ad82f592701f5ef2bc Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/118481 Commit-Queue: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
1 parent 381d808 commit 4895185

File tree

5 files changed

+62
-5
lines changed

5 files changed

+62
-5
lines changed

pkg/analyzer/lib/error/error.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ const List<ErrorCode> errorCodeValues = const [
196196
CompileTimeErrorCode.INVALID_URI,
197197
CompileTimeErrorCode.INVALID_USE_OF_COVARIANT,
198198
CompileTimeErrorCode.INVALID_USE_OF_COVARIANT_IN_EXTENSION,
199+
CompileTimeErrorCode.INVOCATION_OF_EXTENSION_WITHOUT_CALL,
199200
CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE,
200201
CompileTimeErrorCode.LABEL_UNDEFINED,
201202
CompileTimeErrorCode.MAP_ENTRY_NOT_IN_MAP,

pkg/analyzer/lib/src/error/codes.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,6 +2333,16 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
23332333
static const CompileTimeErrorCode INVALID_URI =
23342334
const CompileTimeErrorCode('INVALID_URI', "Invalid URI syntax: '{0}'.");
23352335

2336+
/**
2337+
* Parameters:
2338+
* 0: the name of the extension
2339+
*/
2340+
static const CompileTimeErrorCode INVOCATION_OF_EXTENSION_WITHOUT_CALL =
2341+
const CompileTimeErrorCode(
2342+
'INVOCATION_OF_EXTENSION_WITHOUT_CALL',
2343+
"The extension '{0}' does not define a 'call' method so the override "
2344+
"can't be used in an invocation.");
2345+
23362346
/**
23372347
* 13.13 Break: It is a compile-time error if no such statement
23382348
* <i>s<sub>E</sub></i> exists within the innermost function in which

pkg/analyzer/lib/src/generated/element_resolver.dart

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -397,13 +397,21 @@ class ElementResolver extends SimpleAstVisitor<void> {
397397
DartType functionType;
398398
if (function is ExtensionOverride) {
399399
var member = _extensionResolver.getOverrideMember(function, 'call');
400-
if (member != null && member.isStatic) {
400+
if (member == null) {
401401
_resolver.errorReporter.reportErrorForNode(
402-
CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER,
403-
node.argumentList);
402+
CompileTimeErrorCode.INVOCATION_OF_EXTENSION_WITHOUT_CALL,
403+
function,
404+
[function.extensionName.name]);
405+
functionType = _resolver.typeProvider.dynamicType;
406+
} else {
407+
if (member.isStatic) {
408+
_resolver.errorReporter.reportErrorForNode(
409+
CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER,
410+
node.argumentList);
411+
}
412+
node.staticElement = member;
413+
functionType = member.type;
404414
}
405-
node.staticElement = member;
406-
functionType = member.type;
407415
} else {
408416
functionType = function.staticType;
409417
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
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.
4+
5+
import 'package:analyzer/dart/analysis/features.dart';
6+
import 'package:analyzer/src/error/codes.dart';
7+
import 'package:analyzer/src/generated/engine.dart';
8+
import 'package:test_reflective_loader/test_reflective_loader.dart';
9+
10+
import '../dart/resolution/driver_resolution.dart';
11+
12+
main() {
13+
defineReflectiveSuite(() {
14+
defineReflectiveTests(InvocationOfExtensionWithoutCallTest);
15+
});
16+
}
17+
18+
@reflectiveTest
19+
class InvocationOfExtensionWithoutCallTest extends DriverResolutionTest {
20+
@override
21+
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
22+
..contextFeatures = new FeatureSet.forTesting(
23+
sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
24+
25+
test_instance_differentKind() async {
26+
await assertErrorsInCode('''
27+
extension E on Object {}
28+
f() {
29+
E(null)();
30+
}
31+
''', [
32+
error(CompileTimeErrorCode.INVOCATION_OF_EXTENSION_WITHOUT_CALL, 33, 7),
33+
]);
34+
}
35+
}

pkg/analyzer/test/src/diagnostics/test_all.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ import 'invalid_use_of_visible_for_testing_member_test.dart'
149149
as invalid_use_of_visible_for_testing_member;
150150
import 'invalid_visibility_annotation_test.dart'
151151
as invalid_visibility_annotation;
152+
import 'invocation_of_extension_without_call_test.dart'
153+
as invocation_of_extension_without_call;
152154
import 'is_double_test.dart' as is_double;
153155
import 'is_int_test.dart' as is_int;
154156
import 'is_not_double_test.dart' as is_not_double;
@@ -428,6 +430,7 @@ main() {
428430
invalid_use_of_visible_for_template_member.main();
429431
invalid_use_of_visible_for_testing_member.main();
430432
invalid_visibility_annotation.main();
433+
invocation_of_extension_without_call.main();
431434
is_double.main();
432435
is_int.main();
433436
is_not_double.main();

0 commit comments

Comments
 (0)