don't disable TODO issues in IDEs (#23274)

* don't disable TODO issues in IDEs

* minor change to start cirrus
diff --git a/dev/bots/analyze-sample-code.dart b/dev/bots/analyze-sample-code.dart
index 9e04582..c3e8c49 100644
--- a/dev/bots/analyze-sample-code.dart
+++ b/dev/bots/analyze-sample-code.dart
@@ -231,7 +231,7 @@
     errors.add(null);
     errors.addAll(await process.stdout.transform<String>(utf8.decoder).transform<String>(const LineSplitter()).toList());
     // top is stderr
-    if (errors.isNotEmpty && (errors.first.contains(' issues found. (ran in ') || errors.first.contains(' issue found. (ran in '))) {
+    if (errors.isNotEmpty && (errors.first.contains(' issues found (ran in ') || errors.first.contains(' issue found (ran in '))) {
       errors.removeAt(0); // the "23 issues found" message goes onto stderr, which is concatenated first
       if (errors.isNotEmpty && errors.last.isEmpty)
         errors.removeLast(); // if there's an "issues found" message, we put a blank line on stdout before it
diff --git a/packages/flutter/lib/analysis_options_user.yaml b/packages/flutter/lib/analysis_options_user.yaml
index e558021..01c274a 100644
--- a/packages/flutter/lib/analysis_options_user.yaml
+++ b/packages/flutter/lib/analysis_options_user.yaml
@@ -24,8 +24,6 @@
   errors:
     # treat missing required parameters as a warning (not a hint)
     missing_required_param: warning
-    # allow having TODOs in the code
-    todo: ignore
 
 linter:
   rules:
diff --git a/packages/flutter_tools/lib/src/commands/analyze_once.dart b/packages/flutter_tools/lib/src/commands/analyze_once.dart
index faadddc..942db17 100644
--- a/packages/flutter_tools/lib/src/commands/analyze_once.dart
+++ b/packages/flutter_tools/lib/src/commands/analyze_once.dart
@@ -87,7 +87,8 @@
       }
     });
     server.onErrors.listen((FileAnalysisErrors fileErrors) {
-      errors.addAll(fileErrors.errors);
+      // Record the issues found (but filter out to do comments).
+      errors.addAll(fileErrors.errors.where((AnalysisError error) => error.type != 'TODO'));
     });
 
     await server.start();
@@ -148,9 +149,9 @@
       final int errorCount = errors.length;
       printStatus('');
       if (undocumentedMembers > 0) {
-        throwToolExit('$errorCount ${pluralize('issue', errorCount)} found. (ran in ${seconds}s; $dartdocMessage)');
+        throwToolExit('$errorCount ${pluralize('issue', errorCount)} found (ran in ${seconds}s; $dartdocMessage).');
       } else {
-        throwToolExit('$errorCount ${pluralize('issue', errorCount)} found. (ran in ${seconds}s)');
+        throwToolExit('$errorCount ${pluralize('issue', errorCount)} found (ran in ${seconds}s).');
       }
     }
 
diff --git a/packages/flutter_tools/test/commands/analyze_once_test.dart b/packages/flutter_tools/test/commands/analyze_once_test.dart
index 1166a6e..4c87e50 100644
--- a/packages/flutter_tools/test/commands/analyze_once_test.dart
+++ b/packages/flutter_tools/test/commands/analyze_once_test.dart
@@ -96,7 +96,7 @@
           'warning $analyzerSeparator The parameter \'onPressed\' is required',
           'info $analyzerSeparator The method \'_incrementCounter\' isn\'t used',
         ],
-        exitMessageContains: '2 issues found.',
+        exitMessageContains: '2 issues found',
         toolExit: true,
       );
     }, timeout: allowForSlowAnalyzeTests);
@@ -123,7 +123,7 @@
           'info $analyzerSeparator The method \'_incrementCounter\' isn\'t used',
           'info $analyzerSeparator Only throw instances of classes extending either Exception or Error',
         ],
-        exitMessageContains: '3 issues found.',
+        exitMessageContains: '3 issues found',
         toolExit: true,
       );
     }, timeout: allowForSlowAnalyzeTests);
@@ -154,7 +154,7 @@
           statusTextContains: <String>[
             'Analyzing',
           ],
-          exitMessageContains: '1 issue found.',
+          exitMessageContains: '1 issue found',
           toolExit: true,
         );
       } finally {
@@ -178,6 +178,24 @@
         tryToDelete(tempDir);
       }
     });
+
+    testUsingContext('returns no issues for todo comments', () async {
+      const String contents = '''
+// TODO(foobar):
+StringBuffer bar = StringBuffer('baz');
+''';
+      final Directory tempDir = fs.systemTempDirectory.createTempSync('flutter_analyze_once_test_4.');
+      tempDir.childFile('main.dart').writeAsStringSync(contents);
+      try {
+        await runCommand(
+          command: AnalyzeCommand(workingDirectory: fs.directory(tempDir)),
+          arguments: <String>['analyze'],
+          statusTextContains: <String>['No issues found!'],
+        );
+      } finally {
+        tryToDelete(tempDir);
+      }
+    });
   });
 }