Files
sdk/pkg/analyzer/test/source/error_processor_test.dart
T
Paul Berry 9f6d1c1029 [messages] Start using toplevel diagnostic constants.
Changes the analyzer and related packages so that when they refer to
diagnostic constants, they do so via the import prefix `diag`, which
refers to the appropriate `diagnostic.dart` file containing the top
level diagnostic constant declarations, rather than the static
declarations inside `DiagnosticCode`-derived classes (which will soon
be removed).

This CL was created by the following steps:

- Run the script
  `pkg/analyzer_utilities/tool/messages/switch_to_toplevel_diagnostics.dart`.

- Execute `dart fix --apply --code=unused_import,unnecessary_import`
  on the following directories (this removes imports that are no
  longer necessary due to the change):
  - `pkg/analysis_server`
  - `pkg/analyzer`
  - `pkg/linter`
  - `pkg/analysis_server_plugin`
  - `pkg/analyzer_plugin`
  - `pkg/analyzer_testing`
  - `pkg/front_end`
  - `pkg/analyzer_cli`

- Execute `dart format` on the following files and directories:
  - `pkg/analysis_server`
  - `pkg/analyzer`
  - `pkg/linter`
  - `pkg/analysis_server_plugin`
  - `pkg/analyzer_plugin`
  - `pkg/analyzer_testing`
  - `pkg/front_end/test/scanner_test.dart`

  (Note that `pkg/front_end` and `pkg/analyzer_cli` are not
  re-formatted as whole directories because they contain `.dart` files
  that are test cases rather than source code, and reformatting those
  files might change test expectations.)

- Manually add `diag` to
  pkg/front_end/test/spell_checking_list_tests.txt.

- Manually fix the ignore comment in
  `pkg/analyzer_testing/lib/src/analysis_rule/pub_package_resolution.dart`. (The
  script `switch_to_toplevel_diagnostics.dart` automatically adds it
  after `import 'package:analyzer/src/diagnostic/diagnostic.dart' as
  diag;`, but then executing `dart format` bumps the ignore comment to
  the following line, where it has no effect.)

Change-Id: I6a6a69643022aab2b5a6224fb4124eead243260d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/461521
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
2025-11-12 16:53:42 -08:00

200 lines
5.9 KiB
Dart

// Copyright (c) 2015, 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/dart/analysis/analysis_options.dart';
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/dart/analysis/analysis_options.dart';
import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:collection/collection.dart';
import 'package:test/test.dart';
import 'package:yaml/yaml.dart';
import '../generated/test_support.dart';
import '../src/util/yaml_test.dart';
main() {
Diagnostic invalid_assignment = Diagnostic.tmp(
source: TestSource(),
offset: 0,
length: 1,
diagnosticCode: diag.invalidAssignment,
arguments: [
['x'],
['y'],
],
);
Diagnostic assignment_of_do_not_store = Diagnostic.tmp(
source: TestSource(),
offset: 0,
length: 1,
diagnosticCode: diag.assignmentOfDoNotStore,
arguments: [
['x'],
],
);
Diagnostic unused_local_variable = Diagnostic.tmp(
source: TestSource(),
offset: 0,
length: 1,
diagnosticCode: diag.unusedLocalVariable,
arguments: [
['x'],
],
);
Diagnostic use_of_void_result = Diagnostic.tmp(
source: TestSource(),
offset: 0,
length: 1,
diagnosticCode: diag.useOfVoidResult,
);
// We in-line a lint code here in order to avoid adding a dependency on the
// linter package.
Diagnostic annotate_overrides = Diagnostic.tmp(
source: TestSource(),
offset: 0,
length: 1,
diagnosticCode: LintCode(
'annotate_overrides',
'',
uniqueName: 'LintCode.annotate_overrides',
),
);
group('ErrorProcessor', () {
late _TestContext context;
setUp(() {
context = _TestContext();
});
test('configureOptions', () {
context.configureOptions('''
analyzer:
errors:
invalid_assignment: error # severity ERROR
assignment_of_do_not_store: false # ignore
unused_local_variable: true # skipped
use_of_void_result: unsupported_action # skipped
''');
expect(
context.getProcessor(invalid_assignment)!.severity,
DiagnosticSeverity.ERROR,
);
expect(
context.getProcessor(assignment_of_do_not_store)!.severity,
isNull,
);
expect(context.getProcessor(unused_local_variable), isNull);
expect(context.getProcessor(use_of_void_result), isNull);
});
test('does not upgrade other warnings to errors in strong mode', () {
context.configureOptions('''
analyzer:
strong-mode: true
''');
expect(context.getProcessor(unused_local_variable), isNull);
});
});
group('ErrorConfig', () {
var config = '''
analyzer:
errors:
invalid_assignment: unsupported_action # should be skipped
assignment_of_do_not_store: false
unused_local_variable: error
''';
group('processing', () {
test('yaml map', () {
var options = AnalysisOptionsProvider().getOptionsFromString(config);
var errorConfig = ErrorConfig(
(options['analyzer'] as YamlMap)['errors'] as YamlNode?,
);
expect(errorConfig.processors, hasLength(2));
// ignore
var missingReturnProcessor = errorConfig.processors.firstWhere(
(p) => p.appliesTo(assignment_of_do_not_store),
);
expect(missingReturnProcessor.severity, isNull);
// error
var unusedLocalProcessor = errorConfig.processors.firstWhere(
(p) => p.appliesTo(unused_local_variable),
);
expect(unusedLocalProcessor.severity, DiagnosticSeverity.ERROR);
// skip
var invalidAssignmentProcessor = errorConfig.processors
.firstWhereOrNull((p) => p.appliesTo(invalid_assignment));
expect(invalidAssignmentProcessor, isNull);
});
test('string map', () {
var options = wrap({
'invalid_assignment': 'unsupported_action', // should be skipped
'assignment_of_do_not_store': 'false',
'unused_local_variable': 'error',
});
var errorConfig = ErrorConfig(options);
expect(errorConfig.processors, hasLength(2));
// ignore
var missingReturnProcessor = errorConfig.processors.firstWhere(
(p) => p.appliesTo(assignment_of_do_not_store),
);
expect(missingReturnProcessor.severity, isNull);
// error
var unusedLocalProcessor = errorConfig.processors.firstWhere(
(p) => p.appliesTo(unused_local_variable),
);
expect(unusedLocalProcessor.severity, DiagnosticSeverity.ERROR);
// skip
var invalidAssignmentProcessor = errorConfig.processors
.firstWhereOrNull((p) => p.appliesTo(invalid_assignment));
expect(invalidAssignmentProcessor, isNull);
});
});
test('configure lints', () {
var options = AnalysisOptionsProvider().getOptionsFromString(
'analyzer:\n errors:\n annotate_overrides: warning\n',
);
var errorConfig = ErrorConfig(
(options['analyzer'] as YamlMap)['errors'] as YamlNode?,
);
expect(errorConfig.processors, hasLength(1));
ErrorProcessor processor = errorConfig.processors.first;
expect(processor.appliesTo(annotate_overrides), true);
expect(processor.severity, DiagnosticSeverity.WARNING);
});
});
}
class _TestContext {
late AnalysisOptions analysisOptions;
void configureOptions(String options) {
analysisOptions = AnalysisOptionsImpl.fromYaml(
optionsMap: AnalysisOptionsProvider().getOptionsFromString(options),
);
}
ErrorProcessor? getProcessor(Diagnostic diagnostic) {
return ErrorProcessor.getProcessor(analysisOptions, diagnostic);
}
}