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

Side by Side Diff: pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart

Issue 2664213003: Add the generator and the generated files (Closed)
Patch Set: add missed files Created 3 years, 10 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
(Empty)
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
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.
4
5 /**
6 * Code generation for the file "integration_test_methods.dart".
7 */
8 import 'dart:convert';
9
10 import 'package:analyzer/src/codegen/tools.dart';
11
12 import 'api.dart';
13 import 'codegen_dart.dart';
14 import 'from_html.dart';
15 import 'to_html.dart';
16
17 final GeneratedFile target = new GeneratedFile(
18 'test/integration/support/integration_test_methods.dart', (String pkgPath) {
19 CodegenInttestMethodsVisitor visitor =
20 new CodegenInttestMethodsVisitor(readApi(pkgPath));
21 return visitor.collectCode(visitor.visitApi);
22 });
23
24 /**
25 * Visitor that generates the code for integration_test_methods.dart
26 */
27 class CodegenInttestMethodsVisitor extends DartCodegenVisitor
28 with CodeGenerator {
29 /**
30 * Visitor used to produce doc comments.
31 */
32 final ToHtmlVisitor toHtmlVisitor;
33
34 /**
35 * Code snippets concatenated to initialize all of the class fields.
36 */
37 List<String> fieldInitializationCode = <String>[];
38
39 /**
40 * Code snippets concatenated to produce the contents of the switch statement
41 * for dispatching notifications.
42 */
43 List<String> notificationSwitchContents = <String>[];
44
45 CodegenInttestMethodsVisitor(Api api)
46 : toHtmlVisitor = new ToHtmlVisitor(api),
47 super(api) {
48 codeGeneratorSettings.commentLineLength = 79;
49 codeGeneratorSettings.languageName = 'dart';
50 }
51
52 /**
53 * Generate a function argument for the given parameter field.
54 */
55 String formatArgument(TypeObjectField field) =>
56 '${dartType(field.type)} ${field.name}';
57
58 /**
59 * Figure out the appropriate Dart type for data having the given API
60 * protocol [type].
61 */
62 String jsonType(TypeDecl type) {
63 type = resolveTypeReferenceChain(type);
64 if (type is TypeEnum) {
65 return 'String';
66 } else if (type is TypeList) {
67 return 'List<${jsonType(type.itemType)}>';
68 } else if (type is TypeMap) {
69 return 'Map<String, ${jsonType(type.valueType)}>';
70 } else if (type is TypeObject) {
71 return 'Map<String, dynamic>';
72 } else if (type is TypeReference) {
73 switch (type.typeName) {
74 case 'String':
75 case 'int':
76 case 'bool':
77 // These types correspond exactly to Dart types
78 return type.typeName;
79 case 'object':
80 return 'Map<String, dynamic>';
81 default:
82 throw new Exception(type.typeName);
83 }
84 } else if (type is TypeUnion) {
85 return 'Object';
86 } else {
87 throw new Exception('Unexpected kind of TypeDecl');
88 }
89 }
90
91 @override
92 visitApi() {
93 outputHeader(year: '2017');
94 writeln();
95 writeln('/**');
96 writeln(' * Convenience methods for running integration tests');
97 writeln(' */');
98 writeln("import 'dart:async';");
99 writeln();
100 writeln(
101 "import 'package:analyzer_plugin/protocol/generated_protocol.dart';");
102 writeln(
103 "import 'package:analyzer_plugin/src/protocol/protocol_internal.dart';") ;
104 writeln("import 'package:test/test.dart';");
105 writeln();
106 writeln("import 'integration_tests.dart';");
107 writeln("import 'protocol_matchers.dart';");
108 writeln();
109 writeln('/**');
110 writeln(' * Convenience methods for running integration tests');
111 writeln(' */');
112 writeln('abstract class IntegrationTestMixin {');
113 indent(() {
114 writeln('Server get server;');
115 super.visitApi();
116 writeln();
117 docComment(toHtmlVisitor.collectHtml(() {
118 toHtmlVisitor.writeln('Initialize the fields in InttestMixin, and');
119 toHtmlVisitor.writeln('ensure that notifications will be handled.');
120 }));
121 writeln('void initializeInttestMixin() {');
122 indent(() {
123 write(fieldInitializationCode.join());
124 });
125 writeln('}');
126 writeln();
127 docComment(toHtmlVisitor.collectHtml(() {
128 toHtmlVisitor.writeln('Dispatch the notification named [event], and');
129 toHtmlVisitor.writeln('containing parameters [params], to the');
130 toHtmlVisitor.writeln('appropriate stream.');
131 }));
132 writeln('void dispatchNotification(String event, params) {');
133 indent(() {
134 writeln('ResponseDecoder decoder = new ResponseDecoder(null);');
135 writeln('switch (event) {');
136 indent(() {
137 write(notificationSwitchContents.join());
138 writeln('default:');
139 indent(() {
140 writeln("fail('Unexpected notification: \$event');");
141 writeln('break;');
142 });
143 });
144 writeln('}');
145 });
146 writeln('}');
147 });
148 writeln('}');
149 }
150
151 @override
152 visitNotification(Notification notification) {
153 String streamName =
154 camelJoin(['on', notification.domainName, notification.event]);
155 String className = camelJoin(
156 [notification.domainName, notification.event, 'params'],
157 doCapitalize: true);
158 writeln();
159 docComment(toHtmlVisitor.collectHtml(() {
160 toHtmlVisitor.translateHtml(notification.html);
161 toHtmlVisitor.describePayload(notification.params, 'Parameters');
162 }));
163 writeln('Stream<$className> $streamName;');
164 writeln();
165 docComment(toHtmlVisitor.collectHtml(() {
166 toHtmlVisitor.write('Stream controller for [$streamName].');
167 }));
168 writeln('StreamController<$className> _$streamName;');
169 fieldInitializationCode.add(collectCode(() {
170 writeln('_$streamName = new StreamController<$className>(sync: true);');
171 writeln('$streamName = _$streamName.stream.asBroadcastStream();');
172 }));
173 notificationSwitchContents.add(collectCode(() {
174 writeln('case ${JSON.encode(notification.longEvent)}:');
175 indent(() {
176 String paramsValidator = camelJoin(
177 ['is', notification.domainName, notification.event, 'params']);
178 writeln('outOfTestExpect(params, $paramsValidator);');
179 String constructorCall;
180 if (notification.params == null) {
181 constructorCall = 'new $className()';
182 } else {
183 constructorCall =
184 "new $className.fromJson(decoder, 'params', params)";
185 }
186 writeln('_$streamName.add($constructorCall);');
187 writeln('break;');
188 });
189 }));
190 }
191
192 @override
193 visitRequest(Request request) {
194 String methodName = camelJoin(['send', request.domainName, request.method]);
195 List<String> args = <String>[];
196 List<String> optionalArgs = <String>[];
197 if (request.params != null) {
198 for (TypeObjectField field in request.params.fields) {
199 if (field.optional) {
200 optionalArgs.add(formatArgument(field));
201 } else {
202 args.add(formatArgument(field));
203 }
204 }
205 }
206 if (optionalArgs.isNotEmpty) {
207 args.add('{${optionalArgs.join(', ')}}');
208 }
209 writeln();
210 docComment(toHtmlVisitor.collectHtml(() {
211 toHtmlVisitor.translateHtml(request.html);
212 toHtmlVisitor.describePayload(request.params, 'Parameters');
213 toHtmlVisitor.describePayload(request.result, 'Returns');
214 }));
215 String resultClass;
216 String futureClass;
217 if (request.result == null) {
218 futureClass = 'Future';
219 } else {
220 resultClass = camelJoin([request.domainName, request.method, 'result'],
221 doCapitalize: true);
222 futureClass = 'Future<$resultClass>';
223 }
224 writeln('$futureClass $methodName(${args.join(', ')}) async {');
225 indent(() {
226 String requestClass = camelJoin(
227 [request.domainName, request.method, 'params'],
228 doCapitalize: true);
229 String paramsVar = 'null';
230 if (request.params != null) {
231 paramsVar = 'params';
232 List<String> args = <String>[];
233 List<String> optionalArgs = <String>[];
234 for (TypeObjectField field in request.params.fields) {
235 if (field.optional) {
236 optionalArgs.add('${field.name}: ${field.name}');
237 } else {
238 args.add(field.name);
239 }
240 }
241 args.addAll(optionalArgs);
242 writeln('var params = new $requestClass(${args.join(', ')}).toJson();');
243 }
244 String methodJson = JSON.encode(request.longMethod);
245 writeln('var result = await server.send($methodJson, $paramsVar);');
246 if (request.result != null) {
247 String kind = 'null';
248 if (requestClass == 'EditGetRefactoringParams') {
249 kind = 'kind';
250 }
251 writeln('ResponseDecoder decoder = new ResponseDecoder($kind);');
252 writeln("return new $resultClass.fromJson(decoder, 'result', result);");
253 } else {
254 writeln('outOfTestExpect(result, isNull);');
255 writeln('return null;');
256 }
257 });
258 writeln('}');
259 }
260 }
OLDNEW
« no previous file with comments | « pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart ('k') | pkg/analyzer_plugin/tool/spec/codegen_matchers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698