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

Side by Side Diff: pkg/analysis_server/tool/spec/codegen_dart_protocol.dart

Issue 492243002: Introduce convenience methods into generated analysis server classes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « pkg/analysis_server/test/services/refactoring/abstract_rename.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library codegen.protocol; 5 library codegen.protocol;
6 6
7 import 'dart:convert'; 7 import 'dart:convert';
8 8
9 import 'api.dart'; 9 import 'api.dart';
10 import 'codegen_tools.dart'; 10 import 'codegen_tools.dart';
11 import 'from_html.dart'; 11 import 'from_html.dart';
12 import 'implied_types.dart'; 12 import 'implied_types.dart';
13 import 'to_html.dart'; 13 import 'to_html.dart';
14 14
15 import 'package:html5lib/dom.dart' as dom;
16
15 /** 17 /**
16 * Container for code that can be used to translate a data type from JSON. 18 * Container for code that can be used to translate a data type from JSON.
17 */ 19 */
18 abstract class FromJsonCode { 20 abstract class FromJsonCode {
19 /** 21 /**
20 * True if the data type is already in JSON form, so the translation is the 22 * True if the data type is already in JSON form, so the translation is the
21 * identity function. 23 * identity function.
22 */ 24 */
23 bool get isIdentity; 25 bool get isIdentity;
24 26
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 * Representation of FromJsonCode for the identity transformation. 158 * Representation of FromJsonCode for the identity transformation.
157 */ 159 */
158 class ToJsonIdentity extends ToJsonSnippet { 160 class ToJsonIdentity extends ToJsonSnippet {
159 ToJsonIdentity(String type) : super(type, (String value) => value); 161 ToJsonIdentity(String type) : super(type, (String value) => value);
160 162
161 @override 163 @override
162 bool get isIdentity => true; 164 bool get isIdentity => true;
163 } 165 }
164 166
165 /** 167 /**
168 * Special flags that need to be inserted into the declaration of the Element
169 * class.
170 */
171 const Map<String, String> specialElementFlags = const {
172 'abstract': '0x01',
173 'const': '0x02',
174 'final': '0x04',
175 'static': '0x08',
176 'private': '0x10',
177 'deprecated': '0x20'
178 };
179
180 /**
166 * Visitor which produces Dart code representing the API. 181 * Visitor which produces Dart code representing the API.
167 */ 182 */
168 class CodegenProtocolVisitor extends HierarchicalApiVisitor with CodeGenerator { 183 class CodegenProtocolVisitor extends HierarchicalApiVisitor with CodeGenerator {
169 /** 184 /**
170 * Type references in the spec that are named something else in Dart. 185 * Type references in the spec that are named something else in Dart.
171 */ 186 */
172 static const Map<String, String> _typeRenames = const { 187 static const Map<String, String> _typeRenames = const {
173 'object': 'Object', 188 'object': 'Object',
174 }; 189 };
175 190
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 docComment(toHtmlVisitor.collectHtml(() { 240 docComment(toHtmlVisitor.collectHtml(() {
226 toHtmlVisitor.p(() { 241 toHtmlVisitor.p(() {
227 toHtmlVisitor.write(impliedType.humanReadableName); 242 toHtmlVisitor.write(impliedType.humanReadableName);
228 }); 243 });
229 if (impliedType.type != null) { 244 if (impliedType.type != null) {
230 toHtmlVisitor.showType(null, impliedType.type); 245 toHtmlVisitor.showType(null, impliedType.type);
231 } 246 }
232 })); 247 }));
233 writeln('class $className implements HasToJson {'); 248 writeln('class $className implements HasToJson {');
234 indent(() { 249 indent(() {
250 if (emitSpecialStaticMembers(className)) {
251 writeln();
252 }
235 for (TypeObjectField field in type.fields) { 253 for (TypeObjectField field in type.fields) {
236 if (field.value != null) { 254 if (field.value != null) {
237 continue; 255 continue;
238 } 256 }
239 docComment(toHtmlVisitor.collectHtml(() { 257 docComment(toHtmlVisitor.collectHtml(() {
240 toHtmlVisitor.translateHtml(field.html); 258 toHtmlVisitor.translateHtml(field.html);
241 })); 259 }));
242 writeln('${dartType(field.type)} ${field.name};'); 260 writeln('${dartType(field.type)} ${field.name};');
243 writeln(); 261 writeln();
244 } 262 }
245 emitObjectConstructor(type, className); 263 emitObjectConstructor(type, className);
246 writeln(); 264 writeln();
247 emitObjectFromJsonConstructor(className, type, impliedType); 265 emitObjectFromJsonConstructor(className, type, impliedType);
248 writeln(); 266 writeln();
249 if (emitConvenienceConstructor(className, impliedType)) { 267 if (emitConvenienceConstructor(className, impliedType)) {
250 writeln(); 268 writeln();
251 } 269 }
270 if (emitSpecialConstructors(className)) {
271 writeln();
272 }
273 if (emitSpecialGetters(className)) {
274 writeln();
275 }
252 emitToJsonMember(type); 276 emitToJsonMember(type);
253 writeln(); 277 writeln();
254 if (emitToRequestMember(impliedType)) { 278 if (emitToRequestMember(impliedType)) {
255 writeln(); 279 writeln();
256 } 280 }
281 if (emitSpecialMembers(className)) {
282 writeln();
283 }
257 writeln('@override'); 284 writeln('@override');
258 writeln('String toString() => JSON.encode(toJson());'); 285 writeln('String toString() => JSON.encode(toJson());');
259 writeln(); 286 writeln();
260 emitObjectEqualsMember(type, className); 287 emitObjectEqualsMember(type, className);
261 writeln(); 288 writeln();
262 emitObjectHashCode(type); 289 emitObjectHashCode(type);
263 }); 290 });
264 writeln('}'); 291 writeln('}');
265 } 292 }
266 293
267 /** 294 /**
295 * If the class named [className] requires special static members, emit them
296 * and return true.
297 */
298 bool emitSpecialStaticMembers(String className) {
299 switch (className) {
300 case 'Element':
301 List<String> makeFlagsArgs = <String>[];
302 List<String> makeFlagsStatements = <String>[];
303 specialElementFlags.forEach((String name, String value) {
304 String flag = 'FLAG_${name.toUpperCase()}';
305 String camelName = camelJoin(['is', name]);
306 writeln('static const int $flag = $value;');
307 makeFlagsArgs.add('$camelName: false');
308 makeFlagsStatements.add('if ($camelName) flags |= $flag;');
309 });
310 writeln();
311 writeln('static int makeFlags({${makeFlagsArgs.join(', ')}}) {');
312 indent(() {
313 writeln('int flags = 0;');
314 for (String statement in makeFlagsStatements) {
315 writeln(statement);
316 }
317 writeln('return flags;');
318 });
319 writeln('}');
320 return true;
321 case 'SourceEdit':
322 docComment([new dom.Text('Get the result of applying a set of ' +
323 '[edits] to the given [code]. Edits are applied in the order ' +
324 'they appear in [edits].')]);
325 writeln(
326 'static String applySequence(String code, Iterable<SourceEdit> edits ) =>');
327 writeln(' _applySequence(code, edits);');
328 return true;
329 default:
330 return false;
331 }
332 }
333
334 /**
335 * If the class named [className] requires special constructors, emit them
336 * and return true.
337 */
338 bool emitSpecialConstructors(String className) {
339 switch (className) {
340 case 'AnalysisError':
341 docComment([new dom.Text(
342 'Construct based on error information from the analyzer engine.')]);
343 writeln(
344 'factory AnalysisError.fromEngine(engine.LineInfo lineInfo, engine.A nalysisError error) =>'
345 );
346 writeln(' _analysisErrorFromEngine(lineInfo, error);');
347 return true;
348 case 'ElementKind':
349 docComment([new dom.Text(
350 'Construct based on a value from the analyzer engine.')]);
351 writeln('factory ElementKind.fromEngine(engine.ElementKind kind) =>');
352 writeln(' _elementKindFromEngine(kind);');
353 return true;
354 case 'SourceEdit':
355 docComment([new dom.Text('Construct based on a SourceRange.')]);
356 writeln(
357 'SourceEdit.range(engine.SourceRange range, String replacement, {Str ing id})');
358 writeln(' : this(range.offset, range.length, replacement, id: id);');
359 return true;
360 default:
361 return false;
362 }
363 }
364
365 /**
366 * If the class named [className] requires special getters, emit them and
367 * return true.
368 */
369 bool emitSpecialGetters(String className) {
370 switch (className) {
371 case 'Element':
372 for (String name in specialElementFlags.keys) {
373 String flag = 'FLAG_${name.toUpperCase()}';
374 writeln('bool get ${camelJoin(['is', name])} => (flags & $flag) != 0;'
375 );
376 }
377 return true;
378 case 'SourceEdit':
379 docComment([new dom.Text('The end of the region to be modified.')]);
380 writeln('int get end => offset + length;');
381 return true;
382 default:
383 return false;
384 }
385 }
386
387 /**
388 * If the class named [className] requires special members, emit them and
389 * return true.
390 */
391 bool emitSpecialMembers(String className) {
392 switch (className) {
393 case 'SourceEdit':
394 docComment([new dom.Text(
395 'Get the result of applying the edit to the given [code].')]);
396 writeln('String apply(String code) => _applyEdit(code, this);');
397 return true;
398 default:
399 return false;
400 }
401 }
402
403 /**
268 * Emit the constructor for an object class. 404 * Emit the constructor for an object class.
269 */ 405 */
270 void emitObjectConstructor(TypeObject type, String className) { 406 void emitObjectConstructor(TypeObject type, String className) {
271 List<String> args = <String>[]; 407 List<String> args = <String>[];
272 List<String> optionalArgs = <String>[]; 408 List<String> optionalArgs = <String>[];
273 for (TypeObjectField field in type.fields) { 409 for (TypeObjectField field in type.fields) {
274 if (field.value != null) { 410 if (field.value != null) {
275 continue; 411 continue;
276 } 412 }
277 String arg = 'this.${field.name}'; 413 String arg = 'this.${field.name}';
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 docComment(toHtmlVisitor.collectHtml(() { 530 docComment(toHtmlVisitor.collectHtml(() {
395 toHtmlVisitor.p(() { 531 toHtmlVisitor.p(() {
396 toHtmlVisitor.write(impliedType.humanReadableName); 532 toHtmlVisitor.write(impliedType.humanReadableName);
397 }); 533 });
398 if (impliedType.type != null) { 534 if (impliedType.type != null) {
399 toHtmlVisitor.showType(null, impliedType.type); 535 toHtmlVisitor.showType(null, impliedType.type);
400 } 536 }
401 })); 537 }));
402 writeln('class $className {'); 538 writeln('class $className {');
403 indent(() { 539 indent(() {
540 if (emitSpecialStaticMembers(className)) {
541 writeln();
542 }
404 for (TypeEnumValue value in type.values) { 543 for (TypeEnumValue value in type.values) {
405 docComment(toHtmlVisitor.collectHtml(() { 544 docComment(toHtmlVisitor.collectHtml(() {
406 toHtmlVisitor.translateHtml(value.html); 545 toHtmlVisitor.translateHtml(value.html);
407 })); 546 }));
408 String valueString = literalString(value.value); 547 String valueString = literalString(value.value);
409 writeln( 548 writeln(
410 'static const ${value.value} = const $className._($valueString);'); 549 'static const ${value.value} = const $className._($valueString);');
411 writeln(); 550 writeln();
412 } 551 }
413 writeln('final String name;'); 552 writeln('final String name;');
414 writeln(); 553 writeln();
415 writeln('const $className._(this.name);'); 554 writeln('const $className._(this.name);');
416 writeln(); 555 writeln();
417 emitEnumClassConstructor(className, type); 556 emitEnumClassConstructor(className, type);
418 writeln(); 557 writeln();
419 emitEnumFromJsonConstructor(className, type, impliedType); 558 emitEnumFromJsonConstructor(className, type, impliedType);
420 writeln(); 559 writeln();
560 if (emitSpecialConstructors(className)) {
561 writeln();
562 }
563 if (emitSpecialGetters(className)) {
564 writeln();
565 }
566 if (emitSpecialMembers(className)) {
567 writeln();
568 }
421 writeln('@override'); 569 writeln('@override');
422 writeln('String toString() => "$className.\$name";'); 570 writeln('String toString() => "$className.\$name";');
423 writeln(); 571 writeln();
424 writeln('String toJson() => name;'); 572 writeln('String toJson() => name;');
425 }); 573 });
426 writeln('}'); 574 writeln('}');
427 } 575 }
428 576
429 /** 577 /**
430 * Emit the constructor for an enum class. 578 * Emit the constructor for an enum class.
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 CodegenProtocolVisitor visitor = new CodegenProtocolVisitor(readApi()); 976 CodegenProtocolVisitor visitor = new CodegenProtocolVisitor(readApi());
829 return visitor.collectCode(visitor.visitApi); 977 return visitor.collectCode(visitor.visitApi);
830 }); 978 });
831 979
832 /** 980 /**
833 * Translate spec_input.html into protocol_matchers.dart. 981 * Translate spec_input.html into protocol_matchers.dart.
834 */ 982 */
835 main() { 983 main() {
836 target.generate(); 984 target.generate();
837 } 985 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/test/services/refactoring/abstract_rename.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698