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

Side by Side Diff: pkg/analysis_server/lib/src/protocol2.dart

Issue 479043002: Code generate Dart classes representing the analysis server API. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Remove accidental comment change 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library protocol2;
6
7 import 'dart:convert';
8
9 import 'protocol.dart';
10
11 part 'generated_protocol.dart';
12
13 /**
14 * Compare the lists [listA] and [listB], using [itemEqual] to compare
15 * list elements.
16 */
17 bool _listEqual(List listA, List listB, bool itemEqual(a, b)) {
18 if (listA.length != listB.length) {
19 return false;
20 }
21 for (int i = 0; i < listA.length; i++) {
22 if (!itemEqual(listA[i], listB[i])) {
23 return false;
24 }
25 }
26 return true;
27 }
28
29 /**
30 * Compare the maps [mapA] and [mapB], using [valueEqual] to compare map
31 * values.
32 */
33 bool _mapEqual(Map mapA, Map mapB, bool valueEqual(a, b)) {
34 if (mapA.length != mapB.length) {
35 return false;
36 }
37 for (var key in mapA.keys) {
38 if (!mapB.containsKey(key)) {
39 return false;
40 }
41 if (!valueEqual(mapA[key], mapB[key])) {
42 return false;
43 }
44 }
45 return true;
46 }
47
48 /**
49 * Translate the input [map], applying [keyCallback] to all its keys, and
50 * [valueCallback] to all its values.
51 */
52 _mapMap(Map map, {dynamic keyCallback(key), dynamic valueCallback(value)}) {
53 Map result = {};
54 map.forEach((key, value) {
55 if (keyCallback != null) {
56 key = keyCallback(key);
57 }
58 if (valueCallback != null) {
59 value = valueCallback(value);
60 }
61 result[key] = value;
62 });
63 return result;
64 }
65
66 /**
67 * Type of callbacks used to decode parts of JSON objects. [jsonPath] is a
68 * string describing the part of the JSON object being decoded, and [value] is
69 * the part to decode.
70 */
71 typedef Object JsonDecoderCallback(String jsonPath, Object value);
72
73
74 /**
75 * Base class for decoding JSON objects. The derived class must implement
76 * error reporting logic.
77 */
78 abstract class JsonDecoder {
79 /**
80 * Create an exception to throw if the JSON object at [jsonPath] fails to
81 * match the API definition of [expected].
82 */
83 dynamic mismatch(String jsonPath, String expected);
84
85 /**
86 * Create an exception to throw if the JSON object at [jsonPath] is missing
87 * the key [key].
88 */
89 dynamic missingKey(String jsonPath, String key);
90
91 /**
92 * Decode a JSON object that is expected to be a boolean. The strings "true"
93 * and "false" are also accepted.
94 */
95 bool _decodeBool(String jsonPath, Object json) {
96 if (json is bool) {
97 return json;
98 } else if (json == 'true') {
99 return true;
100 } else if (json == 'false') {
101 return false;
102 }
103 throw mismatch(jsonPath, 'bool');
104 }
105
106 /**
107 * Decode a JSON object that is expected to be an integer. A string
108 * representation of an integer is also accepted.
109 */
110 int _decodeInt(String jsonPath, Object json) {
111 if (json is int) {
112 return json;
113 } else if (json is String) {
114 return int.parse(json, onError: (String value) {
115 throw mismatch(jsonPath, 'int');
116 });
117 }
118 throw mismatch(jsonPath, 'int');
119 }
120
121 /**
122 * Decode a JSON object that is expected to be a List. [decoder] is used to
123 * decode the items in the list.
124 */
125 List _decodeList(String jsonPath, Object json, [JsonDecoderCallback decoder]) {
126 if (json == null) {
127 return [];
128 } else if (json is List) {
129 List result = [];
130 for (int i = 0; i < json.length; i++) {
131 result.add(decoder('$jsonPath[$i]', json[i]));
132 }
133 return result;
134 } else {
135 throw mismatch(jsonPath, 'List');
136 }
137 }
138
139 /**
140 * Decode a JSON object that is expected to be a Map. [keyDecoder] is used
141 * to decode the keys, and [valueDecoder] is used to decode the values.
142 */
143 Map _decodeMap(String jsonPath, Object json, {JsonDecoderCallback keyDecoder,
144 JsonDecoderCallback valueDecoder}) {
145 if (json == null) {
146 return {};
147 } else if (json is Map) {
148 Map result = {};
149 json.forEach((String key, value) {
150 Object decodedKey;
151 if (keyDecoder != null) {
152 decodedKey = keyDecoder('$jsonPath.key', key);
153 } else {
154 decodedKey = key;
155 }
156 if (valueDecoder != null) {
157 value = valueDecoder('$jsonPath[${JSON.encode(key)}]', value);
158 }
159 result[decodedKey] = value;
160 });
161 return result;
162 } else {
163 throw mismatch(jsonPath, 'Map');
164 }
165 }
166
167 /**
168 * Decode a JSON object that is expected to be a string.
169 */
170 String _decodeString(String jsonPath, Object json) {
171 if (json is String) {
172 return json;
173 } else {
174 throw mismatch(jsonPath, 'String');
175 }
176 }
177
178 /**
179 * Decode a JSON object that is expected to be one of several choices,
180 * where the choices are disambiguated by the contents of the field [field].
181 * [decoders] is a map from each possible string in the field to the decoder
182 * that should be used to decode the JSON object.
183 */
184 Object _decodeUnion(String jsonPath, Map json, String field,
185 Map<String, JsonDecoderCallback> decoders) {
186 if (json is Map) {
187 if (!json.containsKey(field)) {
188 throw missingKey(jsonPath, field);
189 }
190 var disambiguatorPath = '$jsonPath[${JSON.encode(field)}]';
191 String disambiguator = _decodeString(disambiguatorPath,
192 json[field]);
193 if (!decoders.containsKey(disambiguator)) {
194 throw mismatch(disambiguatorPath, 'One of: ${decoders.keys.toList()}');
195 }
196 return decoders[disambiguator](jsonPath, json);
197 } else {
198 throw mismatch(jsonPath, 'Map');
199 }
200 }
201 }
202
203 /**
204 * JsonDecoder for decoding requests. Errors are reporting by throwing a
205 * [RequestFailure].
206 */
207 class RequestDecoder extends JsonDecoder {
208 /**
209 * The request being deserialized.
210 */
211 final Request _request;
212
213 RequestDecoder(this._request);
214
215 @override
216 dynamic mismatch(String jsonPath, String expected) {
217 return new RequestFailure(new Response.invalidParameter(_request, jsonPath,
218 'be $expected'));
219 }
220
221 @override
222 dynamic missingKey(String jsonPath, String key) {
223 return new RequestFailure(new Response.invalidParameter(_request, jsonPath,
224 'contain key ${JSON.encode(key)}'));
225 }
226 }
227
228 /**
229 * JsonDecoder for decoding responses from the server. This is intended to be
230 * used only for testing. Errors are reported using bare [Exception] objects.
231 */
232 class ResponseDecoder extends JsonDecoder {
233 @override
234 dynamic mismatch(String jsonPath, String expected) {
235 return new Exception('Expected $expected at $jsonPath');
236 }
237
238 @override
239 dynamic missingKey(String jsonPath, String key) {
240 return new Exception('Missing key $key at $jsonPath');
241 }
242 }
243
244 /**
245 * Jenkins hash function, optimized for small integers. Borrowed from
246 * sdk/lib/math/jenkins_smi_hash.dart.
247 *
248 * TODO(paulberry): Move to somewhere that can be shared with other code.
249 */
250 class _JenkinsSmiHash {
251 static int combine(int hash, int value) {
252 hash = 0x1fffffff & (hash + value);
253 hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
254 return hash ^ (hash >> 6);
255 }
256
257 static int finish(int hash) {
258 hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
259 hash = hash ^ (hash >> 11);
260 return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
261 }
262
263 static int hash2(a, b) => finish(combine(combine(0, a), b));
264
265 static int hash4(a, b, c, d) =>
266 finish(combine(combine(combine(combine(0, a), b), c), d));
267 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/lib/src/generated_protocol.dart ('k') | pkg/analysis_server/test/test_all.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698