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

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

Issue 1398293002: Move the wire protocol support into the public API (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Add missed files Created 5 years, 2 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
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 'package:html/dom.dart' as dom; 9 import 'package:html/dom.dart' as dom;
10 10
(...skipping 18 matching lines...) Expand all
29 const Map<String, String> specialElementFlags = const { 29 const Map<String, String> specialElementFlags = const {
30 'abstract': '0x01', 30 'abstract': '0x01',
31 'const': '0x02', 31 'const': '0x02',
32 'final': '0x04', 32 'final': '0x04',
33 'static': '0x08', 33 'static': '0x08',
34 'private': '0x10', 34 'private': '0x10',
35 'deprecated': '0x20' 35 'deprecated': '0x20'
36 }; 36 };
37 37
38 final GeneratedFile target = 38 final GeneratedFile target =
39 new GeneratedFile('../../lib/src/generated_protocol.dart', () { 39 new GeneratedFile('../../lib/plugin/protocol/generated_protocol.dart', () {
40 CodegenProtocolVisitor visitor = new CodegenProtocolVisitor(readApi()); 40 CodegenProtocolVisitor visitor = new CodegenProtocolVisitor(readApi());
41 return visitor.collectCode(visitor.visitApi); 41 return visitor.collectCode(visitor.visitApi);
42 }); 42 });
43 43
44 /** 44 /**
45 * Callback type used to represent arbitrary code generation. 45 * Callback type used to represent arbitrary code generation.
46 */ 46 */
47 typedef void CodegenCallback(); 47 typedef void CodegenCallback();
48 48
49 typedef String FromJsonSnippetCallback(String jsonPath, String json); 49 typedef String FromJsonSnippetCallback(String jsonPath, String json);
(...skipping 10 matching lines...) Expand all
60 * the constructor will default the member to the empty list. 60 * the constructor will default the member to the empty list.
61 */ 61 */
62 static const Map<String, List<String>> _optionalConstructorArguments = const { 62 static const Map<String, List<String>> _optionalConstructorArguments = const {
63 'AnalysisErrorFixes': const ['fixes'], 63 'AnalysisErrorFixes': const ['fixes'],
64 'SourceChange': const ['edits', 'linkedEditGroups'], 64 'SourceChange': const ['edits', 'linkedEditGroups'],
65 'SourceFileEdit': const ['edits'], 65 'SourceFileEdit': const ['edits'],
66 'TypeHierarchyItem': const ['interfaces', 'mixins', 'subclasses'], 66 'TypeHierarchyItem': const ['interfaces', 'mixins', 'subclasses'],
67 }; 67 };
68 68
69 /** 69 /**
70 * The disclaimer added to the documentation comment for each of the classes
71 * that are generated.
72 */
73 static const String disclaimer =
74 'Clients are not expected to subtype this class.';
75
76 /**
70 * Visitor used to produce doc comments. 77 * Visitor used to produce doc comments.
71 */ 78 */
72 final ToHtmlVisitor toHtmlVisitor; 79 final ToHtmlVisitor toHtmlVisitor;
73 80
74 /** 81 /**
75 * Types implied by the API. This includes types explicitly named in the 82 * Types implied by the API. This includes types explicitly named in the
76 * API as well as those implied by the definitions of requests, responses, 83 * API as well as those implied by the definitions of requests, responses,
77 * notifications, etc. 84 * notifications, etc.
78 */ 85 */
79 final Map<String, ImpliedType> impliedTypes; 86 final Map<String, ImpliedType> impliedTypes;
(...skipping 13 matching lines...) Expand all
93 TypeDecl resolvedType = resolveTypeReferenceChain(type); 100 TypeDecl resolvedType = resolveTypeReferenceChain(type);
94 if (resolvedType is TypeReference || 101 if (resolvedType is TypeReference ||
95 resolvedType is TypeEnum || 102 resolvedType is TypeEnum ||
96 resolvedType is TypeObject || 103 resolvedType is TypeObject ||
97 resolvedType is TypeUnion) { 104 resolvedType is TypeUnion) {
98 return '$thisVar == $otherVar'; 105 return '$thisVar == $otherVar';
99 } else if (resolvedType is TypeList) { 106 } else if (resolvedType is TypeList) {
100 String itemTypeName = dartType(resolvedType.itemType); 107 String itemTypeName = dartType(resolvedType.itemType);
101 String subComparison = compareEqualsCode(resolvedType.itemType, 'a', 'b'); 108 String subComparison = compareEqualsCode(resolvedType.itemType, 'a', 'b');
102 String closure = '($itemTypeName a, $itemTypeName b) => $subComparison'; 109 String closure = '($itemTypeName a, $itemTypeName b) => $subComparison';
103 return '_listEqual($thisVar, $otherVar, $closure)'; 110 return 'listEqual($thisVar, $otherVar, $closure)';
104 } else if (resolvedType is TypeMap) { 111 } else if (resolvedType is TypeMap) {
105 String valueTypeName = dartType(resolvedType.valueType); 112 String valueTypeName = dartType(resolvedType.valueType);
106 String subComparison = 113 String subComparison =
107 compareEqualsCode(resolvedType.valueType, 'a', 'b'); 114 compareEqualsCode(resolvedType.valueType, 'a', 'b');
108 String closure = '($valueTypeName a, $valueTypeName b) => $subComparison'; 115 String closure = '($valueTypeName a, $valueTypeName b) => $subComparison';
109 return '_mapEqual($thisVar, $otherVar, $closure)'; 116 return 'mapEqual($thisVar, $otherVar, $closure)';
110 } 117 }
111 throw new Exception( 118 throw new Exception(
112 "Don't know how to compare for equality: $resolvedType"); 119 "Don't know how to compare for equality: $resolvedType");
113 } 120 }
114 121
115 /** 122 /**
116 * Translate each type implied by the API to a class. 123 * Translate each type implied by the API to a class.
117 */ 124 */
118 void emitClasses() { 125 void emitClasses() {
119 for (ImpliedType impliedType in impliedTypes.values) { 126 for (ImpliedType impliedType in impliedTypes.values) {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 /** 212 /**
206 * Emit a class representing an data structure that doesn't exist in the 213 * Emit a class representing an data structure that doesn't exist in the
207 * protocol because it is empty (e.g. the "params" object for a request that 214 * protocol because it is empty (e.g. the "params" object for a request that
208 * doesn't have any parameters). 215 * doesn't have any parameters).
209 */ 216 */
210 void emitEmptyObjectClass(String className, ImpliedType impliedType) { 217 void emitEmptyObjectClass(String className, ImpliedType impliedType) {
211 docComment(toHtmlVisitor.collectHtml(() { 218 docComment(toHtmlVisitor.collectHtml(() {
212 toHtmlVisitor.p(() { 219 toHtmlVisitor.p(() {
213 toHtmlVisitor.write(impliedType.humanReadableName); 220 toHtmlVisitor.write(impliedType.humanReadableName);
214 }); 221 });
222 toHtmlVisitor.p(() {
223 toHtmlVisitor.write(disclaimer);
224 });
215 })); 225 }));
216 writeln('class $className {'); 226 writeln('class $className {');
217 indent(() { 227 indent(() {
218 if (emitToRequestMember(impliedType)) { 228 if (emitToRequestMember(impliedType)) {
219 writeln(); 229 writeln();
220 } 230 }
221 if (emitToResponseMember(impliedType)) { 231 if (emitToResponseMember(impliedType)) {
222 writeln(); 232 writeln();
223 } 233 }
224 if (emitToNotificationMember(impliedType)) { 234 if (emitToNotificationMember(impliedType)) {
(...skipping 10 matching lines...) Expand all
235 * Emit a class to encapsulate an enum. 245 * Emit a class to encapsulate an enum.
236 */ 246 */
237 void emitEnumClass(String className, TypeEnum type, ImpliedType impliedType) { 247 void emitEnumClass(String className, TypeEnum type, ImpliedType impliedType) {
238 docComment(toHtmlVisitor.collectHtml(() { 248 docComment(toHtmlVisitor.collectHtml(() {
239 toHtmlVisitor.p(() { 249 toHtmlVisitor.p(() {
240 toHtmlVisitor.write(impliedType.humanReadableName); 250 toHtmlVisitor.write(impliedType.humanReadableName);
241 }); 251 });
242 if (impliedType.type != null) { 252 if (impliedType.type != null) {
243 toHtmlVisitor.showType(null, impliedType.type); 253 toHtmlVisitor.showType(null, impliedType.type);
244 } 254 }
255 toHtmlVisitor.p(() {
256 toHtmlVisitor.write(disclaimer);
257 });
245 })); 258 }));
246 writeln('class $className implements Enum {'); 259 writeln('class $className implements Enum {');
247 indent(() { 260 indent(() {
248 if (emitSpecialStaticMembers(className)) { 261 if (emitSpecialStaticMembers(className)) {
249 writeln(); 262 writeln();
250 } 263 }
251 for (TypeEnumValue value in type.values) { 264 for (TypeEnumValue value in type.values) {
252 docComment(toHtmlVisitor.collectHtml(() { 265 docComment(toHtmlVisitor.collectHtml(() {
253 toHtmlVisitor.translateHtml(value.html); 266 toHtmlVisitor.translateHtml(value.html);
254 })); 267 }));
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 */ 372 */
360 void emitObjectClass( 373 void emitObjectClass(
361 String className, TypeObject type, ImpliedType impliedType) { 374 String className, TypeObject type, ImpliedType impliedType) {
362 docComment(toHtmlVisitor.collectHtml(() { 375 docComment(toHtmlVisitor.collectHtml(() {
363 toHtmlVisitor.p(() { 376 toHtmlVisitor.p(() {
364 toHtmlVisitor.write(impliedType.humanReadableName); 377 toHtmlVisitor.write(impliedType.humanReadableName);
365 }); 378 });
366 if (impliedType.type != null) { 379 if (impliedType.type != null) {
367 toHtmlVisitor.showType(null, impliedType.type); 380 toHtmlVisitor.showType(null, impliedType.type);
368 } 381 }
382 toHtmlVisitor.p(() {
383 toHtmlVisitor.write(disclaimer);
384 });
369 })); 385 }));
370 write('class $className'); 386 write('class $className');
371 if (impliedType.kind == 'refactoringFeedback') { 387 if (impliedType.kind == 'refactoringFeedback') {
372 write(' extends RefactoringFeedback'); 388 write(' extends RefactoringFeedback');
373 } 389 }
374 if (impliedType.kind == 'refactoringOptions') { 390 if (impliedType.kind == 'refactoringOptions') {
375 write(' extends RefactoringOptions'); 391 write(' extends RefactoringOptions');
376 } 392 }
377 writeln(' implements HasToJson {'); 393 writeln(' implements HasToJson {');
378 indent(() { 394 indent(() {
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 * Emit the method for decoding an object from JSON. 562 * Emit the method for decoding an object from JSON.
547 */ 563 */
548 void emitObjectFromJsonConstructor( 564 void emitObjectFromJsonConstructor(
549 String className, TypeObject type, ImpliedType impliedType) { 565 String className, TypeObject type, ImpliedType impliedType) {
550 String humanReadableNameString = 566 String humanReadableNameString =
551 literalString(impliedType.humanReadableName); 567 literalString(impliedType.humanReadableName);
552 if (className == 'RefactoringFeedback') { 568 if (className == 'RefactoringFeedback') {
553 writeln('factory RefactoringFeedback.fromJson(JsonDecoder jsonDecoder, ' 569 writeln('factory RefactoringFeedback.fromJson(JsonDecoder jsonDecoder, '
554 'String jsonPath, Object json, Map responseJson) {'); 570 'String jsonPath, Object json, Map responseJson) {');
555 indent(() { 571 indent(() {
556 writeln('return _refactoringFeedbackFromJson(jsonDecoder, jsonPath, ' 572 writeln('return refactoringFeedbackFromJson(jsonDecoder, jsonPath, '
557 'json, responseJson);'); 573 'json, responseJson);');
558 }); 574 });
559 writeln('}'); 575 writeln('}');
560 return; 576 return;
561 } 577 }
562 if (className == 'RefactoringOptions') { 578 if (className == 'RefactoringOptions') {
563 writeln('factory RefactoringOptions.fromJson(JsonDecoder jsonDecoder, ' 579 writeln('factory RefactoringOptions.fromJson(JsonDecoder jsonDecoder, '
564 'String jsonPath, Object json, RefactoringKind kind) {'); 580 'String jsonPath, Object json, RefactoringKind kind) {');
565 indent(() { 581 indent(() {
566 writeln('return _refactoringOptionsFromJson(jsonDecoder, jsonPath, ' 582 writeln('return refactoringOptionsFromJson(jsonDecoder, jsonPath, '
567 'json, kind);'); 583 'json, kind);');
568 }); 584 });
569 writeln('}'); 585 writeln('}');
570 return; 586 return;
571 } 587 }
572 writeln( 588 writeln(
573 'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, O bject json) {'); 589 'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, O bject json) {');
574 indent(() { 590 indent(() {
575 writeln('if (json == null) {'); 591 writeln('if (json == null) {');
576 indent(() { 592 indent(() {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 writeln('return ${className.hashCode};'); 661 writeln('return ${className.hashCode};');
646 } else { 662 } else {
647 writeln('int hash = 0;'); 663 writeln('int hash = 0;');
648 for (TypeObjectField field in type.fields) { 664 for (TypeObjectField field in type.fields) {
649 String valueToCombine; 665 String valueToCombine;
650 if (field.value != null) { 666 if (field.value != null) {
651 valueToCombine = field.value.hashCode.toString(); 667 valueToCombine = field.value.hashCode.toString();
652 } else { 668 } else {
653 valueToCombine = '${field.name}.hashCode'; 669 valueToCombine = '${field.name}.hashCode';
654 } 670 }
655 writeln('hash = _JenkinsSmiHash.combine(hash, $valueToCombine);'); 671 writeln('hash = JenkinsSmiHash.combine(hash, $valueToCombine);');
656 } 672 }
657 writeln('return _JenkinsSmiHash.finish(hash);'); 673 writeln('return JenkinsSmiHash.finish(hash);');
658 } 674 }
659 }); 675 });
660 writeln('}'); 676 writeln('}');
661 } 677 }
662 678
663 /** 679 /**
664 * If the class named [className] requires special constructors, emit them 680 * If the class named [className] requires special constructors, emit them
665 * and return true. 681 * and return true.
666 */ 682 */
667 bool emitSpecialConstructors(String className) { 683 bool emitSpecialConstructors(String className) {
668 switch (className) { 684 switch (className) {
669 case 'LinkedEditGroup': 685 case 'LinkedEditGroup':
670 docComment([new dom.Text('Construct an empty LinkedEditGroup.')]); 686 docComment([new dom.Text('Construct an empty LinkedEditGroup.')]);
671 writeln( 687 writeln(
672 'LinkedEditGroup.empty() : this(<Position>[], 0, <LinkedEditSuggesti on>[]);'); 688 'LinkedEditGroup.empty() : this(<Position>[], 0, <LinkedEditSuggesti on>[]);');
673 return true; 689 return true;
674 case 'RefactoringProblemSeverity': 690 case 'RefactoringProblemSeverity':
675 docComment([ 691 docComment([
676 new dom.Text( 692 new dom.Text(
677 'Returns the [RefactoringProblemSeverity] with the maximal severit y.') 693 'Returns the [RefactoringProblemSeverity] with the maximal severit y.')
678 ]); 694 ]);
679 writeln( 695 writeln(
680 'static RefactoringProblemSeverity max(RefactoringProblemSeverity a, RefactoringProblemSeverity b) =>'); 696 'static RefactoringProblemSeverity max(RefactoringProblemSeverity a, RefactoringProblemSeverity b) =>');
681 writeln(' _maxRefactoringProblemSeverity(a, b);'); 697 writeln(' maxRefactoringProblemSeverity(a, b);');
682 return true; 698 return true;
683 default: 699 default:
684 return false; 700 return false;
685 } 701 }
686 } 702 }
687 703
688 /** 704 /**
689 * If the class named [className] requires special getters, emit them and 705 * If the class named [className] requires special getters, emit them and
690 * return true. 706 * return true.
691 */ 707 */
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 indent(() { 743 indent(() {
728 writeln('suggestions.add(suggestion);'); 744 writeln('suggestions.add(suggestion);');
729 }); 745 });
730 writeln('}'); 746 writeln('}');
731 return true; 747 return true;
732 case 'SourceChange': 748 case 'SourceChange':
733 docComment([ 749 docComment([
734 new dom.Text('Adds [edit] to the [FileEdit] for the given [file].') 750 new dom.Text('Adds [edit] to the [FileEdit] for the given [file].')
735 ]); 751 ]);
736 writeln('void addEdit(String file, int fileStamp, SourceEdit edit) =>'); 752 writeln('void addEdit(String file, int fileStamp, SourceEdit edit) =>');
737 writeln(' _addEditToSourceChange(this, file, fileStamp, edit);'); 753 writeln(' addEditToSourceChange(this, file, fileStamp, edit);');
738 writeln(); 754 writeln();
739 docComment([new dom.Text('Adds the given [FileEdit].')]); 755 docComment([new dom.Text('Adds the given [FileEdit].')]);
740 writeln('void addFileEdit(SourceFileEdit edit) {'); 756 writeln('void addFileEdit(SourceFileEdit edit) {');
741 indent(() { 757 indent(() {
742 writeln('edits.add(edit);'); 758 writeln('edits.add(edit);');
743 }); 759 });
744 writeln('}'); 760 writeln('}');
745 writeln(); 761 writeln();
746 docComment([new dom.Text('Adds the given [LinkedEditGroup].')]); 762 docComment([new dom.Text('Adds the given [LinkedEditGroup].')]);
747 writeln('void addLinkedEditGroup(LinkedEditGroup linkedEditGroup) {'); 763 writeln('void addLinkedEditGroup(LinkedEditGroup linkedEditGroup) {');
748 indent(() { 764 indent(() {
749 writeln('linkedEditGroups.add(linkedEditGroup);'); 765 writeln('linkedEditGroups.add(linkedEditGroup);');
750 }); 766 });
751 writeln('}'); 767 writeln('}');
752 writeln(); 768 writeln();
753 docComment([ 769 docComment([
754 new dom.Text( 770 new dom.Text(
755 'Returns the [FileEdit] for the given [file], maybe `null`.') 771 'Returns the [FileEdit] for the given [file], maybe `null`.')
756 ]); 772 ]);
757 writeln('SourceFileEdit getFileEdit(String file) =>'); 773 writeln('SourceFileEdit getFileEdit(String file) =>');
758 writeln(' _getChangeFileEdit(this, file);'); 774 writeln(' getChangeFileEdit(this, file);');
759 return true; 775 return true;
760 case 'SourceEdit': 776 case 'SourceEdit':
761 docComment([ 777 docComment([
762 new dom.Text( 778 new dom.Text(
763 'Get the result of applying the edit to the given [code].') 779 'Get the result of applying the edit to the given [code].')
764 ]); 780 ]);
765 writeln('String apply(String code) => _applyEdit(code, this);'); 781 writeln('String apply(String code) => applyEdit(code, this);');
766 return true; 782 return true;
767 case 'SourceFileEdit': 783 case 'SourceFileEdit':
768 docComment([new dom.Text('Adds the given [Edit] to the list.')]); 784 docComment([new dom.Text('Adds the given [Edit] to the list.')]);
769 writeln('void add(SourceEdit edit) => _addEditForSource(this, edit);'); 785 writeln('void add(SourceEdit edit) => addEditForSource(this, edit);');
770 writeln(); 786 writeln();
771 docComment([new dom.Text('Adds the given [Edit]s.')]); 787 docComment([new dom.Text('Adds the given [Edit]s.')]);
772 writeln('void addAll(Iterable<SourceEdit> edits) =>'); 788 writeln('void addAll(Iterable<SourceEdit> edits) =>');
773 writeln(' _addAllEditsForSource(this, edits);'); 789 writeln(' addAllEditsForSource(this, edits);');
774 return true; 790 return true;
775 default: 791 default:
776 return false; 792 return false;
777 } 793 }
778 } 794 }
779 795
780 /** 796 /**
781 * If the class named [className] requires special static members, emit them 797 * If the class named [className] requires special static members, emit them
782 * and return true. 798 * and return true.
783 */ 799 */
(...skipping 21 matching lines...) Expand all
805 writeln('}'); 821 writeln('}');
806 return true; 822 return true;
807 case 'SourceEdit': 823 case 'SourceEdit':
808 docComment([ 824 docComment([
809 new dom.Text('Get the result of applying a set of ' + 825 new dom.Text('Get the result of applying a set of ' +
810 '[edits] to the given [code]. Edits are applied in the order ' + 826 '[edits] to the given [code]. Edits are applied in the order ' +
811 'they appear in [edits].') 827 'they appear in [edits].')
812 ]); 828 ]);
813 writeln( 829 writeln(
814 'static String applySequence(String code, Iterable<SourceEdit> edits ) =>'); 830 'static String applySequence(String code, Iterable<SourceEdit> edits ) =>');
815 writeln(' _applySequence(code, edits);'); 831 writeln(' applySequenceOfEdits(code, edits);');
816 return true; 832 return true;
817 default: 833 default:
818 return false; 834 return false;
819 } 835 }
820 } 836 }
821 837
822 /** 838 /**
823 * Emit the toJson() code for an object class. 839 * Emit the toJson() code for an object class.
824 */ 840 */
825 void emitToJsonMember(TypeObject type) { 841 void emitToJsonMember(TypeObject type) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 } else { 938 } else {
923 return 'new $typeName.fromJson(jsonDecoder, $jsonPath, $json)'; 939 return 'new $typeName.fromJson(jsonDecoder, $jsonPath, $json)';
924 } 940 }
925 }); 941 });
926 } else { 942 } else {
927 return fromJsonCode(referencedType); 943 return fromJsonCode(referencedType);
928 } 944 }
929 } else { 945 } else {
930 switch (type.typeName) { 946 switch (type.typeName) {
931 case 'String': 947 case 'String':
932 return new FromJsonFunction('jsonDecoder._decodeString'); 948 return new FromJsonFunction('jsonDecoder.decodeString');
933 case 'bool': 949 case 'bool':
934 return new FromJsonFunction('jsonDecoder._decodeBool'); 950 return new FromJsonFunction('jsonDecoder.decodeBool');
935 case 'int': 951 case 'int':
936 case 'long': 952 case 'long':
937 return new FromJsonFunction('jsonDecoder._decodeInt'); 953 return new FromJsonFunction('jsonDecoder.decodeInt');
938 case 'object': 954 case 'object':
939 return new FromJsonIdentity(); 955 return new FromJsonIdentity();
940 default: 956 default:
941 throw new Exception('Unexpected type name ${type.typeName}'); 957 throw new Exception('Unexpected type name ${type.typeName}');
942 } 958 }
943 } 959 }
944 } else if (type is TypeMap) { 960 } else if (type is TypeMap) {
945 FromJsonCode keyCode; 961 FromJsonCode keyCode;
946 if (dartType(type.keyType) != 'String') { 962 if (dartType(type.keyType) != 'String') {
947 keyCode = fromJsonCode(type.keyType); 963 keyCode = fromJsonCode(type.keyType);
948 } else { 964 } else {
949 keyCode = new FromJsonIdentity(); 965 keyCode = new FromJsonIdentity();
950 } 966 }
951 FromJsonCode valueCode = fromJsonCode(type.valueType); 967 FromJsonCode valueCode = fromJsonCode(type.valueType);
952 if (keyCode.isIdentity && valueCode.isIdentity) { 968 if (keyCode.isIdentity && valueCode.isIdentity) {
953 return new FromJsonFunction('jsonDecoder._decodeMap'); 969 return new FromJsonFunction('jsonDecoder.decodeMap');
954 } else { 970 } else {
955 return new FromJsonSnippet((String jsonPath, String json) { 971 return new FromJsonSnippet((String jsonPath, String json) {
956 StringBuffer result = new StringBuffer(); 972 StringBuffer result = new StringBuffer();
957 result.write('jsonDecoder._decodeMap($jsonPath, $json'); 973 result.write('jsonDecoder.decodeMap($jsonPath, $json');
958 if (!keyCode.isIdentity) { 974 if (!keyCode.isIdentity) {
959 result.write(', keyDecoder: ${keyCode.asClosure}'); 975 result.write(', keyDecoder: ${keyCode.asClosure}');
960 } 976 }
961 if (!valueCode.isIdentity) { 977 if (!valueCode.isIdentity) {
962 result.write(', valueDecoder: ${valueCode.asClosure}'); 978 result.write(', valueDecoder: ${valueCode.asClosure}');
963 } 979 }
964 result.write(')'); 980 result.write(')');
965 return result.toString(); 981 return result.toString();
966 }); 982 });
967 } 983 }
968 } else if (type is TypeList) { 984 } else if (type is TypeList) {
969 FromJsonCode itemCode = fromJsonCode(type.itemType); 985 FromJsonCode itemCode = fromJsonCode(type.itemType);
970 if (itemCode.isIdentity) { 986 if (itemCode.isIdentity) {
971 return new FromJsonFunction('jsonDecoder._decodeList'); 987 return new FromJsonFunction('jsonDecoder.decodeList');
972 } else { 988 } else {
973 return new FromJsonSnippet((String jsonPath, String json) => 989 return new FromJsonSnippet((String jsonPath, String json) =>
974 'jsonDecoder._decodeList($jsonPath, $json, ${itemCode.asClosure})'); 990 'jsonDecoder.decodeList($jsonPath, $json, ${itemCode.asClosure})');
975 } 991 }
976 } else if (type is TypeUnion) { 992 } else if (type is TypeUnion) {
977 List<String> decoders = <String>[]; 993 List<String> decoders = <String>[];
978 for (TypeDecl choice in type.choices) { 994 for (TypeDecl choice in type.choices) {
979 TypeDecl resolvedChoice = resolveTypeReferenceChain(choice); 995 TypeDecl resolvedChoice = resolveTypeReferenceChain(choice);
980 if (resolvedChoice is TypeObject) { 996 if (resolvedChoice is TypeObject) {
981 TypeObjectField field = resolvedChoice.getField(type.field); 997 TypeObjectField field = resolvedChoice.getField(type.field);
982 if (field == null) { 998 if (field == null) {
983 throw new Exception( 999 throw new Exception(
984 'Each choice in the union needs a field named ${type.field}'); 1000 'Each choice in the union needs a field named ${type.field}');
985 } 1001 }
986 if (field.value == null) { 1002 if (field.value == null) {
987 throw new Exception( 1003 throw new Exception(
988 'Each choice in the union needs a constant value for the field $ {type.field}'); 1004 'Each choice in the union needs a constant value for the field $ {type.field}');
989 } 1005 }
990 String closure = fromJsonCode(choice).asClosure; 1006 String closure = fromJsonCode(choice).asClosure;
991 decoders.add('${literalString(field.value)}: $closure'); 1007 decoders.add('${literalString(field.value)}: $closure');
992 } else { 1008 } else {
993 throw new Exception('Union types must be unions of objects.'); 1009 throw new Exception('Union types must be unions of objects.');
994 } 1010 }
995 } 1011 }
996 return new FromJsonSnippet((String jsonPath, String json) => 1012 return new FromJsonSnippet((String jsonPath, String json) =>
997 'jsonDecoder._decodeUnion($jsonPath, $json, ${literalString(type.field )}, {${decoders.join(', ')}})'); 1013 'jsonDecoder.decodeUnion($jsonPath, $json, ${literalString(type.field) }, {${decoders.join(', ')}})');
998 } else { 1014 } else {
999 throw new Exception("Can't convert $type from JSON"); 1015 throw new Exception("Can't convert $type from JSON");
1000 } 1016 }
1001 } 1017 }
1002 1018
1003 /** 1019 /**
1004 * True if the constructor argument for the given field should be optional. 1020 * True if the constructor argument for the given field should be optional.
1005 */ 1021 */
1006 bool isOptionalConstructorArg(String className, TypeObjectField field) { 1022 bool isOptionalConstructorArg(String className, TypeObjectField field) {
1007 if (field.optional) { 1023 if (field.optional) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 dartType(type), (String value) => '$value.toJson()'); 1089 dartType(type), (String value) => '$value.toJson()');
1074 } else { 1090 } else {
1075 throw new Exception("Can't convert $resolvedType from JSON"); 1091 throw new Exception("Can't convert $resolvedType from JSON");
1076 } 1092 }
1077 } 1093 }
1078 1094
1079 @override 1095 @override
1080 visitApi() { 1096 visitApi() {
1081 outputHeader(); 1097 outputHeader();
1082 writeln(); 1098 writeln();
1083 writeln('part of protocol;'); 1099 writeln('part of analysis_server.plugin.protocol.protocol;');
1100 writeln();
1084 emitClasses(); 1101 emitClasses();
1085 } 1102 }
1086 } 1103 }
1087 1104
1088 /** 1105 /**
1089 * Container for code that can be used to translate a data type from JSON. 1106 * Container for code that can be used to translate a data type from JSON.
1090 */ 1107 */
1091 abstract class FromJsonCode { 1108 abstract class FromJsonCode {
1092 /** 1109 /**
1093 * Get the translation code in the form of a closure. 1110 * Get the translation code in the form of a closure.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 1240
1224 @override 1241 @override
1225 String get asClosure => '($type value) => ${callback('value')}'; 1242 String get asClosure => '($type value) => ${callback('value')}';
1226 1243
1227 @override 1244 @override
1228 bool get isIdentity => false; 1245 bool get isIdentity => false;
1229 1246
1230 @override 1247 @override
1231 String asSnippet(String value) => callback(value); 1248 String asSnippet(String value) => callback(value);
1232 } 1249 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698