Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: pkg/dart_messages/bin/publish.dart

Issue 1582903003: Generate dart2js and analyzer files for shared messages. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Move json file. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 import 'dart:convert';
6 import 'dart:io';
7
8 import '../lib/shared_messages.dart';
9
10 const String jsonPath = '../lib/generated/shared_messages.json';
11 const String dart2jsPath =
12 '../../compiler/lib/src/diagnostics/generated/shared_messages.dart';
13 const String analyzerPath =
14 '../../analyzer/lib/src/generated/generated/shared_messages.dart';
15
16 final String dontEditWarning = """
17 /*
18 DON'T EDIT. GENERATED. DON'T EDIT.
19 This file has been generated by 'publish.dart' in the dart_messages package.
Brian Wilkerson 2016/01/23 18:27:10 This comment should include instructions for how t
floitsch 2016/01/25 12:08:42 Done.
20 */""";
21
22 const String copyrightHeader = '''
23 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
24 // for details. All rights reserved. Use of this source code is governed by a
25 // BSD-style license that can be found in the LICENSE file.''';
26
27 void markAsReadonly(String path) {
28 // TODO(15078): mark as read-only. Currently not possible:
29 // http://dartbug.com/15078.
30 }
31
32 void emitJson() {
33 var input = MESSAGES;
34 var outPath = Platform.script.resolve(jsonPath).toFilePath();
35 print("Emitting JSON:");
36 print(" Input: ${input.length} entries");
37 print(" Output: $outPath");
38 new File(outPath).writeAsStringSync(messagesAsJson);
39 print("Emitting JSON done.");
40 }
41
42 String escapeString(String str) {
43 return JSON.encode(str);
44 }
45
46 /// Emits the messages in dart2js format.
47 ///
48 /// The dart2js-format consists of two entities:
49 /// 1. the `MessageKind` enum, and
50 /// 2. the MessageKind-to-Template map `TEMPLATES`.
51 ///
52 /// The template is an instance of MessageTemplate:
53 ///
54 /// const MessageTemplate(
55 /// this.kind,
56 /// this.template,
57 /// {this.howToFix,
58 /// this.examples,
59 /// this.options: const <String>[]});
60 ///
61 /// A sample output thus looks as follows:
62 ///
63 /// enum MessageKind {
64 /// EXAMPLE_MESSAGE,
65 /// }
66 ///
67 /// const Map<MessageKind, MessageTemplate> {
68 /// EXAMPLE_MESSAGE: const MessageTemplate(
69 /// EXAMPLE_MESSAGE,
70 /// "Don't use #foo with #bar",
71 /// howToFix: "Just don't do it",
72 /// options: const ['--some-flag']),
73 /// examples: const ['''
74 /// some example with bad code;'''],
75 /// };
76 void emitDart2js() {
77 var input = MESSAGES;
78 var outPath = Platform.script.resolve(dart2jsPath).toFilePath();
79 print("Emitting dart2js:");
80 print(" Input: ${input.length} entries");
81 print(" Output: $outPath");
82
83 var enumIds = input.keys.toList();
84
85 StringBuffer out = new StringBuffer();
86 out.writeln(dontEditWarning);
87 out.writeln(copyrightHeader);
88 out.writeln("import '../messages.dart' show MessageTemplate;");
89 out.writeln();
90 out.write(("enum SharedMessageKind {\n "));
91 // We generate on one line on purpose, so that users are less likely to
92 // modify the generated file.
93 out.writeln(enumIds.join(",\n "));
94 out.writeln("}");
95 out.writeln();
96 out.writeln("const Map<SharedMessageKind, MessageTemplate> TEMPLATES = "
97 "const <SharedMessageKind, MessageTemplate>{ ");
98 input.forEach((name, message) {
99 out.writeln(" SharedMessageKind.$name: const MessageTemplate(");
100 // TODO(floitsch): include id.
101 out.writeln(" SharedMessageKind.$name,");
102 out.write(" ");
103 out.write(escapeString(message.template));
104 if (message.howToFix != null) {
105 out.write(",\n howToFix: ${escapeString(message.howToFix)}");
106 }
107 if (message.options != null) {
108 out.write(",\n options: const [");
109 out.write(message.options.map(escapeString).join(","));
110 out.writeln("]");
111 }
112 if (message.examples != null) {
113 out.writeln(",\n examples: const [");
114 for (var example in message.examples) {
115 if (example is String) {
116 out.writeln(" r'''");
117 out.write(example);
118 out.write("'''");
119 } else if (example is Map) {
120 out.writeln(" const {");
121 example.forEach((String fileName, String content) {
122 out.writeln(" '$fileName': r'''");
123 out.write(content);
124 out.writeln("''',");
125 });
126 out.write(" }");
127 }
128 out.writeln(",");
129 }
130 out.writeln(" ]");
131 }
132 out.writeln(" ), // Generated. Don't edit.");
133 });
134 out.writeln("};");
135
136 new File(outPath).writeAsStringSync(out.toString());
137 print("Emitting dart2js done.");
138 }
139
140 String convertToAnalyzerTemplate(String template, holeOrder) {
141 var holeMap;
142 if (holeOrder != null) {
143 holeMap = {};
144 for (int i = 0; i < holeOrder.length; i++) {
145 holeMap[holeOrder[i]] = i;
146 }
147 }
148 int seenHoles = 0;
149 return template.replaceAllMapped(new RegExp(r"#\w+"), (Match match) {
150 if (holeMap != null) {
151 String holeName = match[0].substring(1);
152 int index = holeMap[holeName];
153 if (index == null) {
154 throw "Couldn't find hole-position for $holeName $holeMap";
155 }
156 return "{$index}";
157 } else {
158 return "{${seenHoles++}}";
159 }
160 });
161 }
162
163 /// Emits the messages in analyzer format.
164 ///
165 /// Messages are encoded as instances of `ErrorCode` classes where the
166 /// corresponding class is given by the `category` field of the Message.
167 ///
168 /// All instances are stored as top-level const variables.
169 ///
170 /// A sample output looks as follows:
171 ///
172 /// const EXAMPLE_MESSAGE = const FooCategoryErrorCode(
Brian Wilkerson 2016/01/23 18:27:11 I think this is missing the class name: const Foo
floitsch 2016/01/25 12:08:42 Done.
173 /// "EXAMPLE_MESSAGE",
174 /// "Don't use #foo with #bar",
Brian Wilkerson 2016/01/23 18:27:10 And I think messages get converted to "Don't use
floitsch 2016/01/25 12:08:42 Done.
175 /// "Just don't do it"); // The how-to-fix.
Brian Wilkerson 2016/01/23 18:27:10 "The how-to-fix." --> "Generated. Don't edit." (or
floitsch 2016/01/25 12:08:42 Done.
176 void emitAnalyzer() {
177 var input = MESSAGES;
178 var outPath = Platform.script.resolve(analyzerPath).toFilePath();
179 print("Emitting analyzer:");
180 print(" Input: ${input.length} entries");
181 print(" Output: $outPath");
182
183 StringBuffer out = new StringBuffer();
184 out.writeln(dontEditWarning);
185 out.writeln(copyrightHeader);
186 out.writeln("import '../error.dart';");
Brian Wilkerson 2016/01/23 18:27:10 We avoid relative paths where possible, so I would
floitsch 2016/01/25 12:08:42 I do the exact opposite: avoid non-relative paths
187 out.writeln();
188 input.forEach((name, message) {
189 Category category = message.category;
190 String className = category.name + "Code";
191 out.writeln("const $className $name = const $className(");
192 out.writeln(" '$name',");
193
194 String template = message.template;
195 List holeOrder = message.templateHoleOrder;
196 String analyzerTemplate = convertToAnalyzerTemplate(template, holeOrder);
197 out.write(" ");
198 out.write(escapeString(analyzerTemplate));
199
200 if (message.howToFix) {
Brian Wilkerson 2016/01/23 18:27:11 I think this wants to be "message.howToFix != null
floitsch 2016/01/25 12:08:42 Done.
201 out.write("\n, ${escapeString(message.howToFix)}");
202 }
203
204 out.writeln("); // Generated. Don't edit.");
Brian Wilkerson 2016/01/23 18:27:10 Having this on every constant seems like overkill.
floitsch 2016/01/25 12:08:42 Up to you, but since they don't hurt I think they
205 });
206
207 new File(outPath).writeAsStringSync(out.toString());
208 print("Emitting analyzer done.");
209 }
210
211 /// Translates the shared messages in `../lib/shared_messages.dart` to JSON,
212 /// dart2js, and analyzer formats.
213 ///
214 /// Emits the json-output to [jsonPath], the dart2js-output to [dart2jsPath],
215 /// and the analyzer-output to [analyzerPath].
216 void main() {
217 emitJson();
218 emitDart2js();
219 emitAnalyzer();
220 }
OLDNEW
« no previous file with comments | « pkg/dart_messages/bin/message_id.dart ('k') | pkg/dart_messages/lib/generated/shared_messages.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698