Skip to content

Commit 8944b80

Browse files
stereotype441Commit Queue
authored andcommitted
[messages] Make MessageAccumulator abstraction.
Modifies the logic of `generateMessagesFilesRaw` so that instead of directly generating the contents of the `cfe_codes_generated.dart` and `codes_generated.dart` files, it uses a helper methods in a new `MessageAccumulator` class. This paves the way for follow-up CLs that will change the structure of the generated code to be more similar to the code generated for the analyzer and related packages. Change-Id: I6a6a6964384ea8a247a0608f8b2fa4cdb17d47c0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/475721 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
1 parent 003d943 commit 8944b80

1 file changed

Lines changed: 129 additions & 86 deletions

File tree

pkg/front_end/tool/generate_messages_lib.dart

Lines changed: 129 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -21,25 +21,25 @@ Uri computeCfeGeneratedFile(Uri repoDir) {
2121
);
2222
}
2323

24-
class Messages {
25-
final String sharedMessages;
26-
final String cfeMessages;
24+
class MessageAccumulator {
25+
static const doNotEditComment =
26+
'// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.';
2727

28-
Messages(this.sharedMessages, this.cfeMessages);
29-
}
28+
/// The buffer in which generated code will be accumulated.
29+
final StringBuffer _buffer = new StringBuffer();
3030

31-
Messages generateMessagesFilesRaw(Uri repoDir) {
32-
StringBuffer sharedMessages = new StringBuffer();
33-
StringBuffer cfeMessages = new StringBuffer();
31+
/// The URI which the generated file which will be part of.
32+
final String partOf;
3433

35-
const String preamble1 = """
34+
MessageAccumulator({required this.partOf}) {
35+
const String preamble1 = """
3636
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
3737
// for details. All rights reserved. Use of this source code is governed by a
3838
// BSD-style license that can be found in the LICENSE file.
3939
4040
""";
4141

42-
const String preamble2 = """
42+
const String preamble2 = """
4343
4444
// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
4545
//
@@ -49,63 +49,96 @@ Messages generateMessagesFilesRaw(Uri repoDir) {
4949
// ignore_for_file: lines_longer_than_80_chars
5050
""";
5151

52-
sharedMessages.writeln(preamble1);
53-
sharedMessages.writeln(preamble2);
54-
sharedMessages.writeln("""
55-
part of 'codes.dart';
52+
_buffer.writeln(preamble1);
53+
_buffer.writeln(preamble2);
54+
_buffer.writeln("""
55+
part of '$partOf';
5656
""");
57+
}
5758

58-
cfeMessages.writeln(preamble1);
59-
cfeMessages.writeln("""
59+
String finish() {
60+
return _buffer.toString();
61+
}
6062

61-
""");
62-
cfeMessages.writeln(preamble2);
63-
cfeMessages.writeln("""
64-
part of 'cfe_codes.dart';
65-
""");
63+
void writeConstant({
64+
required String type,
65+
required String name,
66+
required String initializer,
67+
}) {
68+
_buffer.writeln(doNotEditComment);
69+
_buffer.writeln('const $type $name = $initializer;');
70+
_buffer.writeln();
71+
}
72+
73+
void writeEnum({
74+
required String documentation,
75+
required String name,
76+
required List<String> values,
77+
}) {
78+
_buffer.writeln();
79+
_buffer.writeln('/// $documentation');
80+
_buffer.writeln('enum $name {');
81+
for (var value in values) {
82+
_buffer.writeln(' $value,');
83+
}
84+
_buffer.writeln('}');
85+
}
86+
87+
void writeWithArgumentsFunction(String function) {
88+
_buffer.writeln(doNotEditComment);
89+
_buffer.writeln(function);
90+
}
91+
}
92+
93+
class Messages {
94+
final String sharedMessages;
95+
final String cfeMessages;
96+
97+
Messages(this.sharedMessages, this.cfeMessages);
98+
}
99+
100+
Messages generateMessagesFilesRaw(Uri repoDir) {
101+
MessageAccumulator sharedMessages = new MessageAccumulator(
102+
partOf: 'codes.dart',
103+
);
104+
MessageAccumulator cfeMessages = new MessageAccumulator(
105+
partOf: 'cfe_codes.dart',
106+
);
66107

67108
var pseudoSharedCodeValues = <String>{};
68109
for (var message in diagnosticTables.sortedFrontEndDiagnostics) {
69110
var forFeAnalyzerShared =
70111
message is SharedMessage ||
71112
message is FrontEndMessage && message.pseudoSharedCode != null;
72-
String template = LocatedError.wrap(
113+
LocatedError.wrap(
73114
span: message.keySpan,
74115
() => _TemplateCompiler(
75116
message: message,
76117
pseudoSharedCodeValues: forFeAnalyzerShared
77118
? pseudoSharedCodeValues
78119
: null,
79-
).compile(),
120+
).compile(forFeAnalyzerShared ? sharedMessages : cfeMessages),
80121
);
81-
if (forFeAnalyzerShared) {
82-
sharedMessages.writeln(template);
83-
} else {
84-
cfeMessages.writeln(template);
85-
}
86122
}
87-
sharedMessages.writeln();
88-
sharedMessages.writeln(
89-
'/// Enum containing analyzer error codes referenced by '
90-
'[Code.pseudoSharedCode].',
123+
sharedMessages.writeEnum(
124+
documentation:
125+
'Enum containing analyzer error codes referenced by '
126+
'[Code.pseudoSharedCode].',
127+
name: 'PseudoSharedCode',
128+
values: pseudoSharedCodeValues.toList()..sort(),
91129
);
92-
sharedMessages.writeln('enum PseudoSharedCode {');
93-
for (var code in pseudoSharedCodeValues.toList()..sort()) {
94-
sharedMessages.writeln(' $code,');
95-
}
96-
sharedMessages.writeln('}');
97-
sharedMessages.writeln();
98-
sharedMessages.writeln(
99-
'/// Enum containing analyzer error codes referenced by '
100-
'[Code.sharedCode].',
130+
sharedMessages.writeEnum(
131+
documentation:
132+
'Enum containing analyzer error codes referenced by '
133+
'[Code.sharedCode].',
134+
name: 'SharedCode',
135+
values: [
136+
for (var code in diagnosticTables.sortedSharedDiagnostics)
137+
code.analyzerCode.camelCaseName,
138+
],
101139
);
102-
sharedMessages.writeln('enum SharedCode {');
103-
for (var code in diagnosticTables.sortedSharedDiagnostics) {
104-
sharedMessages.writeln(' ${code.analyzerCode.camelCaseName},');
105-
}
106-
sharedMessages.writeln('}');
107140

108-
return new Messages("$sharedMessages", "$cfeMessages");
141+
return new Messages(sharedMessages.finish(), cfeMessages.finish());
109142
}
110143

111144
/// Returns a fresh identifier that is not yet present in [usedNames], and adds
@@ -161,7 +194,8 @@ class _TemplateCompiler {
161194
? message.pseudoSharedCode
162195
: null;
163196

164-
String compile() {
197+
void compile(MessageAccumulator messageAccumulator) {
198+
var constantName = 'code$name';
165199
var codeArguments = <String>[
166200
if (pseudoSharedCodeValues != null && pseudoSharedCode != null)
167201
'pseudoSharedCode: ${_encodePseudoSharedCode(pseudoSharedCode!)}',
@@ -176,59 +210,68 @@ class _TemplateCompiler {
176210
interpolatedProblemMessage += " + labeler.originMessages";
177211
}
178212

213+
String constantType;
214+
String constantInitializer;
215+
List<String> withArgumentsFunctions = [];
179216
if (parameters.isEmpty) {
180217
codeArguments.add('problemMessage: $interpolatedProblemMessage');
181218
if (correctionMessage != null) {
182219
codeArguments.add('correctionMessage: $interpolatedCorrectionMessage');
183220
}
184221

185-
return """
186-
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
187-
const MessageCode code$name =
188-
const MessageCode(\"$name\", ${codeArguments.join(', ')},);
189-
""";
190-
}
191-
192-
List<String> templateArguments = <String>[];
193-
templateArguments.add('\"$name\"');
194-
templateArguments.add("withArgumentsOld: _withArgumentsOld$name");
195-
templateArguments.add("withArguments: _withArguments$name");
196-
templateArguments.addAll(codeArguments);
197-
198-
List<String> messageArguments = <String>[
199-
"problemMessage: $interpolatedProblemMessage",
200-
if (interpolatedCorrectionMessage case var m?) "correctionMessage: $m",
201-
"arguments: { ${arguments.join(', ')}, }",
202-
];
203-
List<String> positionalParameters = parameters.entries
204-
.map((entry) => '${entry.value.type.cfeName!} ${entry.key}')
205-
.toList();
206-
List<String> namedParameters = parameters.entries
207-
.map((entry) => 'required ${entry.value.type.cfeName!} ${entry.key}')
208-
.toList();
209-
List<String> oldToNewArguments = parameters.keys
210-
.map((name) => '$name: $name')
211-
.toList();
212-
213-
return """
214-
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
215-
const Template<
222+
constantType = 'MessageCode';
223+
constantInitializer =
224+
'const MessageCode("$name", ${codeArguments.join(', ')},)';
225+
} else {
226+
List<String> templateArguments = <String>[];
227+
templateArguments.add('\"$name\"');
228+
templateArguments.add("withArgumentsOld: _withArgumentsOld$name");
229+
templateArguments.add("withArguments: _withArguments$name");
230+
templateArguments.addAll(codeArguments);
231+
232+
List<String> messageArguments = <String>[
233+
"problemMessage: $interpolatedProblemMessage",
234+
if (interpolatedCorrectionMessage case var m?) "correctionMessage: $m",
235+
"arguments: { ${arguments.join(', ')}, }",
236+
];
237+
List<String> positionalParameters = parameters.entries
238+
.map((entry) => '${entry.value.type.cfeName!} ${entry.key}')
239+
.toList();
240+
List<String> namedParameters = parameters.entries
241+
.map((entry) => 'required ${entry.value.type.cfeName!} ${entry.key}')
242+
.toList();
243+
List<String> oldToNewArguments = parameters.keys
244+
.map((name) => '$name: $name')
245+
.toList();
246+
247+
constantType =
248+
"""
249+
Template<
216250
Message Function(${positionalParameters.join(', ')}),
217251
Message Function({${namedParameters.join(', ')}})
218-
> code$name = const Template(${templateArguments.join(', ')},);
219-
220-
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
252+
>""";
253+
constantInitializer = 'const Template(${templateArguments.join(', ')},)';
254+
withArgumentsFunctions.add("""
221255
Message _withArguments$name({${namedParameters.join(', ')}}) {
222256
${withArgumentsStatements.join('\n ')}
223257
return new Message(
224-
code$name,
258+
$constantName,
225259
${messageArguments.join(', ')},);
226260
}
227-
228-
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
261+
""");
262+
withArgumentsFunctions.add("""
229263
Message _withArgumentsOld$name(${positionalParameters.join(', ')}) =>
230264
_withArguments$name(${oldToNewArguments.join(', ')});
231-
""";
265+
""");
266+
}
267+
messageAccumulator.writeConstant(
268+
type: constantType,
269+
name: constantName,
270+
initializer: constantInitializer,
271+
);
272+
for (var withArgumentsFunction in withArgumentsFunctions) {
273+
messageAccumulator.writeWithArgumentsFunction(withArgumentsFunction);
274+
}
232275
}
233276

234277
String computeInterpolator(TemplateParameterPart placeholder) {

0 commit comments

Comments
 (0)