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

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: 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 * Translate the input [map], applying [keyCallback] to all its keys, and
15 * [valueCallback] to all its values.
16 */
17 _mapMap(Map map, {dynamic keyCallback(key), dynamic valueCallback(value)}) {
18 Map result = {};
19 map.forEach((key, value) {
20 if (keyCallback != null) {
21 key = keyCallback(key);
22 }
23 if (valueCallback != null) {
24 value = valueCallback(value);
25 }
26 result[key] = value;
27 });
28 return result;
29 }
30
31 /**
32 * Jenkins hash function, optimized for small integers. Borrowed from
33 * sdk/lib/math/jenkins_smi_hash.dart.
34 *
35 * TODO(paulberry): Move to somewhere that can be shared with other code.
36 */
37 class _JenkinsSmiHash {
38 static int combine(int hash, int value) {
39 hash = 0x1fffffff & (hash + value);
40 hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
41 return hash ^ (hash >> 6);
42 }
43
44 static int finish(int hash) {
45 hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
46 hash = hash ^ (hash >> 11);
47 return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
48 }
49
50 static int hash2(a, b) => finish(combine(combine(0, a), b));
51
52 static int hash4(a, b, c, d) =>
53 finish(combine(combine(combine(combine(0, a), b), c), d));
54 }
55
56
57 /**
58 * Type of callbacks used to decode parts of JSON objects. [jsonPath] is a
59 * string describing the part of the JSON object being decoded, and [value] is
60 * the part to decode.
61 */
62 typedef Object JsonDecoderCallback(String jsonPath, Object value);
63
64 /**
65 * Base class for decoding JSON objects. The derived class must implement
66 * error reporting logic.
67 */
68 abstract class JsonDecoderBase {
69 /**
70 * Create an exception to throw if the JSON object at [jsonPath] is missing
71 * the key [key].
72 */
73 dynamic missingKey(String jsonPath, String key);
74
75 /**
76 * Create an exception to throw if the JSON object at [jsonPath] fails to
77 * match the API definition of [expected].
78 */
79 dynamic mismatch(String jsonPath, String expected);
80
81 /**
82 * Decode a JSON object that is expected to be a Map. [keyDecoder] is used
83 * to decode the keys, and [valueDecoder] is used to decode the values.
84 */
85 Map _decodeMap(String jsonPath, Object json, {JsonDecoderCallback keyDecoder,
86 JsonDecoderCallback valueDecoder}) {
87 if (json == null) {
88 return {};
89 } else if (json is Map) {
90 Map result = {};
91 json.forEach((String key, value) {
92 Object decodedKey;
93 if (keyDecoder != null) {
94 decodedKey = keyDecoder('$jsonPath.key', key);
95 } else {
96 decodedKey = key;
97 }
98 if (valueDecoder != null) {
99 value = valueDecoder('$jsonPath[${JSON.encode(key)}]', value);
100 }
101 result[decodedKey] = value;
102 });
103 return result;
104 } else {
105 throw mismatch(jsonPath, 'Map');
106 }
107 }
108
109 /**
110 * Decode a JSON object that is expected to be a List. [decoder] is used to
111 * decode the items in the list.
112 */
113 List _decodeList(String jsonPath, Object json, [JsonDecoderCallback decoder]) {
114 if (json == null) {
115 return [];
116 } else if (json is List) {
117 List result = [];
118 for (int i = 0; i < json.length; i++) {
119 result.add(decoder('$jsonPath[$i]', json[i]));
120 }
121 return result;
122 } else {
123 throw mismatch(jsonPath, 'List');
124 }
125 }
126
127 /**
128 * Decode a JSON object that is expected to be a string.
129 */
130 String _decodeString(String jsonPath, Object json) {
131 if (json is String) {
132 return json;
133 } else {
134 throw mismatch(jsonPath, 'String');
135 }
136 }
137
138 /**
139 * Decode a JSON object that is expected to be a boolean. The strings "true"
140 * and "false" are also accepted.
141 */
142 bool _decodeBool(String jsonPath, Object json) {
danrubel 2014/08/17 17:10:21 Do you want to sort the class memebers via cmd-1 -
Paul Berry 2014/08/18 21:58:03 Done.
143 if (json is bool) {
144 return json;
145 } else if (json == 'true') {
146 return true;
147 } else if (json == 'false') {
148 return false;
149 }
150 throw mismatch(jsonPath, 'bool');
151 }
152
153 /**
154 * Decode a JSON object that is expected to be an integer. A string
155 * representation of an integer is also accepted.
156 */
157 int _decodeInt(String jsonPath, Object json) {
158 if (json is int) {
159 return json;
160 } else if (json is String) {
161 return int.parse(json, onError: (String value) {
162 throw mismatch(jsonPath, 'int');
163 });
164 }
165 throw mismatch(jsonPath, 'int');
166 }
167
168 /**
169 * Decode a JSON object that is expected to be one of several choices,
170 * where the choices are disambiguated by the contents of the field [field].
171 * [decoders] is a map from each possible string in the field to the decoder
172 * that should be used to decode the JSON object.
173 */
174 Object _decodeUnion(String jsonPath, Map json, String field,
175 Map<String, JsonDecoderCallback> decoders) {
176 if (json is Map) {
177 if (!json.containsKey(field)) {
178 throw missingKey(jsonPath, field);
179 }
180 var disambiguatorPath = '$jsonPath[${JSON.encode(field)}]';
181 String disambiguator = _decodeString(disambiguatorPath,
182 json[field]);
183 if (!decoders.containsKey(disambiguator)) {
184 throw mismatch(disambiguatorPath, 'One of: ${decoders.keys.toList()}');
185 }
186 return decoders[disambiguator](jsonPath, json);
187 } else {
188 throw mismatch(jsonPath, 'Map');
189 }
190 }
191 }
192
193 /**
194 * JsonDecoder for decoding requests. Errors are reporting by throwing a
195 * [RequestFailure].
196 */
197 class RequestDecoder extends JsonDecoder {
198 /**
199 * The request being deserialized.
200 */
201 final Request _request;
202
203 RequestDecoder(this._request);
204
205 @override
206 dynamic mismatch(String jsonPath, String expected) {
207 return new RequestFailure(new Response.invalidParameter(_request, jsonPath,
208 'be $expected'));
209 }
210
211 @override
212 dynamic missingKey(String jsonPath, String key) {
213 return new RequestFailure(new Response.invalidParameter(_request, jsonPath,
214 'contain key ${JSON.encode(key)}'));
215 }
216 }
217
218 /**
219 * JsonDecoder for decoding responses from the server. This is intended to be
220 * used only for testing. Errors are reported using bare [Exception] objects.
221 */
222 class ResponseDecoder extends JsonDecoder {
223 @override
224 dynamic mismatch(String jsonPath, String expected) {
225 return new Exception('Expected $expected at $jsonPath');
226 }
227
228 @override
229 dynamic missingKey(String jsonPath, String key) {
230 return new Exception('Missing key $key at $jsonPath');
231 }
232 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698