Skip to content

Commit b32ef34

Browse files
stereotype441Commit Queue
authored andcommitted
[messages] Prepare to add shared messages.yaml file.
Updates the code in `pkg/analyzer_utilities/lib/messages.dart` to attempt to read CFE messages from both `pkg/_fe_analyzer_shared/messages.yaml` and `pkg/front_end/messages.yaml`, and updates clients accordingly. Also updates the `messages_suite.dart` test and the presubmit rules to ensure that the contents of `pkg/_fe_analyzer_shared/messages.yaml` will be appropriately tested. Since the file `pkg/_fe_analyzer_shared/messages.yaml` doesn't exist yet, temporaryhacks have been added to pretend the file is empty if it can't be found. In a follow-up CL, I will move messages that are shared between the analyzer and the CFE to `pkg/_fe_analyzer_shared/messages.yaml`. Change-Id: I6a6a6964c1c02f20df9ae8e34f23e734bbe88c22 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/448605 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Paul Berry <[email protected]>
1 parent 2871699 commit b32ef34

File tree

9 files changed

+700
-619
lines changed

9 files changed

+700
-619
lines changed

pkg/analyzer/test/src/fasta/message_coverage_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class AbstractRecoveryTest extends FastaParserTestCase {
3838
/// Return a list of the front end messages that define an 'analyzerCode'.
3939
List<String> getMappedCodes() {
4040
Set<String> codes = <String>{};
41-
for (var entry in frontEndMessages.entries) {
41+
for (var entry in frontEndAndSharedMessages.entries) {
4242
var name = entry.key;
4343
var errorCodeInfo = entry.value;
4444
if (errorCodeInfo.analyzerCode.isNotEmpty) {
@@ -52,7 +52,7 @@ class AbstractRecoveryTest extends FastaParserTestCase {
5252
/// `messages.yaml` file.
5353
List<String> getReferencedCodes() {
5454
Set<String> codes = <String>{};
55-
for (var errorCodeInfo in frontEndMessages.values) {
55+
for (var errorCodeInfo in frontEndAndSharedMessages.values) {
5656
codes.addAll(errorCodeInfo.analyzerCode);
5757
}
5858
return codes.toList();

pkg/analyzer/tool/messages/error_code_info.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ final String analyzerPkgPath = normalize(
168168

169169
/// A set of tables mapping between front end and analyzer error codes.
170170
final CfeToAnalyzerErrorCodeTables cfeToAnalyzerErrorCodeTables =
171-
CfeToAnalyzerErrorCodeTables._(frontEndMessages);
171+
CfeToAnalyzerErrorCodeTables._(frontEndAndSharedMessages);
172172

173173
/// The path to the `linter` package.
174174
final String linterPkgPath = normalize(join(pkg_root.packageRoot, 'linter'));
@@ -334,7 +334,7 @@ class CfeToAnalyzerErrorCodeTables {
334334
/// automatically generated, and whose values are the front end error name.
335335
final Map<ErrorCodeInfo, String> infoToFrontEndCode = {};
336336

337-
CfeToAnalyzerErrorCodeTables._(Map<String, FrontEndErrorCodeInfo> messages) {
337+
CfeToAnalyzerErrorCodeTables._(Map<String, CfeStyleErrorCodeInfo> messages) {
338338
for (var entry in messages.entries) {
339339
var errorCodeInfo = entry.value;
340340
var index = errorCodeInfo.index;

pkg/analyzer_utilities/lib/messages.dart

Lines changed: 128 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,29 @@ const Map<String, String> severityEnumNames = <String, String>{
2020
'INFO': 'info',
2121
};
2222

23+
/// Decoded messages from the `_fe_analyzer_shared` package's `messages.yaml`
24+
/// file.
25+
final Map<String, CfeStyleErrorCodeInfo> feAnalyzerSharedMessages =
26+
_loadCfeStyleMessages(
27+
feAnalyzerSharedPkgPath,
28+
allowNonExistent: true,
29+
isShared: true,
30+
);
31+
32+
/// The path to the `fe_analyzer_shared` package.
33+
final String feAnalyzerSharedPkgPath = normalize(
34+
join(pkg_root.packageRoot, '_fe_analyzer_shared'),
35+
);
36+
37+
/// Decoded messages from the `messages.yaml` files in the front end and
38+
/// `_fe_analyzer_shared`.
39+
final Map<String, CfeStyleErrorCodeInfo> frontEndAndSharedMessages = Map.from(
40+
frontEndMessages,
41+
)..addAll(feAnalyzerSharedMessages);
42+
2343
/// Decoded messages from the front end's `messages.yaml` file.
24-
final Map<String, FrontEndErrorCodeInfo> frontEndMessages =
25-
_loadFrontEndMessages();
44+
final Map<String, CfeStyleErrorCodeInfo> frontEndMessages =
45+
_loadCfeStyleMessages(frontEndPkgPath, isShared: false);
2646

2747
/// The path to the `front_end` package.
2848
final String frontEndPkgPath = normalize(
@@ -51,14 +71,17 @@ String convertTemplate(Map<String, int> placeholderToIndexMap, String entry) {
5171
);
5272
}
5373

54-
/// Decodes a YAML object (obtained from `pkg/front_end/messages.yaml`) into a
55-
/// map from error name to [ErrorCodeInfo].
56-
Map<String, FrontEndErrorCodeInfo> decodeCfeMessagesYaml(Object? yaml) {
74+
/// Decodes a YAML object (in CFE style `messages.yaml` format) into a map from
75+
/// error name to [ErrorCodeInfo].
76+
Map<String, CfeStyleErrorCodeInfo> decodeCfeStyleMessagesYaml(
77+
Object? yaml, {
78+
required bool isShared,
79+
}) {
5780
Never problem(String message) {
5881
throw 'Problem in pkg/front_end/messages.yaml: $message';
5982
}
6083

61-
var result = <String, FrontEndErrorCodeInfo>{};
84+
var result = <String, CfeStyleErrorCodeInfo>{};
6285
if (yaml is! Map<Object?, Object?>) {
6386
problem('root node is not a map');
6487
}
@@ -72,22 +95,36 @@ Map<String, FrontEndErrorCodeInfo> decodeCfeMessagesYaml(Object? yaml) {
7295
problem('value associated with error $errorName is not a map');
7396
}
7497
try {
75-
result[errorName] = FrontEndErrorCodeInfo.fromYaml(errorValue);
98+
result[errorName] = CfeStyleErrorCodeInfo.fromYaml(
99+
errorValue,
100+
isShared: isShared,
101+
);
76102
} catch (e, st) {
77103
Error.throwWithStackTrace('while processing $errorName, $e', st);
78104
}
79105
}
80106
return result;
81107
}
82108

83-
/// Loads front end messages from the front end's `messages.yaml` file.
84-
Map<String, FrontEndErrorCodeInfo> _loadFrontEndMessages() {
85-
var path = join(frontEndPkgPath, 'messages.yaml');
109+
/// Loads messages in CFE style `messages.yaml` format.
110+
///
111+
/// If [allowNonExistent] is `true`, and the `messages.yaml` file does not
112+
/// exist, an empty map is returned. This is a temporary measure to allow for an
113+
/// easier transition when the file `pkg/_fe_analyzer_shared/messages.yaml` is
114+
/// created.
115+
// TODO(paulberry): remove [allowNonExistent] once it's no longer needed.
116+
Map<String, CfeStyleErrorCodeInfo> _loadCfeStyleMessages(
117+
String packagePath, {
118+
bool allowNonExistent = false,
119+
required bool isShared,
120+
}) {
121+
var path = join(packagePath, 'messages.yaml');
122+
if (allowNonExistent && !File(path).existsSync()) return {};
86123
Object? messagesYaml = loadYaml(
87124
File(path).readAsStringSync(),
88125
sourceUrl: Uri.file(path),
89126
);
90-
return decodeCfeMessagesYaml(messagesYaml);
127+
return decodeCfeStyleMessagesYaml(messagesYaml, isShared: isShared);
91128
}
92129

93130
/// Splits [text] on spaces using the given [maxWidth] (and [firstLineWidth] if
@@ -130,6 +167,86 @@ List<String> _splitText(
130167
return lines;
131168
}
132169

170+
/// In-memory representation of error code information obtained from a
171+
/// `messages.yaml` file in `pkg/front_end` or `pkg/_fe_analyzer_shared`.
172+
class CfeStyleErrorCodeInfo extends ErrorCodeInfo {
173+
/// The set of analyzer error codes that corresponds to this error code, if
174+
/// any.
175+
final List<String> analyzerCode;
176+
177+
/// The index of the error in the analyzer's `fastaAnalyzerErrorCodes` table.
178+
final int? index;
179+
180+
/// The name of the [CfeSeverity] constant describing this error code's CFE
181+
/// severity.
182+
final String? cfeSeverity;
183+
184+
CfeStyleErrorCodeInfo.fromYaml(YamlMap yaml, {required bool isShared})
185+
: analyzerCode = _decodeAnalyzerCode(yaml['analyzerCode']),
186+
index = _decodeIndex(yaml['index']),
187+
cfeSeverity = _decodeSeverity(yaml['severity']),
188+
super.fromYaml(yaml) {
189+
if (yaml['problemMessage'] == null) {
190+
throw 'Missing problemMessage';
191+
}
192+
if (isShared && analyzerCode.length != 1) {
193+
throw StateError('Shared messages must have exactly one analyzerCode');
194+
}
195+
}
196+
197+
@override
198+
Map<Object?, Object?> toYaml() => {
199+
if (analyzerCode.isNotEmpty)
200+
'analyzerCode': _encodeAnalyzerCode(analyzerCode),
201+
if (index != null) 'index': index,
202+
...super.toYaml(),
203+
};
204+
205+
static List<String> _decodeAnalyzerCode(Object? value) {
206+
if (value == null) {
207+
return const [];
208+
} else if (value is String) {
209+
return [value];
210+
} else if (value is List) {
211+
return [for (var s in value) s as String];
212+
} else {
213+
throw 'Unrecognized analyzer code: $value';
214+
}
215+
}
216+
217+
static int? _decodeIndex(Object? value) {
218+
switch (value) {
219+
case null:
220+
return null;
221+
case int():
222+
if (value >= 1) {
223+
return value;
224+
}
225+
}
226+
throw 'Expected positive int for "index:", but found $value';
227+
}
228+
229+
static String? _decodeSeverity(Object? yamlEntry) {
230+
switch (yamlEntry) {
231+
case null:
232+
return null;
233+
case String():
234+
return severityEnumNames[yamlEntry] ??
235+
(throw "Unknown severity '$yamlEntry'");
236+
default:
237+
throw 'Bad severity type: ${yamlEntry.runtimeType}';
238+
}
239+
}
240+
241+
static Object _encodeAnalyzerCode(List<String> analyzerCode) {
242+
if (analyzerCode.length == 1) {
243+
return analyzerCode.single;
244+
} else {
245+
return analyzerCode;
246+
}
247+
}
248+
}
249+
133250
/// Information about how to convert the CFE's internal representation of a
134251
/// template parameter to a string.
135252
///
@@ -688,83 +805,6 @@ enum ErrorCodeParameterType {
688805
bool get isSupportedByAnalyzer => _analyzerName != null;
689806
}
690807

691-
/// In-memory representation of error code information obtained from the front
692-
/// end's `messages.yaml` file.
693-
class FrontEndErrorCodeInfo extends ErrorCodeInfo {
694-
/// The set of analyzer error codes that corresponds to this error code, if
695-
/// any.
696-
final List<String> analyzerCode;
697-
698-
/// The index of the error in the analyzer's `fastaAnalyzerErrorCodes` table.
699-
final int? index;
700-
701-
/// The name of the [CfeSeverity] constant describing this error code's CFE
702-
/// severity.
703-
final String? cfeSeverity;
704-
705-
FrontEndErrorCodeInfo.fromYaml(YamlMap yaml)
706-
: analyzerCode = _decodeAnalyzerCode(yaml['analyzerCode']),
707-
index = _decodeIndex(yaml['index']),
708-
cfeSeverity = _decodeSeverity(yaml['severity']),
709-
super.fromYaml(yaml) {
710-
if (yaml['problemMessage'] == null) {
711-
throw 'Missing problemMessage';
712-
}
713-
}
714-
715-
@override
716-
Map<Object?, Object?> toYaml() => {
717-
if (analyzerCode.isNotEmpty)
718-
'analyzerCode': _encodeAnalyzerCode(analyzerCode),
719-
if (index != null) 'index': index,
720-
...super.toYaml(),
721-
};
722-
723-
static List<String> _decodeAnalyzerCode(Object? value) {
724-
if (value == null) {
725-
return const [];
726-
} else if (value is String) {
727-
return [value];
728-
} else if (value is List) {
729-
return [for (var s in value) s as String];
730-
} else {
731-
throw 'Unrecognized analyzer code: $value';
732-
}
733-
}
734-
735-
static int? _decodeIndex(Object? value) {
736-
switch (value) {
737-
case null:
738-
return null;
739-
case int():
740-
if (value >= 1) {
741-
return value;
742-
}
743-
}
744-
throw 'Expected positive int for "index:", but found $value';
745-
}
746-
747-
static String? _decodeSeverity(Object? yamlEntry) {
748-
switch (yamlEntry) {
749-
case null:
750-
return null;
751-
case String():
752-
return severityEnumNames[yamlEntry] ??
753-
(throw "Unknown severity '$yamlEntry'");
754-
default:
755-
throw 'Bad severity type: ${yamlEntry.runtimeType}';
756-
}
757-
}
758-
759-
static Object _encodeAnalyzerCode(List<String> analyzerCode) {
760-
if (analyzerCode.length == 1) {
761-
return analyzerCode.single;
762-
} else {
763-
return analyzerCode;
764-
}
765-
}
766-
}
767-
768808
/// Representation of a single file containing generated error codes.
769809
class GeneratedErrorCodeFile {
770810
/// The file path (relative to the SDK's `pkg` directory) of the generated

0 commit comments

Comments
 (0)