| 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; | |
| 6 | |
| 7 import 'dart:convert'; | 5 import 'dart:convert'; |
| 8 | 6 |
| 9 import 'package:analyzer/src/codegen/tools.dart'; | 7 import 'package:analyzer/src/codegen/tools.dart'; |
| 10 import 'package:front_end/src/codegen/tools.dart'; | 8 import 'package:front_end/src/codegen/tools.dart'; |
| 11 import 'package:html/dom.dart' as dom; | 9 import 'package:html/dom.dart' as dom; |
| 10 import 'package:path/path.dart' as path; |
| 12 | 11 |
| 13 import 'api.dart'; | 12 import 'api.dart'; |
| 14 import 'codegen_dart.dart'; | 13 import 'codegen_dart.dart'; |
| 15 import 'from_html.dart'; | 14 import 'from_html.dart'; |
| 16 import 'implied_types.dart'; | 15 import 'implied_types.dart'; |
| 17 import 'to_html.dart'; | 16 import 'to_html.dart'; |
| 18 | 17 |
| 19 /** | 18 /** |
| 20 * Special flags that need to be inserted into the declaration of the Element | 19 * Special flags that need to be inserted into the declaration of the Element |
| 21 * class. | 20 * class. |
| 22 */ | 21 */ |
| 23 const Map<String, String> specialElementFlags = const { | 22 const Map<String, String> specialElementFlags = const { |
| 24 'abstract': '0x01', | 23 'abstract': '0x01', |
| 25 'const': '0x02', | 24 'const': '0x02', |
| 26 'final': '0x04', | 25 'final': '0x04', |
| 27 'static': '0x08', | 26 'static': '0x08', |
| 28 'private': '0x10', | 27 'private': '0x10', |
| 29 'deprecated': '0x20' | 28 'deprecated': '0x20' |
| 30 }; | 29 }; |
| 31 | 30 |
| 32 final GeneratedFile target = new GeneratedFile( | 31 final GeneratedFile target = |
| 33 'lib/plugin/protocol/generated_protocol.dart', (String pkgPath) { | 32 new GeneratedFile('lib/protocol/protocol_generated.dart', (String pkgPath) { |
| 34 CodegenProtocolVisitor visitor = new CodegenProtocolVisitor(readApi(pkgPath)); | 33 CodegenProtocolVisitor visitor = |
| 34 new CodegenProtocolVisitor(path.basename(pkgPath), readApi(pkgPath)); |
| 35 return visitor.collectCode(visitor.visitApi); | 35 return visitor.collectCode(visitor.visitApi); |
| 36 }); | 36 }); |
| 37 | 37 |
| 38 /** | 38 /** |
| 39 * Callback type used to represent arbitrary code generation. | 39 * Callback type used to represent arbitrary code generation. |
| 40 */ | 40 */ |
| 41 typedef void CodegenCallback(); | 41 typedef void CodegenCallback(); |
| 42 | 42 |
| 43 typedef String FromJsonSnippetCallback(String jsonPath, String json); | 43 typedef String FromJsonSnippetCallback(String jsonPath, String json); |
| 44 | 44 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 61 }; | 61 }; |
| 62 | 62 |
| 63 /** | 63 /** |
| 64 * The disclaimer added to the documentation comment for each of the classes | 64 * The disclaimer added to the documentation comment for each of the classes |
| 65 * that are generated. | 65 * that are generated. |
| 66 */ | 66 */ |
| 67 static const String disclaimer = | 67 static const String disclaimer = |
| 68 'Clients may not extend, implement or mix-in this class.'; | 68 'Clients may not extend, implement or mix-in this class.'; |
| 69 | 69 |
| 70 /** | 70 /** |
| 71 * The name of the package into which code is being generated. |
| 72 */ |
| 73 final String packageName; |
| 74 |
| 75 /** |
| 71 * Visitor used to produce doc comments. | 76 * Visitor used to produce doc comments. |
| 72 */ | 77 */ |
| 73 final ToHtmlVisitor toHtmlVisitor; | 78 final ToHtmlVisitor toHtmlVisitor; |
| 74 | 79 |
| 75 /** | 80 /** |
| 76 * Types implied by the API. This includes types explicitly named in the | 81 * Types implied by the API. This includes types explicitly named in the |
| 77 * API as well as those implied by the definitions of requests, responses, | 82 * API as well as those implied by the definitions of requests, responses, |
| 78 * notifications, etc. | 83 * notifications, etc. |
| 79 */ | 84 */ |
| 80 final Map<String, ImpliedType> impliedTypes; | 85 final Map<String, ImpliedType> impliedTypes; |
| 81 | 86 |
| 82 CodegenProtocolVisitor(Api api) | 87 CodegenProtocolVisitor(this.packageName, Api api) |
| 83 : toHtmlVisitor = new ToHtmlVisitor(api), | 88 : toHtmlVisitor = new ToHtmlVisitor(api), |
| 84 impliedTypes = computeImpliedTypes(api), | 89 impliedTypes = computeImpliedTypes(api), |
| 85 super(api) { | 90 super(api) { |
| 86 codeGeneratorSettings.commentLineLength = 79; | 91 codeGeneratorSettings.commentLineLength = 79; |
| 87 codeGeneratorSettings.languageName = 'dart'; | 92 codeGeneratorSettings.languageName = 'dart'; |
| 88 } | 93 } |
| 89 | 94 |
| 90 /** | 95 /** |
| 91 * Compute the code necessary to compare two objects for equality. | 96 * Compute the code necessary to compare two objects for equality. |
| 92 */ | 97 */ |
| (...skipping 17 matching lines...) Expand all Loading... |
| 110 return 'mapEqual($thisVar, $otherVar, $closure)'; | 115 return 'mapEqual($thisVar, $otherVar, $closure)'; |
| 111 } | 116 } |
| 112 throw new Exception( | 117 throw new Exception( |
| 113 "Don't know how to compare for equality: $resolvedType"); | 118 "Don't know how to compare for equality: $resolvedType"); |
| 114 } | 119 } |
| 115 | 120 |
| 116 /** | 121 /** |
| 117 * Translate each type implied by the API to a class. | 122 * Translate each type implied by the API to a class. |
| 118 */ | 123 */ |
| 119 void emitClasses() { | 124 void emitClasses() { |
| 120 for (ImpliedType impliedType in impliedTypes.values) { | 125 List<ImpliedType> types = impliedTypes.values.toList(); |
| 126 types.sort((first, second) => |
| 127 capitalize(first.camelName).compareTo(capitalize(second.camelName))); |
| 128 for (ImpliedType impliedType in types) { |
| 121 TypeDecl type = impliedType.type; | 129 TypeDecl type = impliedType.type; |
| 122 String dartTypeName = capitalize(impliedType.camelName); | 130 String dartTypeName = capitalize(impliedType.camelName); |
| 123 if (type == null) { | 131 if (type == null) { |
| 132 writeln(); |
| 124 emitEmptyObjectClass(dartTypeName, impliedType); | 133 emitEmptyObjectClass(dartTypeName, impliedType); |
| 125 } else if (type is TypeObject) { | 134 } else if (type is TypeObject) { |
| 126 writeln(); | 135 writeln(); |
| 127 emitObjectClass(dartTypeName, type, impliedType); | 136 emitObjectClass(dartTypeName, type, impliedType); |
| 128 } else if (type is TypeEnum) { | 137 } else if (type is TypeEnum) { |
| 129 writeln(); | 138 writeln(); |
| 130 emitEnumClass(dartTypeName, type, impliedType); | 139 emitEnumClass(dartTypeName, type, impliedType); |
| 131 } | 140 } |
| 132 } | 141 } |
| 133 } | 142 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 146 // Constructor call to create the JsonDecoder object. | 155 // Constructor call to create the JsonDecoder object. |
| 147 String makeDecoder; | 156 String makeDecoder; |
| 148 // Name of the constructor to create. | 157 // Name of the constructor to create. |
| 149 String constructorName; | 158 String constructorName; |
| 150 // Extra arguments for the constructor. | 159 // Extra arguments for the constructor. |
| 151 List<String> extraArgs = <String>[]; | 160 List<String> extraArgs = <String>[]; |
| 152 switch (impliedType.kind) { | 161 switch (impliedType.kind) { |
| 153 case 'requestParams': | 162 case 'requestParams': |
| 154 inputType = 'Request'; | 163 inputType = 'Request'; |
| 155 inputName = 'request'; | 164 inputName = 'request'; |
| 156 fieldName = '_params'; | 165 fieldName = 'params'; |
| 157 makeDecoder = 'new RequestDecoder(request)'; | 166 makeDecoder = 'new RequestDecoder(request)'; |
| 158 constructorName = 'fromRequest'; | 167 constructorName = 'fromRequest'; |
| 159 break; | 168 break; |
| 160 case 'requestResult': | 169 case 'requestResult': |
| 161 inputType = 'Response'; | 170 inputType = 'Response'; |
| 162 inputName = 'response'; | 171 inputName = 'response'; |
| 163 fieldName = '_result'; | 172 fieldName = 'result'; |
| 164 makeDecoder = | 173 makeDecoder = |
| 165 'new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id
))'; | 174 'new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id
))'; |
| 166 constructorName = 'fromResponse'; | 175 constructorName = 'fromResponse'; |
| 167 break; | 176 break; |
| 168 case 'notificationParams': | 177 case 'notificationParams': |
| 169 inputType = 'Notification'; | 178 inputType = 'Notification'; |
| 170 inputName = 'notification'; | 179 inputName = 'notification'; |
| 171 fieldName = '_params'; | 180 fieldName = 'params'; |
| 172 makeDecoder = 'new ResponseDecoder(null)'; | 181 makeDecoder = 'new ResponseDecoder(null)'; |
| 173 constructorName = 'fromNotification'; | 182 constructorName = 'fromNotification'; |
| 174 break; | 183 break; |
| 175 case 'refactoringOptions': | 184 case 'refactoringOptions': |
| 176 inputType = 'EditGetRefactoringParams'; | 185 inputType = 'EditGetRefactoringParams'; |
| 177 inputName = 'refactoringParams'; | 186 inputName = 'refactoringParams'; |
| 178 fieldName = 'options'; | 187 fieldName = 'options'; |
| 179 makeDecoder = 'new RequestDecoder(request)'; | 188 makeDecoder = 'new RequestDecoder(request)'; |
| 180 constructorName = 'fromRefactoringParams'; | 189 constructorName = 'fromRefactoringParams'; |
| 181 extraArgs.add('Request request'); | 190 extraArgs.add('Request request'); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 212 docComment(toHtmlVisitor.collectHtml(() { | 221 docComment(toHtmlVisitor.collectHtml(() { |
| 213 toHtmlVisitor.p(() { | 222 toHtmlVisitor.p(() { |
| 214 toHtmlVisitor.write(impliedType.humanReadableName); | 223 toHtmlVisitor.write(impliedType.humanReadableName); |
| 215 }); | 224 }); |
| 216 toHtmlVisitor.p(() { | 225 toHtmlVisitor.p(() { |
| 217 toHtmlVisitor.write(disclaimer); | 226 toHtmlVisitor.write(disclaimer); |
| 218 }); | 227 }); |
| 219 })); | 228 })); |
| 220 write('class $className'); | 229 write('class $className'); |
| 221 if (impliedType.kind == 'refactoringFeedback') { | 230 if (impliedType.kind == 'refactoringFeedback') { |
| 222 writeln(' extends RefactoringFeedback {'); | 231 writeln(' extends RefactoringFeedback implements HasToJson {'); |
| 223 } else if (impliedType.kind == 'refactoringOptions') { | 232 } else if (impliedType.kind == 'refactoringOptions') { |
| 224 writeln(' extends RefactoringOptions {'); | 233 writeln(' extends RefactoringOptions implements HasToJson {'); |
| 234 } else if (impliedType.kind == 'requestParams') { |
| 235 writeln(' implements RequestParams {'); |
| 236 } else if (impliedType.kind == 'requestResult') { |
| 237 writeln(' implements ResponseResult {'); |
| 225 } else { | 238 } else { |
| 226 writeln(' {'); | 239 writeln(' {'); |
| 227 } | 240 } |
| 228 indent(() { | 241 indent(() { |
| 242 if (impliedType.kind == 'requestResult' || |
| 243 impliedType.kind == 'requestParams') { |
| 244 emitEmptyToJsonMember(); |
| 245 writeln(); |
| 246 } |
| 229 if (emitToRequestMember(impliedType)) { | 247 if (emitToRequestMember(impliedType)) { |
| 230 writeln(); | 248 writeln(); |
| 231 } | 249 } |
| 232 if (emitToResponseMember(impliedType)) { | 250 if (emitToResponseMember(impliedType)) { |
| 233 writeln(); | 251 writeln(); |
| 234 } | 252 } |
| 235 if (emitToNotificationMember(impliedType)) { | 253 if (emitToNotificationMember(impliedType)) { |
| 236 writeln(); | 254 writeln(); |
| 237 } | 255 } |
| 238 emitObjectEqualsMember(null, className); | 256 emitObjectEqualsMember(null, className); |
| 239 writeln(); | 257 writeln(); |
| 240 emitObjectHashCode(null, className); | 258 emitObjectHashCode(null, className); |
| 241 }); | 259 }); |
| 242 writeln('}'); | 260 writeln('}'); |
| 243 } | 261 } |
| 244 | 262 |
| 245 /** | 263 /** |
| 264 * Emit the toJson() code for an empty class. |
| 265 */ |
| 266 void emitEmptyToJsonMember() { |
| 267 writeln('@override'); |
| 268 writeln('Map<String, dynamic> toJson() => <String, dynamic>{};'); |
| 269 } |
| 270 |
| 271 /** |
| 246 * Emit a class to encapsulate an enum. | 272 * Emit a class to encapsulate an enum. |
| 247 */ | 273 */ |
| 248 void emitEnumClass(String className, TypeEnum type, ImpliedType impliedType) { | 274 void emitEnumClass(String className, TypeEnum type, ImpliedType impliedType) { |
| 249 docComment(toHtmlVisitor.collectHtml(() { | 275 docComment(toHtmlVisitor.collectHtml(() { |
| 250 toHtmlVisitor.p(() { | 276 toHtmlVisitor.p(() { |
| 251 toHtmlVisitor.write(impliedType.humanReadableName); | 277 toHtmlVisitor.write(impliedType.humanReadableName); |
| 252 }); | 278 }); |
| 253 if (impliedType.type != null) { | 279 if (impliedType.type != null) { |
| 254 toHtmlVisitor.showType(null, impliedType.type); | 280 toHtmlVisitor.showType(null, impliedType.type); |
| 255 } | 281 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 285 if (first) { | 311 if (first) { |
| 286 first = false; | 312 first = false; |
| 287 } else { | 313 } else { |
| 288 write(', '); | 314 write(', '); |
| 289 } | 315 } |
| 290 write(value.value); | 316 write(value.value); |
| 291 } | 317 } |
| 292 writeln('];'); | 318 writeln('];'); |
| 293 writeln(); | 319 writeln(); |
| 294 | 320 |
| 321 writeln('@override'); |
| 295 writeln('final String name;'); | 322 writeln('final String name;'); |
| 296 writeln(); | 323 writeln(); |
| 297 writeln('const $className._(this.name);'); | 324 writeln('const $className._(this.name);'); |
| 298 writeln(); | 325 writeln(); |
| 299 emitEnumClassConstructor(className, type); | 326 emitEnumClassConstructor(className, type); |
| 300 writeln(); | 327 writeln(); |
| 301 emitEnumFromJsonConstructor(className, type, impliedType); | 328 emitEnumFromJsonConstructor(className, type, impliedType); |
| 302 writeln(); | 329 writeln(); |
| 303 if (emitSpecialConstructors(className)) { | 330 if (emitSpecialConstructors(className)) { |
| 304 writeln(); | 331 writeln(); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 } | 409 } |
| 383 toHtmlVisitor.p(() { | 410 toHtmlVisitor.p(() { |
| 384 toHtmlVisitor.write(disclaimer); | 411 toHtmlVisitor.write(disclaimer); |
| 385 }); | 412 }); |
| 386 })); | 413 })); |
| 387 write('class $className'); | 414 write('class $className'); |
| 388 if (impliedType.kind == 'refactoringFeedback') { | 415 if (impliedType.kind == 'refactoringFeedback') { |
| 389 writeln(' extends RefactoringFeedback {'); | 416 writeln(' extends RefactoringFeedback {'); |
| 390 } else if (impliedType.kind == 'refactoringOptions') { | 417 } else if (impliedType.kind == 'refactoringOptions') { |
| 391 writeln(' extends RefactoringOptions {'); | 418 writeln(' extends RefactoringOptions {'); |
| 419 } else if (impliedType.kind == 'requestParams') { |
| 420 writeln(' implements RequestParams {'); |
| 421 } else if (impliedType.kind == 'requestResult') { |
| 422 writeln(' implements ResponseResult {'); |
| 392 } else { | 423 } else { |
| 393 writeln(' implements HasToJson {'); | 424 writeln(' implements HasToJson {'); |
| 394 } | 425 } |
| 395 indent(() { | 426 indent(() { |
| 396 if (emitSpecialStaticMembers(className)) { | 427 if (emitSpecialStaticMembers(className)) { |
| 397 writeln(); | 428 writeln(); |
| 398 } | 429 } |
| 399 for (TypeObjectField field in type.fields) { | 430 for (TypeObjectField field in type.fields) { |
| 400 if (field.value != null) { | 431 if (field.value != null) { |
| 401 continue; | 432 continue; |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 indent(() { | 655 indent(() { |
| 625 String fromJson = | 656 String fromJson = |
| 626 fromJsonCode(fieldType).asSnippet(jsonPath, fieldAccessor); | 657 fromJsonCode(fieldType).asSnippet(jsonPath, fieldAccessor); |
| 627 writeln('${field.name} = $fromJson;'); | 658 writeln('${field.name} = $fromJson;'); |
| 628 }); | 659 }); |
| 629 write('}'); | 660 write('}'); |
| 630 if (!field.optional) { | 661 if (!field.optional) { |
| 631 writeln(' else {'); | 662 writeln(' else {'); |
| 632 indent(() { | 663 indent(() { |
| 633 writeln( | 664 writeln( |
| 634 "throw jsonDecoder.missingKey(jsonPath, $fieldNameString);"); | 665 "throw jsonDecoder.mismatch(jsonPath, $fieldNameString);"); |
| 635 }); | 666 }); |
| 636 writeln('}'); | 667 writeln('}'); |
| 637 } else { | 668 } else { |
| 638 writeln(); | 669 writeln(); |
| 639 } | 670 } |
| 640 } | 671 } |
| 641 args.addAll(optionalArgs); | 672 args.addAll(optionalArgs); |
| 642 writeln('return new $className(${args.join(', ')});'); | 673 writeln('return new $className(${args.join(', ')});'); |
| 643 }); | 674 }); |
| 644 writeln('} else {'); | 675 writeln('} else {'); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 return true; | 864 return true; |
| 834 default: | 865 default: |
| 835 return false; | 866 return false; |
| 836 } | 867 } |
| 837 } | 868 } |
| 838 | 869 |
| 839 /** | 870 /** |
| 840 * Emit the toJson() code for an object class. | 871 * Emit the toJson() code for an object class. |
| 841 */ | 872 */ |
| 842 void emitToJsonMember(TypeObject type) { | 873 void emitToJsonMember(TypeObject type) { |
| 874 writeln('@override'); |
| 843 writeln('Map<String, dynamic> toJson() {'); | 875 writeln('Map<String, dynamic> toJson() {'); |
| 844 indent(() { | 876 indent(() { |
| 845 writeln('Map<String, dynamic> result = {};'); | 877 writeln('Map<String, dynamic> result = {};'); |
| 846 for (TypeObjectField field in type.fields) { | 878 for (TypeObjectField field in type.fields) { |
| 847 String fieldNameString = literalString(field.name); | 879 String fieldNameString = literalString(field.name); |
| 848 if (field.value != null) { | 880 if (field.value != null) { |
| 849 writeln('result[$fieldNameString] = ${literalString(field.value)};'); | 881 writeln('result[$fieldNameString] = ${literalString(field.value)};'); |
| 850 continue; | 882 continue; |
| 851 } | 883 } |
| 852 String fieldToJson = toJsonCode(field.type).asSnippet(field.name); | 884 String fieldToJson = toJsonCode(field.type).asSnippet(field.name); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 884 } | 916 } |
| 885 return false; | 917 return false; |
| 886 } | 918 } |
| 887 | 919 |
| 888 /** | 920 /** |
| 889 * Emit the toRequest() code for a class, if appropriate. Returns true if | 921 * Emit the toRequest() code for a class, if appropriate. Returns true if |
| 890 * code was emitted. | 922 * code was emitted. |
| 891 */ | 923 */ |
| 892 bool emitToRequestMember(ImpliedType impliedType) { | 924 bool emitToRequestMember(ImpliedType impliedType) { |
| 893 if (impliedType.kind == 'requestParams') { | 925 if (impliedType.kind == 'requestParams') { |
| 926 writeln('@override'); |
| 894 writeln('Request toRequest(String id) {'); | 927 writeln('Request toRequest(String id) {'); |
| 895 indent(() { | 928 indent(() { |
| 896 String methodString = | 929 String methodString = |
| 897 literalString((impliedType.apiNode as Request).longMethod); | 930 literalString((impliedType.apiNode as Request).longMethod); |
| 898 String jsonPart = impliedType.type != null ? 'toJson()' : 'null'; | 931 String jsonPart = impliedType.type != null ? 'toJson()' : 'null'; |
| 899 writeln('return new Request(id, $methodString, $jsonPart);'); | 932 writeln('return new Request(id, $methodString, $jsonPart);'); |
| 900 }); | 933 }); |
| 901 writeln('}'); | 934 writeln('}'); |
| 902 return true; | 935 return true; |
| 903 } | 936 } |
| 904 return false; | 937 return false; |
| 905 } | 938 } |
| 906 | 939 |
| 907 /** | 940 /** |
| 908 * Emit the toResponse() code for a class, if appropriate. Returns true if | 941 * Emit the toResponse() code for a class, if appropriate. Returns true if |
| 909 * code was emitted. | 942 * code was emitted. |
| 910 */ | 943 */ |
| 911 bool emitToResponseMember(ImpliedType impliedType) { | 944 bool emitToResponseMember(ImpliedType impliedType) { |
| 912 if (impliedType.kind == 'requestResult') { | 945 if (impliedType.kind == 'requestResult') { |
| 946 writeln('@override'); |
| 913 writeln('Response toResponse(String id) {'); | 947 writeln('Response toResponse(String id) {'); |
| 914 indent(() { | 948 indent(() { |
| 915 String jsonPart = impliedType.type != null ? 'toJson()' : 'null'; | 949 String jsonPart = impliedType.type != null ? 'toJson()' : 'null'; |
| 916 writeln('return new Response(id, result: $jsonPart);'); | 950 writeln('return new Response(id, result: $jsonPart);'); |
| 917 }); | 951 }); |
| 918 writeln('}'); | 952 writeln('}'); |
| 919 return true; | 953 return true; |
| 920 } | 954 } |
| 921 return false; | 955 return false; |
| 922 } | 956 } |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1088 } else if (resolvedType is TypeObject || resolvedType is TypeEnum) { | 1122 } else if (resolvedType is TypeObject || resolvedType is TypeEnum) { |
| 1089 return new ToJsonSnippet( | 1123 return new ToJsonSnippet( |
| 1090 dartType(type), (String value) => '$value.toJson()'); | 1124 dartType(type), (String value) => '$value.toJson()'); |
| 1091 } else { | 1125 } else { |
| 1092 throw new Exception("Can't convert $resolvedType from JSON"); | 1126 throw new Exception("Can't convert $resolvedType from JSON"); |
| 1093 } | 1127 } |
| 1094 } | 1128 } |
| 1095 | 1129 |
| 1096 @override | 1130 @override |
| 1097 visitApi() { | 1131 visitApi() { |
| 1098 outputHeader(); | 1132 outputHeader(year: '2017'); |
| 1099 writeln(); | 1133 writeln(); |
| 1100 writeln('part of analysis_server.plugin.protocol.protocol;'); | 1134 writeln("import 'dart:convert' hide JsonDecoder;"); |
| 1101 writeln(); | 1135 writeln(); |
| 1136 writeln("import 'package:analyzer/src/generated/utilities_general.dart';"); |
| 1137 writeln("import 'package:$packageName/protocol/protocol.dart';"); |
| 1138 writeln( |
| 1139 "import 'package:$packageName/src/protocol/protocol_internal.dart';"); |
| 1102 emitClasses(); | 1140 emitClasses(); |
| 1103 } | 1141 } |
| 1104 } | 1142 } |
| 1105 | 1143 |
| 1106 /** | 1144 /** |
| 1107 * Container for code that can be used to translate a data type from JSON. | 1145 * Container for code that can be used to translate a data type from JSON. |
| 1108 */ | 1146 */ |
| 1109 abstract class FromJsonCode { | 1147 abstract class FromJsonCode { |
| 1110 /** | 1148 /** |
| 1111 * Get the translation code in the form of a closure. | 1149 * Get the translation code in the form of a closure. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1123 * is the variable holding the JSON path, and [json] is the variable holding | 1161 * is the variable holding the JSON path, and [json] is the variable holding |
| 1124 * the raw JSON. | 1162 * the raw JSON. |
| 1125 */ | 1163 */ |
| 1126 String asSnippet(String jsonPath, String json); | 1164 String asSnippet(String jsonPath, String json); |
| 1127 } | 1165 } |
| 1128 | 1166 |
| 1129 /** | 1167 /** |
| 1130 * Representation of FromJsonCode for a function defined elsewhere. | 1168 * Representation of FromJsonCode for a function defined elsewhere. |
| 1131 */ | 1169 */ |
| 1132 class FromJsonFunction extends FromJsonCode { | 1170 class FromJsonFunction extends FromJsonCode { |
| 1171 @override |
| 1133 final String asClosure; | 1172 final String asClosure; |
| 1134 | 1173 |
| 1135 FromJsonFunction(this.asClosure); | 1174 FromJsonFunction(this.asClosure); |
| 1136 | 1175 |
| 1137 @override | 1176 @override |
| 1138 bool get isIdentity => false; | 1177 bool get isIdentity => false; |
| 1139 | 1178 |
| 1140 @override | 1179 @override |
| 1141 String asSnippet(String jsonPath, String json) => | 1180 String asSnippet(String jsonPath, String json) => |
| 1142 '$asClosure($jsonPath, $json)'; | 1181 '$asClosure($jsonPath, $json)'; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1194 * Get the translation code in the form of a code snippet, where [value] | 1233 * Get the translation code in the form of a code snippet, where [value] |
| 1195 * is the variable holding the object to be translated. | 1234 * is the variable holding the object to be translated. |
| 1196 */ | 1235 */ |
| 1197 String asSnippet(String value); | 1236 String asSnippet(String value); |
| 1198 } | 1237 } |
| 1199 | 1238 |
| 1200 /** | 1239 /** |
| 1201 * Representation of ToJsonCode for a function defined elsewhere. | 1240 * Representation of ToJsonCode for a function defined elsewhere. |
| 1202 */ | 1241 */ |
| 1203 class ToJsonFunction extends ToJsonCode { | 1242 class ToJsonFunction extends ToJsonCode { |
| 1243 @override |
| 1204 final String asClosure; | 1244 final String asClosure; |
| 1205 | 1245 |
| 1206 ToJsonFunction(this.asClosure); | 1246 ToJsonFunction(this.asClosure); |
| 1207 | 1247 |
| 1208 @override | 1248 @override |
| 1209 bool get isIdentity => false; | 1249 bool get isIdentity => false; |
| 1210 | 1250 |
| 1211 @override | 1251 @override |
| 1212 String asSnippet(String value) => '$asClosure($value)'; | 1252 String asSnippet(String value) => '$asClosure($value)'; |
| 1213 } | 1253 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1241 | 1281 |
| 1242 @override | 1282 @override |
| 1243 String get asClosure => '($type value) => ${callback('value')}'; | 1283 String get asClosure => '($type value) => ${callback('value')}'; |
| 1244 | 1284 |
| 1245 @override | 1285 @override |
| 1246 bool get isIdentity => false; | 1286 bool get isIdentity => false; |
| 1247 | 1287 |
| 1248 @override | 1288 @override |
| 1249 String asSnippet(String value) => callback(value); | 1289 String asSnippet(String value) => callback(value); |
| 1250 } | 1290 } |
| OLD | NEW |