| OLD | NEW |
| 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'; |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 */ | 187 */ |
| 188 class CodegenProtocolVisitor extends HierarchicalApiVisitor with CodeGenerator { | 188 class CodegenProtocolVisitor extends HierarchicalApiVisitor with CodeGenerator { |
| 189 /** | 189 /** |
| 190 * Type references in the spec that are named something else in Dart. | 190 * Type references in the spec that are named something else in Dart. |
| 191 */ | 191 */ |
| 192 static const Map<String, String> _typeRenames = const { | 192 static const Map<String, String> _typeRenames = const { |
| 193 'object': 'Object', | 193 'object': 'Object', |
| 194 }; | 194 }; |
| 195 | 195 |
| 196 /** | 196 /** |
| 197 * Class members for which the constructor argument should be optional, even |
| 198 * if the member is not an optional part of the protocol. For list types, |
| 199 * the constructor will default the member to the empty list. |
| 200 */ |
| 201 static const Map<String, List<String>> _optionalConstructorArguments = const { |
| 202 'SourceFileEdit': const ['edits'], |
| 203 'TypeHierarchyItem': const ['interfaces', 'mixins', 'subclasses'] |
| 204 }; |
| 205 |
| 206 /** |
| 197 * Visitor used to produce doc comments. | 207 * Visitor used to produce doc comments. |
| 198 */ | 208 */ |
| 199 final ToHtmlVisitor toHtmlVisitor; | 209 final ToHtmlVisitor toHtmlVisitor; |
| 200 | 210 |
| 201 /** | 211 /** |
| 202 * Types implied by the API. This includes types explicitly named in the | 212 * Types implied by the API. This includes types explicitly named in the |
| 203 * API as well as those implied by the definitions of requests, responses, | 213 * API as well as those implied by the definitions of requests, responses, |
| 204 * notifications, etc. | 214 * notifications, etc. |
| 205 */ | 215 */ |
| 206 final Map<String, ImpliedType> impliedTypes; | 216 final Map<String, ImpliedType> impliedTypes; |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 */ | 474 */ |
| 465 void emitObjectConstructor(TypeObject type, String className) { | 475 void emitObjectConstructor(TypeObject type, String className) { |
| 466 List<String> args = <String>[]; | 476 List<String> args = <String>[]; |
| 467 List<String> optionalArgs = <String>[]; | 477 List<String> optionalArgs = <String>[]; |
| 468 List<CodegenCallback> extraInitCode = <CodegenCallback>[]; | 478 List<CodegenCallback> extraInitCode = <CodegenCallback>[]; |
| 469 for (TypeObjectField field in type.fields) { | 479 for (TypeObjectField field in type.fields) { |
| 470 if (field.value != null) { | 480 if (field.value != null) { |
| 471 continue; | 481 continue; |
| 472 } | 482 } |
| 473 String arg = 'this.${field.name}'; | 483 String arg = 'this.${field.name}'; |
| 474 if (field.optional) { | 484 if (isOptionalConstructorArg(className, field)) { |
| 475 optionalArgs.add(arg); | 485 optionalArgs.add(arg); |
| 476 TypeDecl fieldType = field.type; | 486 TypeDecl fieldType = field.type; |
| 477 if (fieldType is TypeList) { | 487 if (fieldType is TypeList) { |
| 478 extraInitCode.add(() { | 488 extraInitCode.add(() { |
| 479 writeln('if (${field.name} == null) {'); | 489 writeln('if (${field.name} == null) {'); |
| 480 indent(() { | 490 indent(() { |
| 481 writeln('${field.name} = <${dartType(fieldType.itemType)}>[];'); | 491 writeln('${field.name} = <${dartType(fieldType.itemType)}>[];'); |
| 482 }); | 492 }); |
| 483 writeln('}'); | 493 writeln('}'); |
| 484 }); | 494 }); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 498 indent(() { | 508 indent(() { |
| 499 for (CodegenCallback callback in extraInitCode) { | 509 for (CodegenCallback callback in extraInitCode) { |
| 500 callback(); | 510 callback(); |
| 501 } | 511 } |
| 502 }); | 512 }); |
| 503 writeln('}'); | 513 writeln('}'); |
| 504 } | 514 } |
| 505 } | 515 } |
| 506 | 516 |
| 507 /** | 517 /** |
| 518 * True if the constructor argument for the given field should be optional. |
| 519 */ |
| 520 bool isOptionalConstructorArg(String className, TypeObjectField field) { |
| 521 if (field.optional) { |
| 522 return true; |
| 523 } |
| 524 List<String> forceOptional = _optionalConstructorArguments[className]; |
| 525 if (forceOptional != null && forceOptional.contains(field.name)) { |
| 526 return true; |
| 527 } |
| 528 return false; |
| 529 } |
| 530 |
| 531 /** |
| 508 * Emit the toJson() code for an object class. | 532 * Emit the toJson() code for an object class. |
| 509 */ | 533 */ |
| 510 void emitToJsonMember(TypeObject type) { | 534 void emitToJsonMember(TypeObject type) { |
| 511 writeln('Map<String, dynamic> toJson() {'); | 535 writeln('Map<String, dynamic> toJson() {'); |
| 512 indent(() { | 536 indent(() { |
| 513 writeln('Map<String, dynamic> result = {};'); | 537 writeln('Map<String, dynamic> result = {};'); |
| 514 for (TypeObjectField field in type.fields) { | 538 for (TypeObjectField field in type.fields) { |
| 515 String fieldNameString = literalString(field.name); | 539 String fieldNameString = literalString(field.name); |
| 516 if (field.value != null) { | 540 if (field.value != null) { |
| 517 writeln('result[$fieldNameString] = ${literalString(field.value)};'); | 541 writeln('result[$fieldNameString] = ${literalString(field.value)};'); |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 if (field.value != null) { | 829 if (field.value != null) { |
| 806 String valueString = literalString(field.value); | 830 String valueString = literalString(field.value); |
| 807 writeln('if ($fieldAccessor != $valueString) {'); | 831 writeln('if ($fieldAccessor != $valueString) {'); |
| 808 indent(() { | 832 indent(() { |
| 809 writeln( | 833 writeln( |
| 810 'throw jsonDecoder.mismatch(jsonPath, "equal " + $valueString)
;'); | 834 'throw jsonDecoder.mismatch(jsonPath, "equal " + $valueString)
;'); |
| 811 }); | 835 }); |
| 812 writeln('}'); | 836 writeln('}'); |
| 813 continue; | 837 continue; |
| 814 } | 838 } |
| 815 if (field.optional) { | 839 if (isOptionalConstructorArg(className, field)) { |
| 816 optionalArgs.add('${field.name}: ${field.name}'); | 840 optionalArgs.add('${field.name}: ${field.name}'); |
| 817 } else { | 841 } else { |
| 818 args.add(field.name); | 842 args.add(field.name); |
| 819 } | 843 } |
| 820 TypeDecl fieldType = field.type; | 844 TypeDecl fieldType = field.type; |
| 821 String fieldDartType = dartType(fieldType); | 845 String fieldDartType = dartType(fieldType); |
| 822 writeln('$fieldDartType ${field.name};'); | 846 writeln('$fieldDartType ${field.name};'); |
| 823 writeln('if (json.containsKey($fieldNameString)) {'); | 847 writeln('if (json.containsKey($fieldNameString)) {'); |
| 824 indent(() { | 848 indent(() { |
| 825 String toJson = fromJsonCode(fieldType).asSnippet(jsonPath, | 849 String toJson = fromJsonCode(fieldType).asSnippet(jsonPath, |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1086 CodegenProtocolVisitor visitor = new CodegenProtocolVisitor(readApi()); | 1110 CodegenProtocolVisitor visitor = new CodegenProtocolVisitor(readApi()); |
| 1087 return visitor.collectCode(visitor.visitApi); | 1111 return visitor.collectCode(visitor.visitApi); |
| 1088 }); | 1112 }); |
| 1089 | 1113 |
| 1090 /** | 1114 /** |
| 1091 * Translate spec_input.html into protocol_matchers.dart. | 1115 * Translate spec_input.html into protocol_matchers.dart. |
| 1092 */ | 1116 */ |
| 1093 main() { | 1117 main() { |
| 1094 target.generate(); | 1118 target.generate(); |
| 1095 } | 1119 } |
| OLD | NEW |