Merge remote-tracking branch 'origin/main' into HEAD
diff --git a/lib/src/rules/unnecessary_parenthesis.dart b/lib/src/rules/unnecessary_parenthesis.dart
index e65f41d..82ccd65 100644
--- a/lib/src/rules/unnecessary_parenthesis.dart
+++ b/lib/src/rules/unnecessary_parenthesis.dart
@@ -125,9 +125,14 @@
       if (parent is BinaryExpression) return;
       if (parent is ConditionalExpression) return;
       if (parent is CascadeExpression) return;
-      if (parent is FunctionExpressionInvocation) return;
       if (parent is AsExpression) return;
       if (parent is IsExpression) return;
+      if (parent is FunctionExpressionInvocation) {
+        if (expression is PrefixedIdentifier) {
+          rule.reportLint(node);
+        }
+        return;
+      }
 
       // A prefix expression (! or -) can have an argument wrapped in
       // "unnecessary" parens if that argument has potentially confusing
@@ -149,17 +154,24 @@
       // Something like `({1, 2, 3}).forEach(print);`.
       // The parens cannot be removed because then the curly brackets are not
       // interpreted as a set-or-map literal.
+      if (parent is PropertyAccess || parent is MethodInvocation) {
+        // TODO an API to the AST for better usage
+        // Precedence isn't sufficient (e.g. PostfixExpression requires parenthesis)
+        if (expression is PropertyAccess ||
+            expression is MethodInvocation ||
+            expression is IndexExpression) {
+          rule.reportLint(node);
+        }
+      }
       if (node.wouldBeParsedAsStatementBlock) {
         return;
       }
 
-      if (parent.precedence < node.expression.precedence) {
+      if (parent.precedence < expression.precedence) {
         rule.reportLint(node);
-        return;
       }
     } else {
       rule.reportLint(node);
-      return;
     }
   }
 
diff --git a/test_data/rules/unnecessary_parenthesis.dart b/test_data/rules/unnecessary_parenthesis.dart
index 0cf5d5c..47d16f5 100644
--- a/test_data/rules/unnecessary_parenthesis.dart
+++ b/test_data/rules/unnecessary_parenthesis.dart
@@ -108,6 +108,14 @@
   ({1, 2, 3}).length;
   print(({1, 2, 3}).length); // LINT
   ([false, true]).forEach(print); // LINT
+  (0.sign).isEven; // LINT
+  (0.isEven).toString(); // LINT
+  (0.toString()).isEmpty; // LINT
+  (0.toDouble()).toString(); // LINT
+
+  List<String> list = <String>[];
+  (list[list.length]).toString(); // LINT
+
 }
 
 Invocation? invocation() => null;
@@ -145,3 +153,9 @@
 extension<T> on Set<T> {
   Set<T> operator +(Set<T> other) => {...this, ...other};
 }
+
+class MyType extends Type {
+  MyType.withString(String s) {}
+  MyType.withSelf(MyType myType)
+      : this.withString((myType.toString)()); // LINT
+}