Skip to content

Commit fd97cd4

Browse files
pqCommit Queue
authored and
Commit Queue
committed
enforce @redeclare annotation target restrictions
See: #53121 Change-Id: I994aac6c733704ac7adc4a7923ee733cdc77aacb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319561 Commit-Queue: Phil Quitslund <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent f72c1eb commit fd97cd4

File tree

4 files changed

+145
-1
lines changed

4 files changed

+145
-1
lines changed

pkg/analyzer/lib/dart/element/element.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,10 @@ abstract class ElementAnnotation implements ConstantEvaluationTarget {
849849
/// object.
850850
bool get isProxy;
851851

852-
/// Whether the marks the associated member as being reopened.
852+
/// Whether the annotation marks the associated member as redeclaring.
853+
bool get isRedeclare;
854+
855+
/// Whether the annotation marks the associated member as being reopened.
853856
bool get isReopen;
854857

855858
/// Whether the annotation marks the associated member as being required.

pkg/analyzer/lib/src/dart/element/element.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,6 +1556,9 @@ class ElementAnnotationImpl implements ElementAnnotation {
15561556
/// protected.
15571557
static const String _protectedVariableName = 'protected';
15581558

1559+
/// The name of the top-level variable used to mark a member as redeclaring.
1560+
static const String _redeclareVariableName = 'redeclare';
1561+
15591562
/// The name of the top-level variable used to mark a class or mixin as being
15601563
/// reopened.
15611564
static const String _reopenVariableName = 'reopen';
@@ -1710,6 +1713,9 @@ class ElementAnnotationImpl implements ElementAnnotation {
17101713
@override
17111714
bool get isProxy => false;
17121715

1716+
@override
1717+
bool get isRedeclare => _isPackageMetaGetter(_redeclareVariableName);
1718+
17131719
@override
17141720
bool get isReopen => _isPackageMetaGetter(_reopenVariableName);
17151721

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class AnnotationVerifier {
5454
_checkNonVirtual(node);
5555
} else if (element.isReopen) {
5656
_checkReopen(node);
57+
} else if (element.isRedeclare) {
58+
_checkRedeclare(node);
5759
} else if (element.isSealed) {
5860
_checkSealed(node);
5961
} else if (element.isUseResult) {
@@ -254,6 +256,20 @@ class AnnotationVerifier {
254256
}
255257
}
256258

259+
/// Reports a warning if [parent] is not a valid target for a
260+
/// `@redeclare` annotation.
261+
void _checkRedeclare(Annotation node) {
262+
var parent = node.parent;
263+
if (parent.parent is! ExtensionTypeDeclaration ||
264+
parent is MethodDeclaration && parent.isStatic) {
265+
_errorReporter.reportErrorForNode(
266+
WarningCode.INVALID_ANNOTATION_TARGET,
267+
node,
268+
[node.name.name, 'instance members of extension types'],
269+
);
270+
}
271+
}
272+
257273
/// Reports a warning if [parent] is not a valid target for a `@reopen`
258274
/// annotation.
259275
void _checkReopen(AstNode node) {

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

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ main() {
1111
defineReflectiveSuite(() {
1212
defineReflectiveTests(InvalidAnnotationTarget_MustBeOverriddenTest);
1313
defineReflectiveTests(InvalidAnnotationTarget_MustCallSuperTest);
14+
defineReflectiveTests(InvalidAnnotationTarget_RedeclareTest);
1415
defineReflectiveTests(InvalidAnnotationTargetTest);
1516
});
1617
}
@@ -343,6 +344,124 @@ void m() {}
343344
}
344345
}
345346

347+
@reflectiveTest
348+
class InvalidAnnotationTarget_RedeclareTest extends PubPackageResolutionTest {
349+
@override
350+
void setUp() {
351+
super.setUp();
352+
writeTestPackageConfigWithMeta();
353+
}
354+
355+
test_class_instance_method() async {
356+
await assertErrorsInCode(r'''
357+
import 'package:meta/meta.dart';
358+
359+
class C {
360+
@redeclare
361+
void m() {}
362+
}
363+
''', [
364+
error(WarningCode.INVALID_ANNOTATION_TARGET, 46, 10),
365+
]);
366+
}
367+
368+
test_extensionType_instance_getter() async {
369+
await assertNoErrorsInCode(r'''
370+
import 'package:meta/meta.dart';
371+
372+
class C {
373+
int get g => 0;
374+
}
375+
376+
extension type E(C c) {
377+
@redeclare
378+
int get g => 0;
379+
}
380+
''');
381+
}
382+
383+
test_extensionType_instance_method() async {
384+
await assertNoErrorsInCode(r'''
385+
import 'package:meta/meta.dart';
386+
387+
class C {
388+
void m() {}
389+
}
390+
391+
extension type E(C c) {
392+
@redeclare
393+
void m() {}
394+
}
395+
''');
396+
}
397+
398+
test_extensionType_instance_setter() async {
399+
await assertNoErrorsInCode(r'''
400+
import 'package:meta/meta.dart';
401+
402+
class C {
403+
set g(int i) {}
404+
}
405+
406+
extension type E(C c) {
407+
@redeclare
408+
set g(int i) {}
409+
}
410+
''');
411+
}
412+
413+
test_extensionType_static_getter() async {
414+
await assertErrorsInCode(r'''
415+
import 'package:meta/meta.dart';
416+
417+
class C {
418+
static int get g => 0;
419+
}
420+
421+
extension type E(C c) {
422+
@redeclare
423+
static int get g => 0;
424+
}
425+
''', [
426+
error(WarningCode.INVALID_ANNOTATION_TARGET, 99, 10),
427+
]);
428+
}
429+
430+
test_extensionType_static_method() async {
431+
await assertErrorsInCode(r'''
432+
import 'package:meta/meta.dart';
433+
434+
class C {
435+
static void m() {}
436+
}
437+
438+
extension type E(C c) {
439+
@redeclare
440+
static void m() {}
441+
}
442+
''', [
443+
error(WarningCode.INVALID_ANNOTATION_TARGET, 94, 10),
444+
]);
445+
}
446+
447+
test_extensionType_static_setter() async {
448+
await assertErrorsInCode(r'''
449+
import 'package:meta/meta.dart';
450+
451+
class C {
452+
static set g(int i) {}
453+
}
454+
455+
extension type E(C c) {
456+
@redeclare
457+
static set g(int i) {}
458+
}
459+
''', [
460+
error(WarningCode.INVALID_ANNOTATION_TARGET, 98, 10),
461+
]);
462+
}
463+
}
464+
346465
@reflectiveTest
347466
class InvalidAnnotationTargetTest extends PubPackageResolutionTest {
348467
@override

0 commit comments

Comments
 (0)