Allow unnecessary getters and setters with annotations (#2722)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6beb018..53e32fa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@
 
 - update `use_setters_to_change_properties` to only highlight a method name,
   not the entire body and doc comment.
+- update `unnecessary_getters_setters` to allow otherwise "unnecessary" getters
+  and setters with annotations.
 
 # 1.6.1
 
diff --git a/lib/src/ast.dart b/lib/src/ast.dart
index 50630bd..ad5572f 100644
--- a/lib/src/ast.dart
+++ b/lib/src/ast.dart
@@ -98,12 +98,6 @@
   return false;
 }
 
-/// Returns `true` if the given [declaration] is annotated `@deprecated`.
-bool isDeprecated(Declaration declaration) {
-  var declaredElement = declaration.declaredElement;
-  return declaredElement != null && declaredElement.hasDeprecated;
-}
-
 /// Returns `true` if this element is the `==` method declaration.
 bool isEquals(ClassMember element) =>
     element is MethodDeclaration && element.name.name == '==';
@@ -158,10 +152,6 @@
 bool isPrivate(SimpleIdentifier? identifier) =>
     identifier != null ? Identifier.isPrivateName(identifier.name) : false;
 
-/// Returns `true` if the given [declaration] is annotated `@protected`.
-bool isProtected(Declaration declaration) =>
-    declaration.metadata.any((Annotation a) => a.name.name == 'protected');
-
 /// Returns `true` if the given [ClassMember] is a public method.
 bool isPublicMethod(ClassMember m) {
   var declaredElement = m.declaredElement;
diff --git a/lib/src/rules/unnecessary_getters_setters.dart b/lib/src/rules/unnecessary_getters_setters.dart
index 49f8dea..688691e 100644
--- a/lib/src/rules/unnecessary_getters_setters.dart
+++ b/lib/src/rules/unnecessary_getters_setters.dart
@@ -89,21 +89,20 @@
     }
 
     // Only select getters with setter pairs
-    getters.keys
-        .where((id) => setters.keys.contains(id))
-        .forEach((id) => _visitGetterSetter(getters[id], setters[id]));
+    for (var id in getters.keys) {
+      _visitGetterSetter(getters[id]!, setters[id]);
+    }
   }
 
-  void _visitGetterSetter(
-      MethodDeclaration? getter, MethodDeclaration? setter) {
-    if (getter != null &&
-        setter != null &&
-        isSimpleSetter(setter) &&
+  void _visitGetterSetter(MethodDeclaration getter, MethodDeclaration? setter) {
+    if (setter == null) return;
+    var getterElement = getter.declaredElement;
+    var setterElement = setter.declaredElement;
+    if (getterElement == null || setterElement == null) return;
+    if (isSimpleSetter(setter) &&
         isSimpleGetter(getter) &&
-        !isProtected(getter) &&
-        !isProtected(setter) &&
-        !isDeprecated(getter) &&
-        !isDeprecated(setter)) {
+        getterElement.metadata.isEmpty &&
+        setterElement.metadata.isEmpty) {
       rule..reportLint(getter.name)..reportLint(setter.name);
     }
   }
diff --git a/test_data/rules/unnecessary_getters_setters.dart b/test_data/rules/unnecessary_getters_setters.dart
index 5e18c21..40c59b3 100644
--- a/test_data/rules/unnecessary_getters_setters.dart
+++ b/test_data/rules/unnecessary_getters_setters.dart
@@ -65,6 +65,15 @@
   }
 }
 
+class Box7 {
+  var _contents;
+  @visibleForTesting
+  get contents => _contents; //OK (annotation)
+  set contents(value) {
+    _contents = value;
+  }
+}
+
 class LowerCase {
   var _contents;
   get contents => _contents;