linter: move test_utils out of lib

Change-Id: Ib0ca7fbcf8274c5fed36e73707c9ce206d9f2ff0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/444220
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
diff --git a/pkg/linter/lib/src/test_utilities/linter_options.dart b/pkg/linter/lib/src/test_utilities/linter_options.dart
deleted file mode 100644
index 441d59f..0000000
--- a/pkg/linter/lib/src/test_utilities/linter_options.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// ignore: implementation_imports
-import 'package:analyzer/src/lint/linter.dart';
-// ignore: implementation_imports
-import 'package:analyzer/src/lint/registry.dart';
-
-class LinterOptions {
-  final Iterable<AbstractAnalysisRule> enabledRules;
-
-  /// The path to the Dart SDK.
-  String? dartSdkPath;
-
-  /// Whether to gather timing data during analysis.
-  bool enableTiming = false;
-
-  LinterOptions({Iterable<AbstractAnalysisRule>? enabledRules})
-    : enabledRules = enabledRules ?? Registry.ruleRegistry;
-}
diff --git a/pkg/linter/tool/benchmark.dart b/pkg/linter/tool/benchmark.dart
index 07092c1..e6c3045 100644
--- a/pkg/linter/tool/benchmark.dart
+++ b/pkg/linter/tool/benchmark.dart
@@ -16,12 +16,12 @@
 import 'package:linter/src/extensions.dart';
 import 'package:linter/src/rules.dart';
 import 'package:linter/src/test_utilities/analysis_error_info.dart';
-import 'package:linter/src/test_utilities/linter_options.dart';
-import 'package:linter/src/test_utilities/test_linter.dart';
 import 'package:path/path.dart' as path;
 import 'package:yaml/yaml.dart';
 
 import 'lint_sets.dart';
+import 'linter_options.dart';
+import 'test_linter.dart';
 
 /// Benchmarks lint rules.
 Future<void> main(List<String> args) async {
@@ -134,6 +134,7 @@
 
   var configFile = options['config'];
   var ruleNames = options['rules'];
+  var customSdk = options.option('dart-sdk');
 
   LinterOptions linterOptions;
   if (configFile is String) {
@@ -144,7 +145,10 @@
       (rule) => !ruleConfigs.any((rc) => rc.disables(rule.name)),
     );
 
-    linterOptions = LinterOptions(enabledRules: enabledRules);
+    linterOptions = LinterOptions(
+      enabledRules: enabledRules,
+      dartSdkPath: customSdk,
+    );
   } else if (ruleNames is Iterable<String> && ruleNames.isNotEmpty) {
     var rules = <AbstractAnalysisRule>[];
     for (var ruleName in ruleNames) {
@@ -155,18 +159,11 @@
       }
       rules.add(rule);
     }
-    linterOptions = LinterOptions(enabledRules: rules);
+    linterOptions = LinterOptions(enabledRules: rules, dartSdkPath: customSdk);
   } else {
-    linterOptions = LinterOptions();
+    linterOptions = LinterOptions(dartSdkPath: customSdk);
   }
 
-  var customSdk = options['dart-sdk'];
-  if (customSdk is String) {
-    linterOptions.dartSdkPath = customSdk;
-  }
-
-  linterOptions.enableTiming = true;
-
   var filesToLint = [
     for (var path in paths)
       ...collectFiles(
diff --git a/pkg/linter/tool/checks/driver.dart b/pkg/linter/tool/checks/driver.dart
index 71757af..6615976 100644
--- a/pkg/linter/tool/checks/driver.dart
+++ b/pkg/linter/tool/checks/driver.dart
@@ -95,13 +95,7 @@
             try {
               var result = await context.currentSession.getErrors(filePath);
               if (result is ErrorsResult) {
-                var filtered =
-                    result.diagnostics
-                        .where((e) => e.diagnosticCode.name != 'TODO')
-                        .toList();
-                if (filtered.isNotEmpty) {
-                  errors.add(DiagnosticInfo(filtered, result.lineInfo));
-                }
+                errors.add(DiagnosticInfo(result.diagnostics, result.lineInfo));
               }
             } on Exception catch (e) {
               _print('Exception caught analyzing: $filePath');
diff --git a/pkg/linter/lib/src/test_utilities/lint_driver.dart b/pkg/linter/tool/lint_driver.dart
similarity index 85%
rename from pkg/linter/lib/src/test_utilities/lint_driver.dart
rename to pkg/linter/tool/lint_driver.dart
index 8d8ccb1..96f4a4c 100644
--- a/pkg/linter/lib/src/test_utilities/lint_driver.dart
+++ b/pkg/linter/tool/lint_driver.dart
@@ -6,15 +6,13 @@
 
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart' as file_system;
 import 'package:analyzer/instrumentation/instrumentation.dart';
-// ignore: implementation_imports
 import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
-// ignore: implementation_imports
 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
-// ignore: implementation_imports
 import 'package:analyzer/src/lint/io.dart';
+import 'package:linter/src/test_utilities/analysis_error_info.dart';
 
-import 'analysis_error_info.dart';
 import 'linter_options.dart';
 
 class LintDriver {
@@ -24,9 +22,10 @@
 
   final LinterOptions _options;
 
-  final ResourceProvider _resourceProvider;
+  LintDriver(this._options);
 
-  LintDriver(this._options, this._resourceProvider);
+  ResourceProvider get _resourceProvider =>
+      file_system.PhysicalResourceProvider.INSTANCE;
 
   Future<List<DiagnosticInfo>> analyze(Iterable<io.File> files) async {
     AnalysisEngine.instance.instrumentationService = _StdInstrumentation();
@@ -45,7 +44,7 @@
           growable: false,
         );
       },
-      enableLintRuleTiming: _options.enableTiming,
+      enableLintRuleTiming: true,
     );
 
     _filesAnalyzed.addAll(filesPaths);
@@ -63,10 +62,8 @@
     return result;
   }
 
-  String _absoluteNormalizedPath(String path) {
-    var pathContext = _resourceProvider.pathContext;
-    return pathContext.normalize(pathContext.absolute(path));
-  }
+  String _absoluteNormalizedPath(String path) => _resourceProvider.pathContext
+      .normalize(_resourceProvider.pathContext.absolute(path));
 }
 
 /// Prints logging information comments to the [outSink] and error messages to
