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

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

Issue 506433002: Finish modifying analysis server to make use of code generation. (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/socket_server_test.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';
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 219
220 CodegenProtocolVisitor(Api api) 220 CodegenProtocolVisitor(Api api)
221 : super(api), 221 : super(api),
222 toHtmlVisitor = new ToHtmlVisitor(api), 222 toHtmlVisitor = new ToHtmlVisitor(api),
223 impliedTypes = computeImpliedTypes(api); 223 impliedTypes = computeImpliedTypes(api);
224 224
225 @override 225 @override
226 visitApi() { 226 visitApi() {
227 outputHeader(); 227 outputHeader();
228 writeln(); 228 writeln();
229 writeln('part of protocol2;'); 229 writeln('part of protocol;');
230 emitClasses(); 230 emitClasses();
231 } 231 }
232 232
233 /** 233 /**
234 * Translate each type implied by the API to a class. 234 * Translate each type implied by the API to a class.
235 */ 235 */
236 void emitClasses() { 236 void emitClasses() {
237 for (ImpliedType impliedType in impliedTypes.values) { 237 for (ImpliedType impliedType in impliedTypes.values) {
238 TypeDecl type = impliedType.type; 238 TypeDecl type = impliedType.type;
239 if (type != null) { 239 String dartTypeName = capitalize(impliedType.camelName);
240 String dartTypeName = capitalize(impliedType.camelName); 240 if (type == null) {
241 if (type is TypeObject) { 241 emitEmptyObjectClass(dartTypeName, impliedType);
242 writeln(); 242 } else if (type is TypeObject || type == null) {
243 emitObjectClass(dartTypeName, type, impliedType); 243 writeln();
244 } else if (type is TypeEnum) { 244 emitObjectClass(dartTypeName, type, impliedType);
245 writeln(); 245 } else if (type is TypeEnum) {
246 emitEnumClass(dartTypeName, type, impliedType); 246 writeln();
247 } 247 emitEnumClass(dartTypeName, type, impliedType);
248 } 248 }
249 } 249 }
250 } 250 }
251 251
252 /** 252 /**
253 * Emit a class representing an data structure that doesn't exist in the
254 * protocol because it is empty (e.g. the "params" object for a request that
255 * doesn't have any parameters).
256 */
257 void emitEmptyObjectClass(String className, ImpliedType impliedType) {
258 docComment(toHtmlVisitor.collectHtml(() {
259 toHtmlVisitor.p(() {
260 toHtmlVisitor.write(impliedType.humanReadableName);
261 });
262 }));
263 writeln('class $className {');
264 indent(() {
265 if (emitToRequestMember(impliedType)) {
266 writeln();
267 }
268 if (emitToResponseMember(impliedType)) {
269 writeln();
270 }
271 if (emitToNotificationMember(impliedType)) {
272 writeln();
273 }
274 emitObjectEqualsMember(null, className);
275 writeln();
276 emitObjectHashCode(null, className);
277 });
278 writeln('}');
279 }
280
281 /**
253 * Emit the class to encapsulate an object type. 282 * Emit the class to encapsulate an object type.
254 */ 283 */
255 void emitObjectClass(String className, TypeObject type, 284 void emitObjectClass(String className, TypeObject type,
256 ImpliedType impliedType) { 285 ImpliedType impliedType) {
257 docComment(toHtmlVisitor.collectHtml(() { 286 docComment(toHtmlVisitor.collectHtml(() {
258 toHtmlVisitor.p(() { 287 toHtmlVisitor.p(() {
259 toHtmlVisitor.write(impliedType.humanReadableName); 288 toHtmlVisitor.write(impliedType.humanReadableName);
260 }); 289 });
261 if (impliedType.type != null) { 290 if (impliedType.type != null) {
262 toHtmlVisitor.showType(null, impliedType.type); 291 toHtmlVisitor.showType(null, impliedType.type);
263 } 292 }
264 })); 293 }));
265 writeln('class $className implements HasToJson {'); 294 writeln('class $className {');
266 indent(() { 295 indent(() {
267 if (emitSpecialStaticMembers(className)) { 296 if (emitSpecialStaticMembers(className)) {
268 writeln(); 297 writeln();
269 } 298 }
270 for (TypeObjectField field in type.fields) { 299 for (TypeObjectField field in type.fields) {
271 if (field.value != null) { 300 if (field.value != null) {
272 continue; 301 continue;
273 } 302 }
274 docComment(toHtmlVisitor.collectHtml(() { 303 docComment(toHtmlVisitor.collectHtml(() {
275 toHtmlVisitor.translateHtml(field.html); 304 toHtmlVisitor.translateHtml(field.html);
(...skipping 26 matching lines...) Expand all
302 writeln(); 331 writeln();
303 } 332 }
304 if (emitSpecialMethods(className)) { 333 if (emitSpecialMethods(className)) {
305 writeln(); 334 writeln();
306 } 335 }
307 writeln('@override'); 336 writeln('@override');
308 writeln('String toString() => JSON.encode(toJson());'); 337 writeln('String toString() => JSON.encode(toJson());');
309 writeln(); 338 writeln();
310 emitObjectEqualsMember(type, className); 339 emitObjectEqualsMember(type, className);
311 writeln(); 340 writeln();
312 emitObjectHashCode(type); 341 emitObjectHashCode(type, className);
313 }); 342 });
314 writeln('}'); 343 writeln('}');
315 } 344 }
316 345
317 /** 346 /**
318 * If the class named [className] requires special static members, emit them 347 * If the class named [className] requires special static members, emit them
319 * and return true. 348 * and return true.
320 */ 349 */
321 bool emitSpecialStaticMembers(String className) { 350 bool emitSpecialStaticMembers(String className) {
322 switch (className) { 351 switch (className) {
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 /** 690 /**
662 * Emit the toRequest() code for a class, if appropriate. Returns true if 691 * Emit the toRequest() code for a class, if appropriate. Returns true if
663 * code was emitted. 692 * code was emitted.
664 */ 693 */
665 bool emitToRequestMember(ImpliedType impliedType) { 694 bool emitToRequestMember(ImpliedType impliedType) {
666 if (impliedType.kind == 'requestParams') { 695 if (impliedType.kind == 'requestParams') {
667 writeln('Request toRequest(String id) {'); 696 writeln('Request toRequest(String id) {');
668 indent(() { 697 indent(() {
669 String methodString = 698 String methodString =
670 literalString((impliedType.apiNode as Request).longMethod); 699 literalString((impliedType.apiNode as Request).longMethod);
671 writeln('return new Request(id, $methodString, toJson());'); 700 String jsonPart = impliedType.type != null ? 'toJson()' : 'null';
701 writeln('return new Request(id, $methodString, $jsonPart);');
672 }); 702 });
673 writeln('}'); 703 writeln('}');
674 return true; 704 return true;
675 } 705 }
676 return false; 706 return false;
677 } 707 }
678 708
679 /** 709 /**
680 * Emit the toResponse() code for a class, if appropriate. Returns true if 710 * Emit the toResponse() code for a class, if appropriate. Returns true if
681 * code was emitted. 711 * code was emitted.
682 */ 712 */
683 bool emitToResponseMember(ImpliedType impliedType) { 713 bool emitToResponseMember(ImpliedType impliedType) {
684 if (impliedType.kind == 'requestResult') { 714 if (impliedType.kind == 'requestResult') {
685 writeln('Response toResponse(String id) {'); 715 writeln('Response toResponse(String id) {');
686 indent(() { 716 indent(() {
687 writeln('return new Response(id, result: toJson());'); 717 String jsonPart = impliedType.type != null ? 'toJson()' : 'null';
718 writeln('return new Response(id, result: $jsonPart);');
688 }); 719 });
689 writeln('}'); 720 writeln('}');
690 return true; 721 return true;
691 } 722 }
692 return false; 723 return false;
693 } 724 }
694 725
695 /** 726 /**
696 * Emit the toNotification() code for a class, if appropriate. Returns true 727 * Emit the toNotification() code for a class, if appropriate. Returns true
697 * if code was emitted. 728 * if code was emitted.
698 */ 729 */
699 bool emitToNotificationMember(ImpliedType impliedType) { 730 bool emitToNotificationMember(ImpliedType impliedType) {
700 if (impliedType.kind == 'notificationParams') { 731 if (impliedType.kind == 'notificationParams') {
701 writeln('Notification toNotification() {'); 732 writeln('Notification toNotification() {');
702 indent(() { 733 indent(() {
703 String eventString = 734 String eventString =
704 literalString((impliedType.apiNode as Notification).longEvent); 735 literalString((impliedType.apiNode as Notification).longEvent);
705 writeln('return new Notification($eventString, toJson());'); 736 String jsonPart = impliedType.type != null ? 'toJson()' : 'null';
737 writeln('return new Notification($eventString, $jsonPart);');
706 }); 738 });
707 writeln('}'); 739 writeln('}');
708 return true; 740 return true;
709 } 741 }
710 return false; 742 return false;
711 } 743 }
712 744
713 /** 745 /**
714 * Emit the operator== code for an object class. 746 * Emit the operator== code for an object class.
715 */ 747 */
716 void emitObjectEqualsMember(TypeObject type, String className) { 748 void emitObjectEqualsMember(TypeObject type, String className) {
717 writeln('@override'); 749 writeln('@override');
718 writeln('bool operator==(other) {'); 750 writeln('bool operator==(other) {');
719 indent(() { 751 indent(() {
720 writeln('if (other is $className) {'); 752 writeln('if (other is $className) {');
721 indent(() { 753 indent(() {
722 var comparisons = <String>[]; 754 var comparisons = <String>[];
723 for (TypeObjectField field in type.fields) { 755 if (type != null) {
724 if (field.value != null) { 756 for (TypeObjectField field in type.fields) {
725 continue; 757 if (field.value != null) {
758 continue;
759 }
760 comparisons.add(
761 compareEqualsCode(field.type, field.name, 'other.${field.name}') );
726 } 762 }
727 comparisons.add(
728 compareEqualsCode(field.type, field.name, 'other.${field.name}'));
729 } 763 }
730 if (comparisons.isEmpty) { 764 if (comparisons.isEmpty) {
731 writeln('return true;'); 765 writeln('return true;');
732 } else { 766 } else {
733 String concatenated = comparisons.join(' &&\n '); 767 String concatenated = comparisons.join(' &&\n ');
734 writeln('return $concatenated;'); 768 writeln('return $concatenated;');
735 } 769 }
736 }); 770 });
737 writeln('}'); 771 writeln('}');
738 writeln('return false;'); 772 writeln('return false;');
739 }); 773 });
740 writeln('}'); 774 writeln('}');
741 } 775 }
742 776
743 /** 777 /**
744 * Emit the hashCode getter for an object class. 778 * Emit the hashCode getter for an object class.
745 */ 779 */
746 void emitObjectHashCode(TypeObject type) { 780 void emitObjectHashCode(TypeObject type, String className) {
747 writeln('@override'); 781 writeln('@override');
748 writeln('int get hashCode {'); 782 writeln('int get hashCode {');
749 indent(() { 783 indent(() {
750 writeln('int hash = 0;'); 784 if (type == null) {
751 for (TypeObjectField field in type.fields) { 785 writeln('return ${className.hashCode};');
752 String valueToCombine; 786 } else {
753 if (field.value != null) { 787 writeln('int hash = 0;');
754 valueToCombine = field.value.hashCode.toString(); 788 for (TypeObjectField field in type.fields) {
755 } else { 789 String valueToCombine;
756 valueToCombine = '${field.name}.hashCode'; 790 if (field.value != null) {
791 valueToCombine = field.value.hashCode.toString();
792 } else {
793 valueToCombine = '${field.name}.hashCode';
794 }
795 writeln('hash = _JenkinsSmiHash.combine(hash, $valueToCombine);');
757 } 796 }
758 writeln('hash = _JenkinsSmiHash.combine(hash, $valueToCombine);'); 797 writeln('return _JenkinsSmiHash.finish(hash);');
759 } 798 }
760 writeln('return _JenkinsSmiHash.finish(hash);');
761 }); 799 });
762 writeln('}'); 800 writeln('}');
763 } 801 }
764 802
765 /** 803 /**
766 * Emit a class to encapsulate an enum. 804 * Emit a class to encapsulate an enum.
767 */ 805 */
768 void emitEnumClass(String className, TypeEnum type, ImpliedType impliedType) { 806 void emitEnumClass(String className, TypeEnum type, ImpliedType impliedType) {
769 docComment(toHtmlVisitor.collectHtml(() { 807 docComment(toHtmlVisitor.collectHtml(() {
770 toHtmlVisitor.p(() { 808 toHtmlVisitor.p(() {
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 // Constructor call to create the JsonDecoder object. 1168 // Constructor call to create the JsonDecoder object.
1131 String makeDecoder; 1169 String makeDecoder;
1132 // Name of the constructor to create. 1170 // Name of the constructor to create.
1133 String constructorName; 1171 String constructorName;
1134 // Extra arguments for the constructor. 1172 // Extra arguments for the constructor.
1135 List<String> extraArgs = <String>[]; 1173 List<String> extraArgs = <String>[];
1136 switch (impliedType.kind) { 1174 switch (impliedType.kind) {
1137 case 'requestParams': 1175 case 'requestParams':
1138 inputType = 'Request'; 1176 inputType = 'Request';
1139 inputName = 'request'; 1177 inputName = 'request';
1140 fieldName = 'params'; 1178 fieldName = '_params';
1141 makeDecoder = 'new RequestDecoder(request)'; 1179 makeDecoder = 'new RequestDecoder(request)';
1142 constructorName = 'fromRequest'; 1180 constructorName = 'fromRequest';
1143 break; 1181 break;
1144 case 'requestResult': 1182 case 'requestResult':
1145 inputType = 'Response'; 1183 inputType = 'Response';
1146 inputName = 'response'; 1184 inputName = 'response';
1147 fieldName = 'result'; 1185 fieldName = '_result';
1148 makeDecoder = 'new ResponseDecoder()'; 1186 makeDecoder = 'new ResponseDecoder()';
1149 constructorName = 'fromResponse'; 1187 constructorName = 'fromResponse';
1150 break; 1188 break;
1151 case 'notificationParams': 1189 case 'notificationParams':
1152 inputType = 'Notification'; 1190 inputType = 'Notification';
1153 inputName = 'notification'; 1191 inputName = 'notification';
1154 fieldName = 'params'; 1192 fieldName = '_params';
1155 makeDecoder = 'new ResponseDecoder()'; 1193 makeDecoder = 'new ResponseDecoder()';
1156 constructorName = 'fromNotification'; 1194 constructorName = 'fromNotification';
1157 break; 1195 break;
1158 case 'refactoringFeedback': 1196 case 'refactoringFeedback':
1159 inputType = 'EditGetRefactoringResult'; 1197 inputType = 'EditGetRefactoringResult';
1160 inputName = 'refactoringResult'; 1198 inputName = 'refactoringResult';
1161 fieldName = 'feedback'; 1199 fieldName = 'feedback';
1162 makeDecoder = 'new ResponseDecoder()'; 1200 makeDecoder = 'new ResponseDecoder()';
1163 constructorName = 'fromRefactoringResult'; 1201 constructorName = 'fromRefactoringResult';
1164 break; 1202 break;
1165 case 'refactoringOptions': 1203 case 'refactoringOptions':
1166 inputType = 'EditGetRefactoringParams'; 1204 inputType = 'EditGetRefactoringParams';
1167 inputName = 'refactoringParams'; 1205 inputName = 'refactoringParams';
1168 fieldName = 'options'; 1206 fieldName = 'options';
1169 makeDecoder = 'new RequestDecoder(request)'; 1207 makeDecoder = 'new RequestDecoder(request)';
1170 constructorName = 'fromRefactoringParams'; 1208 constructorName = 'fromRefactoringParams';
1171 extraArgs.add('Request request'); 1209 extraArgs.add('Request request');
1172 break; 1210 break;
1173 default: 1211 default:
1174 return false; 1212 return false;
1175 } 1213 }
1176 List<String> args = ['$inputType $inputName']; 1214 List<String> args = ['$inputType $inputName'];
1177 args.addAll(extraArgs); 1215 args.addAll(extraArgs);
1178 writeln('factory $className.$constructorName(${args.join(', ')}) {'); 1216 writeln('factory $className.$constructorName(${args.join(', ')}) {');
1179 indent(() { 1217 indent(() {
1180 String fieldNameString = literalString(fieldName); 1218 String fieldNameString =
1219 literalString(fieldName.replaceFirst(new RegExp('^_'), ''));
1181 writeln('return new $className.fromJson('); 1220 writeln('return new $className.fromJson(');
1182 writeln(' $makeDecoder, $fieldNameString, $inputName.$fieldName);'); 1221 writeln(' $makeDecoder, $fieldNameString, $inputName.$fieldName);');
1183 }); 1222 });
1184 writeln('}'); 1223 writeln('}');
1185 return true; 1224 return true;
1186 } 1225 }
1187 1226
1188 /** 1227 /**
1189 * Create a string literal that evaluates to [s]. 1228 * Create a string literal that evaluates to [s].
1190 */ 1229 */
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 CodegenProtocolVisitor visitor = new CodegenProtocolVisitor(readApi()); 1266 CodegenProtocolVisitor visitor = new CodegenProtocolVisitor(readApi());
1228 return visitor.collectCode(visitor.visitApi); 1267 return visitor.collectCode(visitor.visitApi);
1229 }); 1268 });
1230 1269
1231 /** 1270 /**
1232 * Translate spec_input.html into protocol_matchers.dart. 1271 * Translate spec_input.html into protocol_matchers.dart.
1233 */ 1272 */
1234 main() { 1273 main() {
1235 target.generate(); 1274 target.generate();
1236 } 1275 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/test/socket_server_test.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698