Skip to content

Commit 59c6313

Browse files
committed
set thisType for functions and void types
Change-Id: I7886d02b982bd0303074cb4c2370a9bc72258d58 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112261 Reviewed-by: Brian Wilkerson <[email protected]>
1 parent 3f4ccc1 commit 59c6313

File tree

4 files changed

+74
-5
lines changed

4 files changed

+74
-5
lines changed

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3815,10 +3815,7 @@ class ResolverVisitor extends ScopedVisitor {
38153815
//
38163816
try {
38173817
DartType extendedType = node.declaredElement.extendedType;
3818-
if (extendedType is InterfaceType) {
3819-
// TODO(brianwilkerson) Handle other cases.
3820-
typeAnalyzer.thisType = extendedType;
3821-
}
3818+
typeAnalyzer.thisType = typeSystem.resolveToBound(extendedType);
38223819
super.visitExtensionDeclaration(node);
38233820
node.accept(elementResolver);
38243821
node.accept(typeAnalyzer);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<void> {
6969
* The type representing the class containing the nodes being analyzed,
7070
* or `null` if the nodes are not within a class.
7171
*/
72-
InterfaceType thisType;
72+
DartType thisType;
7373

7474
/**
7575
* The object providing promoted or declared types of variables.

pkg/analyzer/test/src/dart/resolution/extension_method_test.dart

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,26 @@ f(C c) {
195195
/// by code external to the extension declaration.
196196
@reflectiveTest
197197
class ExtensionMethodsExternalReferenceTest extends BaseExtensionMethodsTest {
198+
/// Corresponds to: extension_member_resolution_t07
199+
test_dynamicInvocation() async {
200+
await assertNoErrorsInCode(r'''
201+
class A {}
202+
class C extends A {
203+
String method(int i) => "$i";
204+
noSuchMethod(Invocation i) { }
205+
}
206+
207+
extension E<T extends A> on T {
208+
String method(int i, String s) => '';
209+
}
210+
211+
main() {
212+
dynamic c = new C();
213+
c.method(42, "-42");
214+
}
215+
''');
216+
}
217+
198218
test_instance_call_fromExtendedType() async {
199219
await assertNoErrorsInCode('''
200220
class C {
@@ -1014,6 +1034,35 @@ f() => E.a;
10141034
assertElement(identifier, findElement.method('a'));
10151035
assertType(identifier, 'void Function(int)');
10161036
}
1037+
1038+
test_thisAccessOnDynamic() async {
1039+
await assertNoErrorsInCode('''
1040+
extension on dynamic {
1041+
int get d => 3;
1042+
1043+
void testDynamic() {
1044+
// Static type of `this` is dynamic, allows dynamic invocation.
1045+
this.arglebargle();
1046+
}
1047+
}
1048+
''');
1049+
}
1050+
1051+
test_thisAccessOnFunction() async {
1052+
await assertNoErrorsInCode('''
1053+
extension on Function {
1054+
int get f => 4;
1055+
1056+
void testFunction() {
1057+
// Static type of `this` is Function. Allows any dynamic invocation.
1058+
this();
1059+
this(1);
1060+
this(x: 1);
1061+
// No function can have both optional positional and named parameters.
1062+
}
1063+
}
1064+
''');
1065+
}
10171066
}
10181067

10191068
/// Tests that extension members can be correctly resolved when referenced

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'package:analyzer/dart/analysis/features.dart';
56
import 'package:analyzer/src/dart/analysis/experiments.dart';
67
import 'package:analyzer/src/error/codes.dart';
78
import 'package:analyzer/src/generated/engine.dart';
@@ -13,6 +14,7 @@ import '../dart/resolution/driver_resolution.dart';
1314
main() {
1415
defineReflectiveSuite(() {
1516
defineReflectiveTests(UseOfVoidResultTest);
17+
defineReflectiveTests(UseOfVoidResultWithExtensionMethodsTest);
1618
defineReflectiveTests(UseOfVoidResultTest_NonNullable);
1719
});
1820
}
@@ -567,3 +569,24 @@ g() {
567569
''', [ExpectedError(StaticWarningCode.USE_OF_VOID_RESULT, 23, 4)]);
568570
}
569571
}
572+
573+
@reflectiveTest
574+
class UseOfVoidResultWithExtensionMethodsTest extends UseOfVoidResultTest {
575+
@override
576+
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
577+
..contextFeatures = FeatureSet.forTesting(
578+
sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
579+
580+
test_useOfVoidReturnInExtensionMethod() async {
581+
await assertErrorsInCode('''
582+
extension on void {
583+
testVoid() {
584+
// No access on void. Static type of `this` is void!
585+
this.toString();
586+
}
587+
}
588+
''', [
589+
error(StaticWarningCode.USE_OF_VOID_RESULT, 96, 4),
590+
]);
591+
}
592+
}

0 commit comments

Comments
 (0)