From 6372704784db6c03a685fd0f6e96236c22b7ab44 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Wed, 13 Aug 2025 12:09:59 -0700 Subject: [PATCH] analyzer: move io utils out of analyzer/lib, into linter/tool Change-Id: Iacbb37db605f831a11277d1933db0a8d2274a195 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/445103 Reviewed-by: Konstantin Shcheglov Commit-Queue: Konstantin Shcheglov Auto-Submit: Samuel Rawlins --- pkg/linter/lib/src/utils.dart | 7 ------- pkg/linter/test/all.dart | 6 ------ pkg/linter/test/doc_test.dart | 4 ++-- pkg/linter/test/util/test_utils.dart | 20 ------------------- pkg/linter/test/utils_test.dart | 8 ++++++-- ...validate_rule_description_format_test.dart | 5 ++--- pkg/linter/tool/benchmark.dart | 2 +- pkg/linter/tool/checks/check_all_yaml.dart | 3 +-- pkg/linter/tool/lint_sets.dart | 3 ++- pkg/linter/tool/machine.dart | 2 +- pkg/linter/tool/messages_info.dart | 5 +++-- pkg/linter/tool/test_linter.dart | 3 ++- .../lib/src/lint => linter/tool/util}/io.dart | 9 ++++++--- 13 files changed, 26 insertions(+), 51 deletions(-) delete mode 100644 pkg/linter/test/util/test_utils.dart rename pkg/{analyzer/lib/src/lint => linter/tool/util}/io.dart (58%) diff --git a/pkg/linter/lib/src/utils.dart b/pkg/linter/lib/src/utils.dart index bc5ad4cf04b..e8f4e936e52 100644 --- a/pkg/linter/lib/src/utils.dart +++ b/pkg/linter/lib/src/utils.dart @@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/dart/ast/token.dart'; -import 'package:analyzer/src/lint/io.dart'; // ignore: implementation_imports // A camel case string here is defined as: // * An arbitrary number of optional leading `_`s or `$`s, @@ -88,12 +87,6 @@ bool isValidPackageName(String id) => _isIdentifier(id) && !_isReservedWord(id); -/// Write the given [object] to the console. -/// Uses the shared [outSink] for redirecting in tests. -void printToConsole(Object? object) { - outSink.writeln(object); -} - bool _isCamelCase(String name) => _camelCasePattern.hasMatch(name); /// Whether this [name] is a legal Dart identifier. diff --git a/pkg/linter/test/all.dart b/pkg/linter/test/all.dart index 9625261880a..49d8e4d3204 100644 --- a/pkg/linter/test/all.dart +++ b/pkg/linter/test/all.dart @@ -2,14 +2,11 @@ // 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/io.dart'; - import 'ascii_utils_test.dart' as ascii_utils; import 'doc_test.dart' as doc; import 'formatter_test.dart' as formatter; import 'integration_test.dart' as integration; import 'lint_code_test.dart' as lint_code; -import 'mocks.dart'; import 'pubspec_test.dart' as pubspec; import 'rules/all.dart' as rules; import 'scope_util_test.dart' as scope_util; @@ -25,9 +22,6 @@ import 'verify_reflective_test_suites_test.dart' as verify_reflective_test_suites; void main() { - // Redirect output. - outSink = MockIOSink(); - ascii_utils.main(); doc.main(); formatter.main(); diff --git a/pkg/linter/test/doc_test.dart b/pkg/linter/test/doc_test.dart index 97a46e743a8..ec6dd834f55 100644 --- a/pkg/linter/test/doc_test.dart +++ b/pkg/linter/test/doc_test.dart @@ -2,14 +2,14 @@ // 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:linter/src/rules.dart'; import 'package:test/test.dart'; import '../tool/machine.dart'; -import 'util/test_utils.dart'; void main() { group('doc generation', () { - setUp(setUpSharedTestEnvironment); + setUp(registerLintRules); test('fixStatus (sanity)', () { var fixStatusMap = readFixStatusMap(); // Doc generation reads the fix status map to associate fix status diff --git a/pkg/linter/test/util/test_utils.dart b/pkg/linter/test/util/test_utils.dart deleted file mode 100644 index a3f86cbbca6..00000000000 --- a/pkg/linter/test/util/test_utils.dart +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2017, 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/io.dart'; -import 'package:linter/src/rules.dart'; -import 'package:test/test.dart'; - -import '../mocks.dart'; - -void setUpSharedTestEnvironment() { - // Redirect output. - outSink = MockIOSink(); - registerLintRules(); -} - -void testEach(Iterable values, bool Function(T s) f, Matcher m) { - for (var s in values) { - test('"$s"', () => expect(f(s), m)); - } -} diff --git a/pkg/linter/test/utils_test.dart b/pkg/linter/test/utils_test.dart index e783393d306..b8d7cdfbc61 100644 --- a/pkg/linter/test/utils_test.dart +++ b/pkg/linter/test/utils_test.dart @@ -5,8 +5,6 @@ import 'package:linter/src/utils.dart'; import 'package:test/test.dart'; -import 'util/test_utils.dart'; - void main() { group('isDartFileName', () { testEach(['foo.dart'], isDartFileName, isTrue); @@ -165,3 +163,9 @@ void main() { testEach(bad, isUpperCase, isFalse); }); } + +void testEach(Iterable values, bool Function(T s) f, Matcher m) { + for (var s in values) { + test('"$s"', () => expect(f(s), m)); + } +} diff --git a/pkg/linter/test/validate_rule_description_format_test.dart b/pkg/linter/test/validate_rule_description_format_test.dart index 41ba20a2136..4e332b15caf 100644 --- a/pkg/linter/test/validate_rule_description_format_test.dart +++ b/pkg/linter/test/validate_rule_description_format_test.dart @@ -3,13 +3,12 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/lint/registry.dart'; +import 'package:linter/src/rules.dart'; import 'package:test/test.dart'; -import 'util/test_utils.dart'; - void main() { group('rule doc format', () { - setUpSharedTestEnvironment(); + registerLintRules(); var rules = Registry.ruleRegistry.rules; test('(setup)', () { diff --git a/pkg/linter/tool/benchmark.dart b/pkg/linter/tool/benchmark.dart index 1165360ee2a..37e36c15640 100644 --- a/pkg/linter/tool/benchmark.dart +++ b/pkg/linter/tool/benchmark.dart @@ -10,7 +10,6 @@ import 'package:analyzer/analysis_rule/analysis_rule.dart'; import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/src/lint/analysis_rule_timers.dart'; import 'package:analyzer/src/lint/config.dart'; -import 'package:analyzer/src/lint/io.dart'; import 'package:analyzer/src/lint/registry.dart'; import 'package:analyzer/src/util/file_paths.dart' as file_paths; import 'package:args/args.dart'; @@ -21,6 +20,7 @@ import 'package:yaml/yaml.dart'; import 'lint_sets.dart'; import 'test_linter.dart'; +import 'util/io.dart'; /// Benchmarks lint rules. Future main(List args) async { diff --git a/pkg/linter/tool/checks/check_all_yaml.dart b/pkg/linter/tool/checks/check_all_yaml.dart index e0f854f2948..026aac10e96 100644 --- a/pkg/linter/tool/checks/check_all_yaml.dart +++ b/pkg/linter/tool/checks/check_all_yaml.dart @@ -4,7 +4,6 @@ import 'dart:io'; -import 'package:analyzer/src/lint/io.dart'; import 'package:analyzer/src/lint/registry.dart'; import 'package:linter/src/rules.dart'; import 'package:yaml/yaml.dart'; @@ -27,7 +26,7 @@ void main() { /// there are errors, and `null` otherwise. String? checkAllYaml() { var allYamlPath = pathRelativeToPackageRoot(['example', 'all.yaml']); - var src = readFile(allYamlPath); + var src = File(allYamlPath).readAsStringSync(); var options = _getOptionsFromString(src); var linterSection = options['linter'] as YamlMap?; diff --git a/pkg/linter/tool/lint_sets.dart b/pkg/linter/tool/lint_sets.dart index 5a15b0e145c..794063470f1 100644 --- a/pkg/linter/tool/lint_sets.dart +++ b/pkg/linter/tool/lint_sets.dart @@ -6,9 +6,10 @@ import 'dart:async'; import 'package:analyzer/src/lint/config.dart'; import 'package:http/http.dart' as http; -import 'package:linter/src/utils.dart'; import 'package:yaml/yaml.dart'; +import 'util/io.dart'; + Future> get dartCoreLints => _fetchRulesFromGitHub('/dart-lang/core/main/pkgs/lints/lib/core.yaml'); diff --git a/pkg/linter/tool/machine.dart b/pkg/linter/tool/machine.dart index 1e905b56b06..a51580718c3 100644 --- a/pkg/linter/tool/machine.dart +++ b/pkg/linter/tool/machine.dart @@ -10,11 +10,11 @@ import 'package:analyzer/src/lint/registry.dart'; import 'package:args/args.dart'; import 'package:collection/collection.dart'; import 'package:linter/src/rules.dart'; -import 'package:linter/src/utils.dart'; import 'package:pub_semver/pub_semver.dart'; import 'package:yaml/yaml.dart'; import 'messages_info.dart'; +import 'util/io.dart'; import 'util/path_utils.dart'; /// Generates a list of built-in lint rules in JSON suitable for diff --git a/pkg/linter/tool/messages_info.dart b/pkg/linter/tool/messages_info.dart index a5e0bf77657..afe9b4dede1 100644 --- a/pkg/linter/tool/messages_info.dart +++ b/pkg/linter/tool/messages_info.dart @@ -2,8 +2,9 @@ // 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 'dart:io'; + import 'package:analyzer/analysis_rule/rule_state.dart'; -import 'package:analyzer/src/lint/io.dart'; import 'package:collection/collection.dart'; import 'package:pub_semver/pub_semver.dart'; import 'package:yaml/yaml.dart'; @@ -39,7 +40,7 @@ const _stateNames = { }; final Map messagesRuleInfo = () { - var messagesYaml = loadYamlNode(readFile(_messagesYamlPath)); + var messagesYaml = loadYamlNode(File(_messagesYamlPath).readAsStringSync()); if (messagesYaml is! YamlMap) { throw StateError("The '$_messagesFileName' file is not a YAML map."); } diff --git a/pkg/linter/tool/test_linter.dart b/pkg/linter/tool/test_linter.dart index 9abfd93ee11..bf0a50a07f6 100644 --- a/pkg/linter/tool/test_linter.dart +++ b/pkg/linter/tool/test_linter.dart @@ -14,11 +14,12 @@ import 'package:analyzer/instrumentation/instrumentation.dart'; import 'package:analyzer/source/file_source.dart'; import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart'; import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine; -import 'package:analyzer/src/lint/io.dart'; import 'package:analyzer/src/lint/pub.dart'; import 'package:analyzer/src/util/file_paths.dart' as file_paths; import 'package:path/path.dart' as path; +import 'util/io.dart'; + class TestLinter implements DiagnosticListener { final errors = []; diff --git a/pkg/analyzer/lib/src/lint/io.dart b/pkg/linter/tool/util/io.dart similarity index 58% rename from pkg/analyzer/lib/src/lint/io.dart rename to pkg/linter/tool/util/io.dart index 84ff61532a9..148971ab2f5 100644 --- a/pkg/analyzer/lib/src/lint/io.dart +++ b/pkg/linter/tool/util/io.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2025, 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. @@ -10,5 +10,8 @@ StringSink errorSink = stderr; /// A shared sink for standard out reporting. StringSink outSink = stdout; -/// Synchronously read the contents of the file at the given [path] as a string. -String readFile(String path) => File(path).readAsStringSync(); +/// Write the given [object] to the console. +/// Uses the shared [outSink] for redirecting in tests. +void printToConsole(Object? object) { + outSink.writeln(object); +}