[messages] Create a script to add types to messages.yaml files.

Adds a script, `add_types_to_yaml.dart`, which will add `type:`
entries to analyzer-style `messages.yaml` files.

Currently the only function of these entries is that they are checked
against the diagnostic types implied by the diagnostic's class name
(diagnostics under the heading `CompileTimeErrorCode` must have type
`compileTimeError`, those under `StaticWarningCode` must have type
`staticWarning`, etc).

In a follow-up CL I will run the script, adding these `type:` entries,
and then change the code generation logic to use them instead of
inferring the type from the diagnostic code's class. This will pave
the way for removing the notion of diagnostic code class entirely.

Change-Id: I6a6a6964fc4c06a7b2c15fd10d0bd500c3c3f3f4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/464281
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Paul Berry
2025-11-25 09:40:03 -08:00
committed by Commit Queue
parent 5f569bf333
commit 837bc936c3
2 changed files with 59 additions and 0 deletions
+1
View File
@@ -21,5 +21,6 @@ dependencies:
# Use 'any' constraints here; we get our versions from the DEPS file.
dev_dependencies:
analyzer_plugin: any
lints: any
test_reflective_loader: any
@@ -0,0 +1,58 @@
// 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.
/// This is a temporary utility that modifies `messages.yaml` files in the
/// analyzer and related packages so that each message contains a `type` field
/// that identifies its type, rather than inferring the type from the message's
/// class name.
library;
import 'dart:io';
import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_utilities/analyzer_messages.dart';
import 'package:analyzer_utilities/messages.dart';
import 'package:collection/collection.dart';
void main() async {
Map<Uri, Converter> converters = {};
for (var message in [
...analyzerMessages,
...analysisServerMessages,
...feAnalyzerSharedMessages,
...lintMessages,
]) {
var sourceUrl = message.keySpan.sourceUrl;
(converters[sourceUrl!] ??= Converter(
File(sourceUrl.toFilePath()),
)).convertMessage(message);
}
for (var converter in converters.values) {
converter.apply();
}
}
class Converter {
final File file;
late final String content = file.readAsStringSync();
final List<SourceEdit> edits = [];
Converter(this.file);
void apply() {
edits.sortBy((e) => -e.offset);
file.writeAsStringSync(SourceEdit.applySequence(content, edits));
}
void convertMessage(Message message) {
if (message is MessageWithAnalyzerCode) {
var type = message.analyzerCode.diagnosticClass.type;
var insertPosition = message.valueSpan.start.offset;
var indentLevel = message.valueSpan.start.column;
var indent = ' ' * indentLevel;
edits.add(SourceEdit(insertPosition, 0, 'type: ${type.name}\n$indent'));
}
}
}