diff --git a/pkg/linter/tool/linter_options.dart b/pkg/linter/tool/linter_options.dart
new file mode 100644
index 0000000..32b533c
--- /dev/null
+++ b/pkg/linter/tool/linter_options.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/lint/linter.dart';
+import 'package:analyzer/src/lint/registry.dart';
+
+class LinterOptions {
+  final Iterable<AbstractAnalysisRule> enabledRules;
+
+  /// The path to the Dart SDK.
+  final String? dartSdkPath;
+
+  LinterOptions({
+    Iterable<AbstractAnalysisRule>? enabledRules,
+    this.dartSdkPath,
+  }) : enabledRules = enabledRules ?? Registry.ruleRegistry;
+}
diff --git a/pkg/linter/lib/src/test_utilities/test_linter.dart b/pkg/linter/tool/test_linter.dart
similarity index 75%
rename from pkg/linter/lib/src/test_utilities/test_linter.dart
rename to pkg/linter/tool/test_linter.dart
index a4cb0bc..e860e45 100644
--- a/pkg/linter/lib/src/test_utilities/test_linter.dart
+++ b/pkg/linter/tool/test_linter.dart
@@ -6,18 +6,14 @@
 
 import 'package:analyzer/diagnostic/diagnostic.dart';
 import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/file_system/file_system.dart' as file_system;
 import 'package:analyzer/file_system/physical_file_system.dart' as file_system;
 import 'package:analyzer/source/file_source.dart';
 import 'package:analyzer/source/source.dart';
-// ignore: implementation_imports
 import 'package:analyzer/src/lint/pub.dart';
-// ignore: implementation_imports
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
-import 'package:meta/meta.dart';
+import 'package:linter/src/test_utilities/analysis_error_info.dart';
 import 'package:path/path.dart' as path;
 
-import 'analysis_error_info.dart';
 import 'lint_driver.dart';
 import 'linter_options.dart';
 
@@ -27,33 +23,37 @@
   return FileSource(file, uri);
 }
 
-/// Dart source linter, only for package:linter's tools and tests.
 class TestLinter implements DiagnosticListener {
   final errors = <Diagnostic>[];
 
   final LinterOptions options;
-  final file_system.ResourceProvider _resourceProvider;
+  TestLinter(this.options);
 
-  TestLinter(this.options, {file_system.ResourceProvider? resourceProvider})
-    : _resourceProvider =
-          resourceProvider ?? file_system.PhysicalResourceProvider.INSTANCE;
+  path.Context get _pathContext =>
+      file_system.PhysicalResourceProvider.INSTANCE.pathContext;
 
   Future<List<DiagnosticInfo>> lintFiles(List<File> files) async {
-    var lintDriver = LintDriver(options, _resourceProvider);
+    var lintDriver = LintDriver(options);
     var errors = await lintDriver.analyze(
       files.where((f) => f.path.endsWith('.dart')),
     );
     for (var file in files.where(_isPubspecFile)) {
-      lintPubspecSource(
+      _lintPubspecSource(
         contents: file.readAsStringSync(),
-        sourcePath: _resourceProvider.pathContext.normalize(file.absolute.path),
+        sourcePath: _pathContext.normalize(file.absolute.path),
       );
     }
     return errors;
   }
 
-  @visibleForTesting
-  void lintPubspecSource({required String contents, String? sourcePath}) {
+  @override
+  void onDiagnostic(Diagnostic error) => errors.add(error);
+
+  /// Returns whether this [entry] is a pubspec file.
+  bool _isPubspecFile(FileSystemEntity entry) =>
+      path.basename(entry.path) == file_paths.pubspecYaml;
+
+  void _lintPubspecSource({required String contents, String? sourcePath}) {
     var sourceUrl = sourcePath == null ? null : path.toUri(sourcePath);
     var spec = Pubspec.parse(contents, sourceUrl: sourceUrl);
 
@@ -75,11 +75,4 @@
       }
     }
   }
-
-  @override
-  void onDiagnostic(Diagnostic error) => errors.add(error);
-
-  /// Returns whether this [entry] is a pubspec file.
-  bool _isPubspecFile(FileSystemEntity entry) =>
-      path.basename(entry.path) == file_paths.pubspecYaml;
 }