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 |