Report invalid mustCallSuper annotation targets

Fixes https://github.com/dart-lang/sdk/issues/49499

Change-Id: Ibea55a78b58ee83b9290c33bca5e69039c995d55
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/252865
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Phil Quitslund <pquitslund@google.com>
This commit is contained in:
Sam Rawlins 2022-07-28 17:48:15 +00:00 committed by Commit Bot
parent 20bc34c8ac
commit d77ded508e
4 changed files with 185 additions and 2 deletions

View file

@ -190,13 +190,19 @@ class BestPracticesVerifier extends RecursiveAstVisitor<void> {
}
} else if (element.isMustBeOverridden) {
if ((parent is MethodDeclaration && parent.isStatic) ||
(parent is FieldDeclaration && parent.isStatic)) {
(parent is FieldDeclaration && parent.isStatic) ||
parent.parent is ExtensionDeclaration ||
parent.parent is EnumDeclaration) {
_errorReporter.reportErrorForNode(
HintCode.INVALID_ANNOTATION_TARGET,
node,
[node.name.name, 'instance members of classes and mixins'],
);
} else if (parent.parent is ExtensionDeclaration ||
}
} else if (element.isMustCallSuper) {
if ((parent is MethodDeclaration && parent.isStatic) ||
(parent is FieldDeclaration && parent.isStatic) ||
parent.parent is ExtensionDeclaration ||
parent.parent is EnumDeclaration) {
_errorReporter.reportErrorForNode(
HintCode.INVALID_ANNOTATION_TARGET,

View file

@ -179,6 +179,12 @@ class _MustBeOverridden {
const _MustBeOverridden();
}
@Target({
TargetKind.field,
TargetKind.getter,
TargetKind.method,
TargetKind.setter,
})
class _MustCallSuper {
const _MustCallSuper();
}

View file

@ -10,6 +10,7 @@ import '../dart/resolution/context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(InvalidAnnotationTarget_MustBeOverriddenTest);
defineReflectiveTests(InvalidAnnotationTarget_MustCallSuperTest);
defineReflectiveTests(InvalidAnnotationTargetTest);
});
}
@ -178,6 +179,170 @@ void m() {}
}
}
@reflectiveTest
class InvalidAnnotationTarget_MustCallSuperTest
extends PubPackageResolutionTest {
@override
void setUp() {
super.setUp();
writeTestPackageConfigWithMeta();
}
test_class_instance_field() async {
await assertNoErrorsInCode(r'''
import 'package:meta/meta.dart';
class A {
@mustCallSuper
int f = 0;
}
''');
}
test_class_instance_getter() async {
await assertNoErrorsInCode(r'''
import 'package:meta/meta.dart';
class A {
@mustCallSuper
int get f => 0;
}
''');
}
test_class_instance_method() async {
await assertNoErrorsInCode(r'''
import 'package:meta/meta.dart';
class A {
@mustCallSuper
void m() {}
}
''');
}
test_class_instance_setter() async {
await assertNoErrorsInCode(r'''
import 'package:meta/meta.dart';
class A {
@mustCallSuper
void set s(int value) {}
}
''');
}
test_class_static_field() async {
await assertErrorsInCode(r'''
import 'package:meta/meta.dart';
class A {
@mustCallSuper
static int f = 0;
}
''', [
error(HintCode.INVALID_ANNOTATION_TARGET, 45, 14),
]);
}
test_class_static_getter() async {
await assertErrorsInCode(r'''
import 'package:meta/meta.dart';
class A {
@mustCallSuper
static int get f => 0;
}
''', [
error(HintCode.INVALID_ANNOTATION_TARGET, 45, 14),
]);
}
test_class_static_method() async {
await assertErrorsInCode(r'''
import 'package:meta/meta.dart';
class A {
@mustCallSuper
static void m() {}
}
''', [
error(HintCode.INVALID_ANNOTATION_TARGET, 45, 14),
]);
}
test_class_static_setter() async {
await assertErrorsInCode(r'''
import 'package:meta/meta.dart';
class A {
@mustCallSuper
static void set f(int value) {}
}
''', [
error(HintCode.INVALID_ANNOTATION_TARGET, 45, 14),
]);
}
test_constructor() async {
await assertErrorsInCode(r'''
import 'package:meta/meta.dart';
class C {
@mustCallSuper
C();
}
''', [
error(HintCode.INVALID_ANNOTATION_TARGET, 47, 13),
]);
}
test_enum_member() async {
await assertErrorsInCode(r'''
import 'package:meta/meta.dart';
enum E {
one, two;
@mustCallSuper
void m() {}
}
''', [
error(HintCode.INVALID_ANNOTATION_TARGET, 57, 14),
]);
}
test_extension_member() async {
await assertErrorsInCode(r'''
import 'package:meta/meta.dart';
extension E on String {
@mustCallSuper
void m() {}
}
''', [
error(HintCode.INVALID_ANNOTATION_TARGET, 60, 14),
]);
}
test_mixin_instance_method() async {
await assertNoErrorsInCode(r'''
import 'package:meta/meta.dart';
mixin M {
@mustCallSuper
void m() {}
}
''');
}
test_topLevel() async {
await assertErrorsInCode(r'''
import 'package:meta/meta.dart';
@mustCallSuper
void m() {}
''', [
error(HintCode.INVALID_ANNOTATION_TARGET, 35, 13),
]);
}
}
@reflectiveTest
class InvalidAnnotationTargetTest extends PubPackageResolutionTest {
// todo(pq): add tests for topLevelVariables:

View file

@ -458,6 +458,12 @@ class _MustBeOverridden {
const _MustBeOverridden();
}
@Target({
TargetKind.field,
TargetKind.getter,
TargetKind.method,
TargetKind.setter,
})
class _MustCallSuper {
const _MustCallSuper();
}