Issue 44780. Fix reporing accessing instance from static when enclosed in local variable.
Bug: https://github.com/dart-lang/sdk/issues/44780
Change-Id: Iec59d928161b68ecf77f95792bd6e9ac8ca0d462
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/181305
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index b275202..c9a953d 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -114,26 +114,28 @@
DartType get returnType => catchErrorOnErrorReturnType ?? element.returnType;
- static bool _inFactoryConstructor(ExecutableElement element) {
+ static bool _inFactoryConstructor(Element element) {
+ var enclosing = element?.enclosingElement;
+ if (enclosing == null) {
+ return false;
+ }
if (element is ConstructorElement) {
return element.isFactory;
}
- var enclosing = element?.enclosingElement;
- if (enclosing is ExecutableElement) {
- return _inFactoryConstructor(enclosing);
- }
- return false;
+ return _inFactoryConstructor(enclosing);
}
- static bool _inStaticMethod(ExecutableElement element) {
+ static bool _inStaticMethod(Element element) {
var enclosing = element?.enclosingElement;
+ if (enclosing == null) {
+ return false;
+ }
if (enclosing is ClassElement || enclosing is ExtensionElement) {
- return element.isStatic;
+ if (element is ExecutableElement) {
+ return element.isStatic;
+ }
}
- if (enclosing is ExecutableElement) {
- return _inStaticMethod(enclosing);
- }
- return false;
+ return _inStaticMethod(enclosing);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/instance_member_access_from_factory_test.dart b/pkg/analyzer/test/src/diagnostics/instance_member_access_from_factory_test.dart
index 8791394..d4de128 100644
--- a/pkg/analyzer/test/src/diagnostics/instance_member_access_from_factory_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/instance_member_access_from_factory_test.dart
@@ -15,66 +15,97 @@
@reflectiveTest
class InstanceMemberAccessFromFactoryTest extends PubPackageResolutionTest {
- test_named() async {
+ test_named_getter() async {
await assertErrorsInCode(r'''
class A {
- m() {}
- A();
+ int get foo => 0;
+
factory A.make() {
- m();
- return new A();
+ foo;
+ throw 0;
}
}
''', [
- error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, 51, 1),
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, 56, 3),
]);
}
- test_property() async {
+ test_named_getter_localFunction() async {
await assertErrorsInCode(r'''
class A {
- int m;
- A();
- factory A.make() {
- m;
- return new A();
- }
-}
-''', [
- error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, 51, 1),
- ]);
- }
+ int get foo => 0;
- test_property_fromClosure() async {
- await assertErrorsInCode(r'''
-class A {
- int m;
- A();
factory A.make() {
void f() {
- m;
+ foo;
}
f();
- return new A();
+ throw 0;
}
}
''', [
- error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, 68, 1),
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, 73, 3),
]);
}
- test_unnamed() async {
+ test_named_method() async {
await assertErrorsInCode(r'''
class A {
- m() {}
- A._();
- factory A() {
- m();
- return new A._();
+ void foo() {}
+
+ factory A.make() {
+ foo();
+ throw 0;
}
}
''', [
- error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, 48, 1),
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, 52, 3),
+ ]);
+ }
+
+ test_named_method_functionExpression() async {
+ await assertErrorsInCode(r'''
+class A {
+ void foo() {}
+
+ factory A.make() {
+ () => foo();
+ throw 0;
+ }
+}
+''', [
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, 58, 3),
+ ]);
+ }
+
+ test_named_method_functionExpression_localVariable() async {
+ await assertErrorsInCode(r'''
+class A {
+ void foo() {}
+
+ factory A.make() {
+ // ignore:unused_local_variable
+ var x = () => foo();
+ throw 0;
+ }
+}
+''', [
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, 102, 3),
+ ]);
+ }
+
+ test_unnamed_method() async {
+ await assertErrorsInCode(r'''
+class A {
+ void foo() {}
+
+ factory A() {
+ foo();
+ throw 0;
+ }
+}
+''', [
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, 47, 3),
]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/instance_member_access_from_static_test.dart b/pkg/analyzer/test/src/diagnostics/instance_member_access_from_static_test.dart
index c1a122b..f56d41a 100644
--- a/pkg/analyzer/test/src/diagnostics/instance_member_access_from_static_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/instance_member_access_from_static_test.dart
@@ -61,6 +61,35 @@
]);
}
+ test_class_thisGetter_fromMethod_functionExpression() async {
+ await assertErrorsInCode(r'''
+class A {
+ int get foo => 0;
+
+ static void bar() {
+ () => foo;
+ }
+}
+''', [
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, 63, 3),
+ ]);
+ }
+
+ test_class_thisGetter_fromMethod_functionExpression_localVariable() async {
+ await assertErrorsInCode(r'''
+class A {
+ int get foo => 0;
+
+ static void bar() {
+ // ignore:unused_local_variable
+ var x = () => foo;
+ }
+}
+''', [
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, 107, 3),
+ ]);
+ }
+
test_class_thisMethod_fromMethod() async {
await assertErrorsInCode(r'''
class A {