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

Side by Side Diff: mojo/public/tools/bindings/generators/mojom_js_generator.py

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 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 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """Generates JavaScript source files from a mojom.Module."""
6
7 import mojom.generate.generator as generator
8 import mojom.generate.module as mojom
9 import mojom.generate.pack as pack
10 from mojom.generate.template_expander import UseJinja
11
12 _kind_to_javascript_default_value = {
13 mojom.BOOL: "false",
14 mojom.INT8: "0",
15 mojom.UINT8: "0",
16 mojom.INT16: "0",
17 mojom.UINT16: "0",
18 mojom.INT32: "0",
19 mojom.UINT32: "0",
20 mojom.FLOAT: "0",
21 mojom.HANDLE: "null",
22 mojom.DCPIPE: "null",
23 mojom.DPPIPE: "null",
24 mojom.MSGPIPE: "null",
25 mojom.SHAREDBUFFER: "null",
26 mojom.NULLABLE_HANDLE: "null",
27 mojom.NULLABLE_DCPIPE: "null",
28 mojom.NULLABLE_DPPIPE: "null",
29 mojom.NULLABLE_MSGPIPE: "null",
30 mojom.NULLABLE_SHAREDBUFFER: "null",
31 mojom.INT64: "0",
32 mojom.UINT64: "0",
33 mojom.DOUBLE: "0",
34 mojom.STRING: "null",
35 mojom.NULLABLE_STRING: "null"
36 }
37
38
39 def JavaScriptType(kind):
40 if kind.imported_from:
41 return kind.imported_from["unique_name"] + "." + kind.name
42 return kind.name
43
44
45 def JavaScriptDefaultValue(field):
46 if field.default:
47 if mojom.IsStructKind(field.kind):
48 assert field.default == "default"
49 return "new %s()" % JavaScriptType(field.kind)
50 return ExpressionToText(field.default)
51 if field.kind in mojom.PRIMITIVES:
52 return _kind_to_javascript_default_value[field.kind]
53 if mojom.IsStructKind(field.kind):
54 return "null"
55 if mojom.IsArrayKind(field.kind):
56 return "null"
57 if mojom.IsMapKind(field.kind):
58 return "null"
59 if mojom.IsInterfaceKind(field.kind) or \
60 mojom.IsInterfaceRequestKind(field.kind):
61 return _kind_to_javascript_default_value[mojom.MSGPIPE]
62 if mojom.IsEnumKind(field.kind):
63 return "0"
64
65
66 def JavaScriptPayloadSize(packed):
67 packed_fields = packed.packed_fields
68 if not packed_fields:
69 return 0
70 last_field = packed_fields[-1]
71 offset = last_field.offset + last_field.size
72 pad = pack.GetPad(offset, 8)
73 return offset + pad
74
75
76 _kind_to_codec_type = {
77 mojom.BOOL: "codec.Uint8",
78 mojom.INT8: "codec.Int8",
79 mojom.UINT8: "codec.Uint8",
80 mojom.INT16: "codec.Int16",
81 mojom.UINT16: "codec.Uint16",
82 mojom.INT32: "codec.Int32",
83 mojom.UINT32: "codec.Uint32",
84 mojom.FLOAT: "codec.Float",
85 mojom.HANDLE: "codec.Handle",
86 mojom.DCPIPE: "codec.Handle",
87 mojom.DPPIPE: "codec.Handle",
88 mojom.MSGPIPE: "codec.Handle",
89 mojom.SHAREDBUFFER: "codec.Handle",
90 mojom.NULLABLE_HANDLE: "codec.NullableHandle",
91 mojom.NULLABLE_DCPIPE: "codec.NullableHandle",
92 mojom.NULLABLE_DPPIPE: "codec.NullableHandle",
93 mojom.NULLABLE_MSGPIPE: "codec.NullableHandle",
94 mojom.NULLABLE_SHAREDBUFFER: "codec.NullableHandle",
95 mojom.INT64: "codec.Int64",
96 mojom.UINT64: "codec.Uint64",
97 mojom.DOUBLE: "codec.Double",
98 mojom.STRING: "codec.String",
99 mojom.NULLABLE_STRING: "codec.NullableString",
100 }
101
102
103 def CodecType(kind):
104 if kind in mojom.PRIMITIVES:
105 return _kind_to_codec_type[kind]
106 if mojom.IsStructKind(kind):
107 pointer_type = "NullablePointerTo" if mojom.IsNullableKind(kind) \
108 else "PointerTo"
109 return "new codec.%s(%s)" % (pointer_type, JavaScriptType(kind))
110 if mojom.IsArrayKind(kind):
111 array_type = "NullableArrayOf" if mojom.IsNullableKind(kind) else "ArrayOf"
112 array_length = "" if kind.length is None else ", %d" % kind.length
113 element_type = ElementCodecType(kind.kind)
114 return "new codec.%s(%s%s)" % (array_type, element_type, array_length)
115 if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind):
116 return CodecType(mojom.MSGPIPE)
117 if mojom.IsEnumKind(kind):
118 return _kind_to_codec_type[mojom.INT32]
119 if mojom.IsMapKind(kind):
120 map_type = "NullableMapOf" if mojom.IsNullableKind(kind) else "MapOf"
121 key_type = ElementCodecType(kind.key_kind)
122 value_type = ElementCodecType(kind.value_kind)
123 return "new codec.%s(%s, %s)" % (map_type, key_type, value_type)
124 return kind
125
126 def ElementCodecType(kind):
127 return "codec.PackedBool" if mojom.IsBoolKind(kind) else CodecType(kind)
128
129 def JavaScriptDecodeSnippet(kind):
130 if kind in mojom.PRIMITIVES:
131 return "decodeStruct(%s)" % CodecType(kind)
132 if mojom.IsStructKind(kind):
133 return "decodeStructPointer(%s)" % JavaScriptType(kind)
134 if mojom.IsMapKind(kind):
135 return "decodeMapPointer(%s, %s)" % \
136 (ElementCodecType(kind.key_kind), ElementCodecType(kind.value_kind))
137 if mojom.IsArrayKind(kind) and mojom.IsBoolKind(kind.kind):
138 return "decodeArrayPointer(codec.PackedBool)"
139 if mojom.IsArrayKind(kind):
140 return "decodeArrayPointer(%s)" % CodecType(kind.kind)
141 if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind):
142 return JavaScriptDecodeSnippet(mojom.MSGPIPE)
143 if mojom.IsEnumKind(kind):
144 return JavaScriptDecodeSnippet(mojom.INT32)
145
146
147 def JavaScriptEncodeSnippet(kind):
148 if kind in mojom.PRIMITIVES:
149 return "encodeStruct(%s, " % CodecType(kind)
150 if mojom.IsStructKind(kind):
151 return "encodeStructPointer(%s, " % JavaScriptType(kind)
152 if mojom.IsMapKind(kind):
153 return "encodeMapPointer(%s, %s, " % \
154 (ElementCodecType(kind.key_kind), ElementCodecType(kind.value_kind))
155 if mojom.IsArrayKind(kind) and mojom.IsBoolKind(kind.kind):
156 return "encodeArrayPointer(codec.PackedBool, ";
157 if mojom.IsArrayKind(kind):
158 return "encodeArrayPointer(%s, " % CodecType(kind.kind)
159 if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind):
160 return JavaScriptEncodeSnippet(mojom.MSGPIPE)
161 if mojom.IsEnumKind(kind):
162 return JavaScriptEncodeSnippet(mojom.INT32)
163
164
165 def JavaScriptFieldOffset(packed_field):
166 return "offset + codec.kStructHeaderSize + %s" % packed_field.offset
167
168
169 def JavaScriptNullableParam(packed_field):
170 return "true" if mojom.IsNullableKind(packed_field.field.kind) else "false"
171
172
173 def GetArrayExpectedDimensionSizes(kind):
174 expected_dimension_sizes = []
175 while mojom.IsArrayKind(kind):
176 expected_dimension_sizes.append(generator.ExpectedArraySize(kind) or 0)
177 kind = kind.kind
178 # Strings are serialized as variable-length arrays.
179 if (mojom.IsStringKind(kind)):
180 expected_dimension_sizes.append(0)
181 return expected_dimension_sizes
182
183
184 def JavaScriptValidateArrayParams(packed_field):
185 nullable = JavaScriptNullableParam(packed_field)
186 field_offset = JavaScriptFieldOffset(packed_field)
187 element_kind = packed_field.field.kind.kind
188 element_size = pack.PackedField.GetSizeForKind(element_kind)
189 expected_dimension_sizes = GetArrayExpectedDimensionSizes(
190 packed_field.field.kind)
191 element_type = ElementCodecType(element_kind)
192 return "%s, %s, %s, %s, %s, 0" % \
193 (field_offset, element_size, element_type, nullable,
194 expected_dimension_sizes)
195
196
197 def JavaScriptValidateStructParams(packed_field):
198 nullable = JavaScriptNullableParam(packed_field)
199 field_offset = JavaScriptFieldOffset(packed_field)
200 struct_type = JavaScriptType(packed_field.field.kind)
201 return "%s, %s, %s" % (field_offset, struct_type, nullable)
202
203
204 def JavaScriptValidateMapParams(packed_field):
205 nullable = JavaScriptNullableParam(packed_field)
206 field_offset = JavaScriptFieldOffset(packed_field)
207 keys_type = ElementCodecType(packed_field.field.kind.key_kind)
208 values_kind = packed_field.field.kind.value_kind;
209 values_type = ElementCodecType(values_kind)
210 values_nullable = "true" if mojom.IsNullableKind(values_kind) else "false"
211 return "%s, %s, %s, %s, %s" % \
212 (field_offset, nullable, keys_type, values_type, values_nullable)
213
214
215 def JavaScriptValidateStringParams(packed_field):
216 nullable = JavaScriptNullableParam(packed_field)
217 return "%s, %s" % (JavaScriptFieldOffset(packed_field), nullable)
218
219
220 def JavaScriptValidateHandleParams(packed_field):
221 nullable = JavaScriptNullableParam(packed_field)
222 field_offset = JavaScriptFieldOffset(packed_field)
223 return "%s, %s" % (field_offset, nullable)
224
225
226
227
228 def JavaScriptProxyMethodParameterValue(parameter):
229 name = parameter.name;
230 if (IsInterfaceParameter(parameter)):
231 type = JavaScriptType(parameter.kind)
232 return "core.isHandle(%s) ? %s : connection.bindProxyClient" \
233 "(%s, %s, %s.client)" % (name, name, name, type, type)
234 if (IsInterfaceRequestParameter(parameter)):
235 type = JavaScriptType(parameter.kind.kind)
236 return "core.isHandle(%s) ? %s : connection.bindProxyClient" \
237 "(%s, %s.client, %s)" % (name, name, name, type, type)
238 return name;
239
240 def JavaScriptStubMethodParameterValue(parameter):
241 name = parameter.name;
242 if (IsInterfaceParameter(parameter)):
243 type = JavaScriptType(parameter.kind)
244 return "connection.bindProxyHandle(%s, %s.client, %s)" % (name, type, type)
245 if (IsInterfaceRequestParameter(parameter)):
246 type = JavaScriptType(parameter.kind.kind)
247 return "connection.bindProxyHandle(%s, %s, %s.client)" % (name, type, type)
248 return name;
249
250 def TranslateConstants(token):
251 if isinstance(token, (mojom.EnumValue, mojom.NamedValue)):
252 # Both variable and enum constants are constructed like:
253 # NamespaceUid.Struct[.Enum].CONSTANT_NAME
254 name = []
255 if token.imported_from:
256 name.append(token.imported_from["unique_name"])
257 if token.parent_kind:
258 name.append(token.parent_kind.name)
259 if isinstance(token, mojom.EnumValue):
260 name.append(token.enum.name)
261 name.append(token.name)
262 return ".".join(name)
263
264 if isinstance(token, mojom.BuiltinValue):
265 if token.value == "double.INFINITY" or token.value == "float.INFINITY":
266 return "Infinity";
267 if token.value == "double.NEGATIVE_INFINITY" or \
268 token.value == "float.NEGATIVE_INFINITY":
269 return "-Infinity";
270 if token.value == "double.NAN" or token.value == "float.NAN":
271 return "NaN";
272
273 return token
274
275
276 def ExpressionToText(value):
277 return TranslateConstants(value)
278
279 def IsArrayPointerField(field):
280 return mojom.IsArrayKind(field.kind)
281
282 def IsStringPointerField(field):
283 return mojom.IsStringKind(field.kind)
284
285 def IsStructPointerField(field):
286 return mojom.IsStructKind(field.kind)
287
288 def IsMapPointerField(field):
289 return mojom.IsMapKind(field.kind)
290
291 def IsHandleField(field):
292 return mojom.IsAnyHandleKind(field.kind)
293
294 def IsInterfaceRequestParameter(parameter):
295 return mojom.IsInterfaceRequestKind(parameter.kind)
296
297 def IsInterfaceParameter(parameter):
298 return mojom.IsInterfaceKind(parameter.kind)
299
300
301 class Generator(generator.Generator):
302
303 js_filters = {
304 "default_value": JavaScriptDefaultValue,
305 "payload_size": JavaScriptPayloadSize,
306 "decode_snippet": JavaScriptDecodeSnippet,
307 "encode_snippet": JavaScriptEncodeSnippet,
308 "expression_to_text": ExpressionToText,
309 "field_offset": JavaScriptFieldOffset,
310 "has_callbacks": mojom.HasCallbacks,
311 "is_array_pointer_field": IsArrayPointerField,
312 "is_map_pointer_field": IsMapPointerField,
313 "is_struct_pointer_field": IsStructPointerField,
314 "is_string_pointer_field": IsStringPointerField,
315 "is_handle_field": IsHandleField,
316 "js_type": JavaScriptType,
317 "is_interface_request_parameter": IsInterfaceRequestParameter,
318 "is_interface_parameter": IsInterfaceParameter,
319 "js_proxy_method_parameter_value": JavaScriptProxyMethodParameterValue,
320 "js_stub_method_parameter_value": JavaScriptStubMethodParameterValue,
321 "stylize_method": generator.StudlyCapsToCamel,
322 "validate_array_params": JavaScriptValidateArrayParams,
323 "validate_handle_params": JavaScriptValidateHandleParams,
324 "validate_map_params": JavaScriptValidateMapParams,
325 "validate_string_params": JavaScriptValidateStringParams,
326 "validate_struct_params": JavaScriptValidateStructParams,
327 }
328
329 def GetParameters(self):
330 return {
331 "namespace": self.module.namespace,
332 "imports": self.GetImports(),
333 "kinds": self.module.kinds,
334 "enums": self.module.enums,
335 "module": self.module,
336 "structs": self.GetStructs() + self.GetStructsFromMethods(),
337 "interfaces": self.module.interfaces,
338 "imported_interfaces": self.GetImportedInterfaces(),
339 }
340
341 @UseJinja("js_templates/module.amd.tmpl", filters=js_filters)
342 def GenerateAMDModule(self):
343 return self.GetParameters()
344
345 @UseJinja("js_templates/module.sky.tmpl", filters=js_filters)
346 def GenerateHTMLModule(self):
347 return self.GetParameters()
348
349 def GenerateFiles(self, args):
350 self.Write(self.GenerateAMDModule(),
351 self.MatchMojomFilePath("%s.js" % self.module.name))
352 self.Write(self.GenerateHTMLModule(),
353 self.MatchMojomFilePath("%s.sky" % self.module.name))
354
355 def GetImports(self):
356 used_names = set()
357 for each_import in self.module.imports:
358 simple_name = each_import["module_name"].split(".")[0]
359
360 # Since each import is assigned a variable in JS, they need to have unique
361 # names.
362 unique_name = simple_name
363 counter = 0
364 while unique_name in used_names:
365 counter += 1
366 unique_name = simple_name + str(counter)
367
368 used_names.add(unique_name)
369 each_import["unique_name"] = unique_name + "$"
370 counter += 1
371 return self.module.imports
372
373 def GetImportedInterfaces(self):
374 interface_to_import = {};
375 for each_import in self.module.imports:
376 for each_interface in each_import["module"].interfaces:
377 name = each_interface.name
378 interface_to_import[name] = each_import["unique_name"] + "." + name
379 return interface_to_import;
380
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698