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

Side by Side Diff: pkg/analyzer_plugin/tool/spec/codegen_matchers.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 "matchers.dart".
7 */
8 import 'dart:convert';
9
10 import 'package:analyzer/src/codegen/tools.dart';
11
12 import 'api.dart';
13 import 'from_html.dart';
14 import 'implied_types.dart';
15 import 'to_html.dart';
16
17 final GeneratedFile target = new GeneratedFile(
18 'test/integration/support/protocol_matchers.dart', (String pkgPath) {
19 CodegenMatchersVisitor visitor = new CodegenMatchersVisitor(readApi(pkgPath));
20 return visitor.collectCode(visitor.visitApi);
21 });
22
23 class CodegenMatchersVisitor extends HierarchicalApiVisitor with CodeGenerator {
24 /**
25 * Visitor used to produce doc comments.
26 */
27 final ToHtmlVisitor toHtmlVisitor;
28
29 /**
30 * Short human-readable string describing the context of the matcher being
31 * created.
32 */
33 String context;
34
35 CodegenMatchersVisitor(Api api)
36 : toHtmlVisitor = new ToHtmlVisitor(api),
37 super(api) {
38 codeGeneratorSettings.commentLineLength = 79;
39 codeGeneratorSettings.languageName = 'dart';
40 }
41
42 /**
43 * Create a matcher for the part of the API called [name], optionally
44 * clarified by [nameSuffix]. The matcher should verify that its input
45 * matches the given [type].
46 */
47 void makeMatcher(ImpliedType impliedType) {
48 context = impliedType.humanReadableName;
49 docComment(toHtmlVisitor.collectHtml(() {
50 toHtmlVisitor.p(() {
51 toHtmlVisitor.write(context);
52 });
53 if (impliedType.type != null) {
54 toHtmlVisitor.showType(null, impliedType.type);
55 }
56 }));
57 write('final Matcher ${camelJoin(['is', impliedType.camelName])} = ');
58 if (impliedType.type == null) {
59 write('isNull');
60 } else {
61 visitTypeDecl(impliedType.type);
62 }
63 writeln(';');
64 writeln();
65 }
66
67 /**
68 * Generate a map describing the given set of fields, for use as the
69 * 'requiredFields' or 'optionalFields' argument to the [MatchesJsonObject]
70 * constructor.
71 */
72 void outputObjectFields(Iterable<TypeObjectField> fields) {
73 if (fields.isEmpty) {
74 write('null');
75 return;
76 }
77 writeln('{');
78 indent(() {
79 bool commaNeeded = false;
80 for (TypeObjectField field in fields) {
81 if (commaNeeded) {
82 writeln(',');
83 }
84 write('${JSON.encode(field.name)}: ');
85 if (field.value != null) {
86 write('equals(${JSON.encode(field.value)})');
87 } else {
88 visitTypeDecl(field.type);
89 }
90 commaNeeded = true;
91 }
92 writeln();
93 });
94 write('}');
95 }
96
97 @override
98 visitApi() {
99 outputHeader(year: '2017');
100 writeln();
101 writeln('/**');
102 writeln(' * Matchers for data types defined in the analysis server API');
103 writeln(' */');
104 writeln("import 'package:test/test.dart';");
105 writeln();
106 writeln("import 'integration_tests.dart';");
107 writeln();
108 for (ImpliedType impliedType in computeImpliedTypes(api).values) {
109 makeMatcher(impliedType);
110 }
111 }
112
113 @override
114 visitTypeEnum(TypeEnum typeEnum) {
115 writeln('new MatchesEnum(${JSON.encode(context)}, [');
116 indent(() {
117 bool commaNeeded = false;
118 for (TypeEnumValue value in typeEnum.values) {
119 if (commaNeeded) {
120 writeln(',');
121 }
122 write('${JSON.encode(value.value)}');
123 commaNeeded = true;
124 }
125 writeln();
126 });
127 write('])');
128 }
129
130 @override
131 visitTypeList(TypeList typeList) {
132 write('isListOf(');
133 visitTypeDecl(typeList.itemType);
134 write(')');
135 }
136
137 @override
138 visitTypeMap(TypeMap typeMap) {
139 write('isMapOf(');
140 visitTypeDecl(typeMap.keyType);
141 write(', ');
142 visitTypeDecl(typeMap.valueType);
143 write(')');
144 }
145
146 @override
147 void visitTypeObject(TypeObject typeObject) {
148 writeln('new LazyMatcher(() => new MatchesJsonObject(');
149 indent(() {
150 write('${JSON.encode(context)}, ');
151 Iterable<TypeObjectField> requiredFields =
152 typeObject.fields.where((TypeObjectField field) => !field.optional);
153 outputObjectFields(requiredFields);
154 List<TypeObjectField> optionalFields = typeObject.fields
155 .where((TypeObjectField field) => field.optional)
156 .toList();
157 if (optionalFields.isNotEmpty) {
158 write(', optionalFields: ');
159 outputObjectFields(optionalFields);
160 }
161 });
162 write('))');
163 }
164
165 @override
166 void visitTypeReference(TypeReference typeReference) {
167 String typeName = typeReference.typeName;
168 if (typeName == 'long') {
169 typeName = 'int';
170 }
171 write(camelJoin(['is', typeName]));
172 }
173
174 @override
175 void visitTypeUnion(TypeUnion typeUnion) {
176 bool commaNeeded = false;
177 write('isOneOf([');
178 for (TypeDecl choice in typeUnion.choices) {
179 if (commaNeeded) {
180 write(', ');
181 }
182 visitTypeDecl(choice);
183 commaNeeded = true;
184 }
185 write('])');
186 }
187 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698