OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Generates JavaScript source files from a mojom.Module.""" | 5 """Generates JavaScript source files from a mojom.Module.""" |
6 | 6 |
7 import mojom.generate.generator as generator | 7 import mojom.generate.generator as generator |
8 import mojom.generate.module as mojom | 8 import mojom.generate.module as mojom |
9 import mojom.generate.pack as pack | 9 import mojom.generate.pack as pack |
10 import os | 10 import os |
(...skipping 18 matching lines...) Expand all Loading... |
29 mojom.NULLABLE_DPPIPE: "null", | 29 mojom.NULLABLE_DPPIPE: "null", |
30 mojom.NULLABLE_MSGPIPE: "null", | 30 mojom.NULLABLE_MSGPIPE: "null", |
31 mojom.NULLABLE_SHAREDBUFFER: "null", | 31 mojom.NULLABLE_SHAREDBUFFER: "null", |
32 mojom.INT64: "0", | 32 mojom.INT64: "0", |
33 mojom.UINT64: "0", | 33 mojom.UINT64: "0", |
34 mojom.DOUBLE: "0", | 34 mojom.DOUBLE: "0", |
35 mojom.STRING: "null", | 35 mojom.STRING: "null", |
36 mojom.NULLABLE_STRING: "null" | 36 mojom.NULLABLE_STRING: "null" |
37 } | 37 } |
38 | 38 |
39 | |
40 def JavaScriptType(kind): | |
41 name = [] | |
42 if kind.imported_from: | |
43 name.append(kind.imported_from["unique_name"]) | |
44 if kind.parent_kind: | |
45 name.append(kind.parent_kind.name) | |
46 name.append(kind.name) | |
47 return ".".join(name) | |
48 | |
49 | |
50 def JavaScriptDefaultValue(field): | |
51 if field.default: | |
52 if mojom.IsStructKind(field.kind): | |
53 assert field.default == "default" | |
54 return "new %s()" % JavaScriptType(field.kind) | |
55 return ExpressionToText(field.default) | |
56 if field.kind in mojom.PRIMITIVES: | |
57 return _kind_to_javascript_default_value[field.kind] | |
58 if mojom.IsStructKind(field.kind): | |
59 return "null" | |
60 if mojom.IsUnionKind(field.kind): | |
61 return "null" | |
62 if mojom.IsArrayKind(field.kind): | |
63 return "null" | |
64 if mojom.IsMapKind(field.kind): | |
65 return "null" | |
66 if mojom.IsInterfaceKind(field.kind): | |
67 return "new %sPtr()" % JavaScriptType(field.kind) | |
68 if mojom.IsInterfaceRequestKind(field.kind): | |
69 return "new bindings.InterfaceRequest()" | |
70 if mojom.IsAssociatedInterfaceKind(field.kind): | |
71 return "new associatedBindings.AssociatedInterfacePtrInfo()" | |
72 if mojom.IsAssociatedInterfaceRequestKind(field.kind): | |
73 return "new associatedBindings.AssociatedInterfaceRequest()" | |
74 if mojom.IsEnumKind(field.kind): | |
75 return "0" | |
76 raise Exception("No valid default: %s" % field) | |
77 | |
78 | |
79 def JavaScriptPayloadSize(packed): | |
80 packed_fields = packed.packed_fields | |
81 if not packed_fields: | |
82 return 0 | |
83 last_field = packed_fields[-1] | |
84 offset = last_field.offset + last_field.size | |
85 pad = pack.GetPad(offset, 8) | |
86 return offset + pad | |
87 | |
88 | |
89 _kind_to_codec_type = { | 39 _kind_to_codec_type = { |
90 mojom.BOOL: "codec.Uint8", | 40 mojom.BOOL: "codec.Uint8", |
91 mojom.INT8: "codec.Int8", | 41 mojom.INT8: "codec.Int8", |
92 mojom.UINT8: "codec.Uint8", | 42 mojom.UINT8: "codec.Uint8", |
93 mojom.INT16: "codec.Int16", | 43 mojom.INT16: "codec.Int16", |
94 mojom.UINT16: "codec.Uint16", | 44 mojom.UINT16: "codec.Uint16", |
95 mojom.INT32: "codec.Int32", | 45 mojom.INT32: "codec.Int32", |
96 mojom.UINT32: "codec.Uint32", | 46 mojom.UINT32: "codec.Uint32", |
97 mojom.FLOAT: "codec.Float", | 47 mojom.FLOAT: "codec.Float", |
98 mojom.HANDLE: "codec.Handle", | 48 mojom.HANDLE: "codec.Handle", |
99 mojom.DCPIPE: "codec.Handle", | 49 mojom.DCPIPE: "codec.Handle", |
100 mojom.DPPIPE: "codec.Handle", | 50 mojom.DPPIPE: "codec.Handle", |
101 mojom.MSGPIPE: "codec.Handle", | 51 mojom.MSGPIPE: "codec.Handle", |
102 mojom.SHAREDBUFFER: "codec.Handle", | 52 mojom.SHAREDBUFFER: "codec.Handle", |
103 mojom.NULLABLE_HANDLE: "codec.NullableHandle", | 53 mojom.NULLABLE_HANDLE: "codec.NullableHandle", |
104 mojom.NULLABLE_DCPIPE: "codec.NullableHandle", | 54 mojom.NULLABLE_DCPIPE: "codec.NullableHandle", |
105 mojom.NULLABLE_DPPIPE: "codec.NullableHandle", | 55 mojom.NULLABLE_DPPIPE: "codec.NullableHandle", |
106 mojom.NULLABLE_MSGPIPE: "codec.NullableHandle", | 56 mojom.NULLABLE_MSGPIPE: "codec.NullableHandle", |
107 mojom.NULLABLE_SHAREDBUFFER: "codec.NullableHandle", | 57 mojom.NULLABLE_SHAREDBUFFER: "codec.NullableHandle", |
108 mojom.INT64: "codec.Int64", | 58 mojom.INT64: "codec.Int64", |
109 mojom.UINT64: "codec.Uint64", | 59 mojom.UINT64: "codec.Uint64", |
110 mojom.DOUBLE: "codec.Double", | 60 mojom.DOUBLE: "codec.Double", |
111 mojom.STRING: "codec.String", | 61 mojom.STRING: "codec.String", |
112 mojom.NULLABLE_STRING: "codec.NullableString", | 62 mojom.NULLABLE_STRING: "codec.NullableString", |
113 } | 63 } |
114 | 64 |
115 | 65 |
116 def CodecType(kind): | 66 def JavaScriptPayloadSize(packed): |
117 if kind in mojom.PRIMITIVES: | 67 packed_fields = packed.packed_fields |
118 return _kind_to_codec_type[kind] | 68 if not packed_fields: |
119 if mojom.IsStructKind(kind): | 69 return 0 |
120 pointer_type = "NullablePointerTo" if mojom.IsNullableKind(kind) \ | 70 last_field = packed_fields[-1] |
121 else "PointerTo" | 71 offset = last_field.offset + last_field.size |
122 return "new codec.%s(%s)" % (pointer_type, JavaScriptType(kind)) | 72 pad = pack.GetPad(offset, 8) |
123 if mojom.IsUnionKind(kind): | 73 return offset + pad |
124 return JavaScriptType(kind) | |
125 if mojom.IsArrayKind(kind): | |
126 array_type = "NullableArrayOf" if mojom.IsNullableKind(kind) else "ArrayOf" | |
127 array_length = "" if kind.length is None else ", %d" % kind.length | |
128 element_type = ElementCodecType(kind.kind) | |
129 return "new codec.%s(%s%s)" % (array_type, element_type, array_length) | |
130 if mojom.IsInterfaceKind(kind): | |
131 return "new codec.%s(%sPtr)" % ( | |
132 "NullableInterface" if mojom.IsNullableKind(kind) else "Interface", | |
133 JavaScriptType(kind)) | |
134 if mojom.IsInterfaceRequestKind(kind): | |
135 return "codec.%s" % ( | |
136 "NullableInterfaceRequest" if mojom.IsNullableKind(kind) | |
137 else "InterfaceRequest") | |
138 if mojom.IsAssociatedInterfaceKind(kind): | |
139 return "codec.%s" % ( | |
140 "NullableAssociatedInterfacePtrInfo" if mojom.IsNullableKind(kind) | |
141 else "AssociatedInterfacePtrInfo") | |
142 if mojom.IsAssociatedInterfaceRequestKind(kind): | |
143 return "codec.%s" % ( | |
144 "NullableAssociatedInterfaceRequest" if mojom.IsNullableKind(kind) | |
145 else "AssociatedInterfaceRequest") | |
146 if mojom.IsEnumKind(kind): | |
147 return "new codec.Enum(%s)" % JavaScriptType(kind) | |
148 if mojom.IsMapKind(kind): | |
149 map_type = "NullableMapOf" if mojom.IsNullableKind(kind) else "MapOf" | |
150 key_type = ElementCodecType(kind.key_kind) | |
151 value_type = ElementCodecType(kind.value_kind) | |
152 return "new codec.%s(%s, %s)" % (map_type, key_type, value_type) | |
153 raise Exception("No codec type for %s" % kind) | |
154 | |
155 | |
156 def ElementCodecType(kind): | |
157 return "codec.PackedBool" if mojom.IsBoolKind(kind) else CodecType(kind) | |
158 | |
159 | |
160 def JavaScriptDecodeSnippet(kind): | |
161 if (kind in mojom.PRIMITIVES or mojom.IsUnionKind(kind) or | |
162 mojom.IsAnyInterfaceKind(kind)): | |
163 return "decodeStruct(%s)" % CodecType(kind) | |
164 if mojom.IsStructKind(kind): | |
165 return "decodeStructPointer(%s)" % JavaScriptType(kind) | |
166 if mojom.IsMapKind(kind): | |
167 return "decodeMapPointer(%s, %s)" % \ | |
168 (ElementCodecType(kind.key_kind), ElementCodecType(kind.value_kind)) | |
169 if mojom.IsArrayKind(kind) and mojom.IsBoolKind(kind.kind): | |
170 return "decodeArrayPointer(codec.PackedBool)" | |
171 if mojom.IsArrayKind(kind): | |
172 return "decodeArrayPointer(%s)" % CodecType(kind.kind) | |
173 if mojom.IsUnionKind(kind): | |
174 return "decodeUnion(%s)" % CodecType(kind) | |
175 if mojom.IsEnumKind(kind): | |
176 return JavaScriptDecodeSnippet(mojom.INT32) | |
177 raise Exception("No decode snippet for %s" % kind) | |
178 | |
179 | |
180 def JavaScriptEncodeSnippet(kind): | |
181 if (kind in mojom.PRIMITIVES or mojom.IsUnionKind(kind) or | |
182 mojom.IsAnyInterfaceKind(kind)): | |
183 return "encodeStruct(%s, " % CodecType(kind) | |
184 if mojom.IsUnionKind(kind): | |
185 return "encodeStruct(%s, " % JavaScriptType(kind) | |
186 if mojom.IsStructKind(kind): | |
187 return "encodeStructPointer(%s, " % JavaScriptType(kind) | |
188 if mojom.IsMapKind(kind): | |
189 return "encodeMapPointer(%s, %s, " % \ | |
190 (ElementCodecType(kind.key_kind), ElementCodecType(kind.value_kind)) | |
191 if mojom.IsArrayKind(kind) and mojom.IsBoolKind(kind.kind): | |
192 return "encodeArrayPointer(codec.PackedBool, "; | |
193 if mojom.IsArrayKind(kind): | |
194 return "encodeArrayPointer(%s, " % CodecType(kind.kind) | |
195 if mojom.IsEnumKind(kind): | |
196 return JavaScriptEncodeSnippet(mojom.INT32) | |
197 raise Exception("No encode snippet for %s" % kind) | |
198 | |
199 | |
200 def JavaScriptUnionDecodeSnippet(kind): | |
201 if mojom.IsUnionKind(kind): | |
202 return "decodeStructPointer(%s)" % JavaScriptType(kind) | |
203 return JavaScriptDecodeSnippet(kind) | |
204 | |
205 | |
206 def JavaScriptUnionEncodeSnippet(kind): | |
207 if mojom.IsUnionKind(kind): | |
208 return "encodeStructPointer(%s, " % JavaScriptType(kind) | |
209 return JavaScriptEncodeSnippet(kind) | |
210 | 74 |
211 | 75 |
212 def JavaScriptFieldOffset(packed_field): | 76 def JavaScriptFieldOffset(packed_field): |
213 return "offset + codec.kStructHeaderSize + %s" % packed_field.offset | 77 return "offset + codec.kStructHeaderSize + %s" % packed_field.offset |
214 | 78 |
215 | 79 |
216 def JavaScriptNullableParam(field): | |
217 return "true" if mojom.IsNullableKind(field.kind) else "false" | |
218 | |
219 | |
220 def GetArrayExpectedDimensionSizes(kind): | 80 def GetArrayExpectedDimensionSizes(kind): |
221 expected_dimension_sizes = [] | 81 expected_dimension_sizes = [] |
222 while mojom.IsArrayKind(kind): | 82 while mojom.IsArrayKind(kind): |
223 expected_dimension_sizes.append(generator.ExpectedArraySize(kind) or 0) | 83 expected_dimension_sizes.append(generator.ExpectedArraySize(kind) or 0) |
224 kind = kind.kind | 84 kind = kind.kind |
225 # Strings are serialized as variable-length arrays. | 85 # Strings are serialized as variable-length arrays. |
226 if (mojom.IsStringKind(kind)): | 86 if (mojom.IsStringKind(kind)): |
227 expected_dimension_sizes.append(0) | 87 expected_dimension_sizes.append(0) |
228 return expected_dimension_sizes | 88 return expected_dimension_sizes |
229 | 89 |
230 | 90 |
231 def JavaScriptValidateArrayParams(field): | |
232 nullable = JavaScriptNullableParam(field) | |
233 element_kind = field.kind.kind | |
234 element_size = pack.PackedField.GetSizeForKind(element_kind) | |
235 expected_dimension_sizes = GetArrayExpectedDimensionSizes( | |
236 field.kind) | |
237 element_type = ElementCodecType(element_kind) | |
238 return "%s, %s, %s, %s, 0" % \ | |
239 (element_size, element_type, nullable, | |
240 expected_dimension_sizes) | |
241 | |
242 | |
243 def JavaScriptValidateEnumParams(field): | |
244 return JavaScriptType(field.kind) | |
245 | |
246 def JavaScriptValidateStructParams(field): | |
247 nullable = JavaScriptNullableParam(field) | |
248 struct_type = JavaScriptType(field.kind) | |
249 return "%s, %s" % (struct_type, nullable) | |
250 | |
251 def JavaScriptValidateUnionParams(field): | |
252 nullable = JavaScriptNullableParam(field) | |
253 union_type = JavaScriptType(field.kind) | |
254 return "%s, %s" % (union_type, nullable) | |
255 | |
256 def JavaScriptValidateMapParams(field): | |
257 nullable = JavaScriptNullableParam(field) | |
258 keys_type = ElementCodecType(field.kind.key_kind) | |
259 values_kind = field.kind.value_kind; | |
260 values_type = ElementCodecType(values_kind) | |
261 values_nullable = "true" if mojom.IsNullableKind(values_kind) else "false" | |
262 return "%s, %s, %s, %s" % \ | |
263 (nullable, keys_type, values_type, values_nullable) | |
264 | |
265 | |
266 def TranslateConstants(token): | |
267 if isinstance(token, (mojom.EnumValue, mojom.NamedValue)): | |
268 # Both variable and enum constants are constructed like: | |
269 # NamespaceUid.Struct[.Enum].CONSTANT_NAME | |
270 name = [] | |
271 if token.imported_from: | |
272 name.append(token.imported_from["unique_name"]) | |
273 if token.parent_kind: | |
274 name.append(token.parent_kind.name) | |
275 if isinstance(token, mojom.EnumValue): | |
276 name.append(token.enum.name) | |
277 name.append(token.name) | |
278 return ".".join(name) | |
279 | |
280 if isinstance(token, mojom.BuiltinValue): | |
281 if token.value == "double.INFINITY" or token.value == "float.INFINITY": | |
282 return "Infinity"; | |
283 if token.value == "double.NEGATIVE_INFINITY" or \ | |
284 token.value == "float.NEGATIVE_INFINITY": | |
285 return "-Infinity"; | |
286 if token.value == "double.NAN" or token.value == "float.NAN": | |
287 return "NaN"; | |
288 | |
289 return token | |
290 | |
291 | |
292 def ExpressionToText(value): | |
293 return TranslateConstants(value) | |
294 | |
295 def IsArrayPointerField(field): | |
296 return mojom.IsArrayKind(field.kind) | |
297 | |
298 def IsEnumField(field): | |
299 return mojom.IsEnumKind(field.kind) | |
300 | |
301 def IsStringPointerField(field): | |
302 return mojom.IsStringKind(field.kind) | |
303 | |
304 def IsStructPointerField(field): | |
305 return mojom.IsStructKind(field.kind) | |
306 | |
307 def IsMapPointerField(field): | |
308 return mojom.IsMapKind(field.kind) | |
309 | |
310 def IsHandleField(field): | |
311 return mojom.IsAnyHandleKind(field.kind) | |
312 | |
313 def IsInterfaceField(field): | |
314 return mojom.IsInterfaceKind(field.kind) | |
315 | |
316 def IsInterfaceRequestField(field): | |
317 return mojom.IsInterfaceRequestKind(field.kind) | |
318 | |
319 def IsAssociatedInterfaceField(field): | |
320 return mojom.IsAssociatedInterfaceKind(field.kind) | |
321 | |
322 def IsAssociatedInterfaceRequestField(field): | |
323 return mojom.IsAssociatedInterfaceRequestKind(field.kind) | |
324 | |
325 def IsUnionField(field): | |
326 return mojom.IsUnionKind(field.kind) | |
327 | |
328 def IsBoolField(field): | |
329 return mojom.IsBoolKind(field.kind) | |
330 | |
331 def IsObjectField(field): | |
332 return mojom.IsObjectKind(field.kind) | |
333 | |
334 def IsAnyHandleOrInterfaceField(field): | |
335 return mojom.IsAnyHandleOrInterfaceKind(field.kind) | |
336 | |
337 def IsEnumField(field): | |
338 return mojom.IsEnumKind(field.kind) | |
339 | |
340 def GetRelativePath(module, base_module): | 91 def GetRelativePath(module, base_module): |
341 return os.path.relpath(module.path, os.path.dirname(base_module.path)) | 92 return os.path.relpath(module.path, os.path.dirname(base_module.path)) |
342 | 93 |
343 | 94 |
344 class Generator(generator.Generator): | 95 class Generator(generator.Generator): |
345 def _GetParameters(self): | 96 def _GetParameters(self): |
346 return { | 97 return { |
347 "namespace": self.module.namespace, | 98 "namespace": self.module.namespace, |
348 "imports": self._GetImports(), | 99 "imports": self._GetImports(), |
349 "kinds": self.module.kinds, | 100 "kinds": self.module.kinds, |
350 "enums": self.module.enums, | 101 "enums": self.module.enums, |
351 "module": self.module, | 102 "module": self.module, |
352 "structs": self.GetStructs() + self.GetStructsFromMethods(), | 103 "structs": self.GetStructs() + self.GetStructsFromMethods(), |
353 "unions": self.GetUnions(), | 104 "unions": self.GetUnions(), |
354 "use_new_js_bindings": self.use_new_js_bindings, | 105 "use_new_js_bindings": self.use_new_js_bindings, |
355 "interfaces": self.GetInterfaces(), | 106 "interfaces": self.GetInterfaces(), |
356 "imported_interfaces": self._GetImportedInterfaces(), | 107 "imported_interfaces": self._GetImportedInterfaces(), |
357 } | 108 } |
358 | 109 |
359 @staticmethod | 110 @staticmethod |
360 def GetTemplatePrefix(): | 111 def GetTemplatePrefix(): |
361 return "js_templates" | 112 return "js_templates" |
362 | 113 |
363 def GetFilters(self): | 114 def GetFilters(self): |
364 js_filters = { | 115 js_filters = { |
365 "decode_snippet": JavaScriptDecodeSnippet, | 116 "decode_snippet": self._JavaScriptDecodeSnippet, |
366 "default_value": JavaScriptDefaultValue, | 117 "default_value": self._JavaScriptDefaultValue, |
367 "encode_snippet": JavaScriptEncodeSnippet, | 118 "encode_snippet": self._JavaScriptEncodeSnippet, |
368 "expression_to_text": ExpressionToText, | 119 "expression_to_text": self._ExpressionToText, |
369 "field_offset": JavaScriptFieldOffset, | 120 "field_offset": JavaScriptFieldOffset, |
370 "has_callbacks": mojom.HasCallbacks, | 121 "has_callbacks": mojom.HasCallbacks, |
371 "is_any_handle_or_interface_field": IsAnyHandleOrInterfaceField, | 122 "is_any_handle_or_interface_kind": mojom.IsAnyHandleOrInterfaceKind, |
372 "is_array_pointer_field": IsArrayPointerField, | 123 "is_array_kind": mojom.IsArrayKind, |
373 "is_associated_interface_field": IsAssociatedInterfaceField, | 124 "is_associated_interface_kind": mojom.IsAssociatedInterfaceKind, |
374 "is_associated_interface_request_field": | 125 "is_associated_interface_request_kind": |
375 IsAssociatedInterfaceRequestField, | 126 mojom.IsAssociatedInterfaceRequestKind, |
376 "is_bool_field": IsBoolField, | 127 "is_bool_kind": mojom.IsBoolKind, |
377 "is_enum_field": IsEnumField, | 128 "is_enum_kind": mojom.IsEnumKind, |
378 "is_handle_field": IsHandleField, | 129 "is_any_handle_kind": mojom.IsAnyHandleKind, |
379 "is_interface_field": IsInterfaceField, | 130 "is_interface_kind": mojom.IsInterfaceKind, |
380 "is_interface_request_field": IsInterfaceRequestField, | 131 "is_interface_request_kind": mojom.IsInterfaceRequestKind, |
381 "is_map_pointer_field": IsMapPointerField, | 132 "is_map_kind": mojom.IsMapKind, |
382 "is_object_field": IsObjectField, | 133 "is_object_kind": mojom.IsObjectKind, |
383 "is_string_pointer_field": IsStringPointerField, | 134 "is_string_kind": mojom.IsStringKind, |
384 "is_struct_pointer_field": IsStructPointerField, | 135 "is_struct_kind": mojom.IsStructKind, |
385 "is_union_field": IsUnionField, | 136 "is_union_kind": mojom.IsUnionKind, |
386 "js_type": JavaScriptType, | 137 "js_type": self._JavaScriptType, |
387 "method_passes_associated_kinds": mojom.MethodPassesAssociatedKinds, | 138 "method_passes_associated_kinds": mojom.MethodPassesAssociatedKinds, |
388 "payload_size": JavaScriptPayloadSize, | 139 "payload_size": JavaScriptPayloadSize, |
389 "get_relative_path": GetRelativePath, | 140 "get_relative_path": GetRelativePath, |
390 "stylize_method": generator.StudlyCapsToCamel, | 141 "stylize_method": generator.StudlyCapsToCamel, |
391 "union_decode_snippet": JavaScriptUnionDecodeSnippet, | 142 "union_decode_snippet": self._JavaScriptUnionDecodeSnippet, |
392 "union_encode_snippet": JavaScriptUnionEncodeSnippet, | 143 "union_encode_snippet": self._JavaScriptUnionEncodeSnippet, |
393 "validate_array_params": JavaScriptValidateArrayParams, | 144 "validate_array_params": self._JavaScriptValidateArrayParams, |
394 "validate_enum_params": JavaScriptValidateEnumParams, | 145 "validate_enum_params": self._JavaScriptValidateEnumParams, |
395 "validate_map_params": JavaScriptValidateMapParams, | 146 "validate_map_params": self._JavaScriptValidateMapParams, |
396 "validate_nullable_params": JavaScriptNullableParam, | 147 "validate_nullable_params": self._JavaScriptNullableParam, |
397 "validate_struct_params": JavaScriptValidateStructParams, | 148 "validate_struct_params": self._JavaScriptValidateStructParams, |
398 "validate_union_params": JavaScriptValidateUnionParams, | 149 "validate_union_params": self._JavaScriptValidateUnionParams, |
399 } | 150 } |
400 return js_filters | 151 return js_filters |
401 | 152 |
402 @UseJinja("module.amd.tmpl") | 153 @UseJinja("module.amd.tmpl") |
403 def _GenerateAMDModule(self): | 154 def _GenerateAMDModule(self): |
404 return self._GetParameters() | 155 return self._GetParameters() |
405 | 156 |
406 def GenerateFiles(self, args): | 157 def GenerateFiles(self, args): |
407 if self.variant: | 158 if self.variant: |
408 raise Exception("Variants not supported in JavaScript bindings.") | 159 raise Exception("Variants not supported in JavaScript bindings.") |
409 | 160 |
410 self.Write(self._GenerateAMDModule(), | 161 self.Write(self._GenerateAMDModule(), |
411 self.MatchMojomFilePath("%s.js" % self.module.name)) | 162 self.MatchMojomFilePath("%s.js" % self.module.name)) |
412 | 163 |
413 def _GetImports(self): | 164 def _GetImports(self): |
| 165 # TODO(yzshen): Remove this method once the old JS bindings go away. |
414 used_names = set() | 166 used_names = set() |
415 for each_import in self.module.imports: | 167 for each_import in self.module.imports: |
416 simple_name = each_import["module_name"].split(".")[0] | 168 simple_name = each_import.name.split(".")[0] |
417 | 169 |
418 # Since each import is assigned a variable in JS, they need to have unique | 170 # Since each import is assigned a variable in JS, they need to have unique |
419 # names. | 171 # names. |
420 unique_name = simple_name | 172 unique_name = simple_name |
421 counter = 0 | 173 counter = 0 |
422 while unique_name in used_names: | 174 while unique_name in used_names: |
423 counter += 1 | 175 counter += 1 |
424 unique_name = simple_name + str(counter) | 176 unique_name = simple_name + str(counter) |
425 | 177 |
426 used_names.add(unique_name) | 178 used_names.add(unique_name) |
427 each_import["unique_name"] = unique_name + "$" | 179 each_import.unique_name = unique_name + "$" |
428 counter += 1 | 180 counter += 1 |
429 return self.module.imports | 181 return self.module.imports |
430 | 182 |
431 def _GetImportedInterfaces(self): | 183 def _GetImportedInterfaces(self): |
432 interface_to_import = {}; | 184 interface_to_import = {}; |
433 for each_import in self.module.imports: | 185 for each_import in self.module.imports: |
434 for each_interface in each_import["module"].interfaces: | 186 for each_interface in each_import.interfaces: |
435 name = each_interface.name | 187 name = each_interface.name |
436 interface_to_import[name] = each_import["unique_name"] + "." + name | 188 interface_to_import[name] = each_import.unique_name + "." + name |
437 return interface_to_import; | 189 return interface_to_import; |
438 | 190 |
| 191 def _JavaScriptType(self, kind): |
| 192 name = [] |
| 193 if kind.module and kind.module.path != self.module.path: |
| 194 name.append(kind.module.unique_name) |
| 195 if kind.parent_kind: |
| 196 name.append(kind.parent_kind.name) |
| 197 name.append(kind.name) |
| 198 return ".".join(name) |
| 199 |
| 200 def _JavaScriptDefaultValue(self, field): |
| 201 if field.default: |
| 202 if mojom.IsStructKind(field.kind): |
| 203 assert field.default == "default" |
| 204 return "new %s()" % self._JavaScriptType(field.kind) |
| 205 return self._ExpressionToText(field.default) |
| 206 if field.kind in mojom.PRIMITIVES: |
| 207 return _kind_to_javascript_default_value[field.kind] |
| 208 if mojom.IsStructKind(field.kind): |
| 209 return "null" |
| 210 if mojom.IsUnionKind(field.kind): |
| 211 return "null" |
| 212 if mojom.IsArrayKind(field.kind): |
| 213 return "null" |
| 214 if mojom.IsMapKind(field.kind): |
| 215 return "null" |
| 216 if mojom.IsInterfaceKind(field.kind): |
| 217 return "new %sPtr()" % self._JavaScriptType(field.kind) |
| 218 if mojom.IsInterfaceRequestKind(field.kind): |
| 219 return "new bindings.InterfaceRequest()" |
| 220 if mojom.IsAssociatedInterfaceKind(field.kind): |
| 221 return "new associatedBindings.AssociatedInterfacePtrInfo()" |
| 222 if mojom.IsAssociatedInterfaceRequestKind(field.kind): |
| 223 return "new associatedBindings.AssociatedInterfaceRequest()" |
| 224 if mojom.IsEnumKind(field.kind): |
| 225 return "0" |
| 226 raise Exception("No valid default: %s" % field) |
| 227 |
| 228 def _CodecType(self, kind): |
| 229 if kind in mojom.PRIMITIVES: |
| 230 return _kind_to_codec_type[kind] |
| 231 if mojom.IsStructKind(kind): |
| 232 pointer_type = "NullablePointerTo" if mojom.IsNullableKind(kind) \ |
| 233 else "PointerTo" |
| 234 return "new codec.%s(%s)" % (pointer_type, self._JavaScriptType(kind)) |
| 235 if mojom.IsUnionKind(kind): |
| 236 return self._JavaScriptType(kind) |
| 237 if mojom.IsArrayKind(kind): |
| 238 array_type = ("NullableArrayOf" if mojom.IsNullableKind(kind) |
| 239 else "ArrayOf") |
| 240 array_length = "" if kind.length is None else ", %d" % kind.length |
| 241 element_type = self._ElementCodecType(kind.kind) |
| 242 return "new codec.%s(%s%s)" % (array_type, element_type, array_length) |
| 243 if mojom.IsInterfaceKind(kind): |
| 244 return "new codec.%s(%sPtr)" % ( |
| 245 "NullableInterface" if mojom.IsNullableKind(kind) else "Interface", |
| 246 self._JavaScriptType(kind)) |
| 247 if mojom.IsInterfaceRequestKind(kind): |
| 248 return "codec.%s" % ( |
| 249 "NullableInterfaceRequest" if mojom.IsNullableKind(kind) |
| 250 else "InterfaceRequest") |
| 251 if mojom.IsAssociatedInterfaceKind(kind): |
| 252 return "codec.%s" % ("NullableAssociatedInterfacePtrInfo" |
| 253 if mojom.IsNullableKind(kind) else "AssociatedInterfacePtrInfo") |
| 254 if mojom.IsAssociatedInterfaceRequestKind(kind): |
| 255 return "codec.%s" % ("NullableAssociatedInterfaceRequest" |
| 256 if mojom.IsNullableKind(kind) else "AssociatedInterfaceRequest") |
| 257 if mojom.IsEnumKind(kind): |
| 258 return "new codec.Enum(%s)" % self._JavaScriptType(kind) |
| 259 if mojom.IsMapKind(kind): |
| 260 map_type = "NullableMapOf" if mojom.IsNullableKind(kind) else "MapOf" |
| 261 key_type = self._ElementCodecType(kind.key_kind) |
| 262 value_type = self._ElementCodecType(kind.value_kind) |
| 263 return "new codec.%s(%s, %s)" % (map_type, key_type, value_type) |
| 264 raise Exception("No codec type for %s" % kind) |
| 265 |
| 266 def _ElementCodecType(self, kind): |
| 267 return ("codec.PackedBool" if mojom.IsBoolKind(kind) |
| 268 else self._CodecType(kind)) |
| 269 |
| 270 def _JavaScriptDecodeSnippet(self, kind): |
| 271 if (kind in mojom.PRIMITIVES or mojom.IsUnionKind(kind) or |
| 272 mojom.IsAnyInterfaceKind(kind)): |
| 273 return "decodeStruct(%s)" % self._CodecType(kind) |
| 274 if mojom.IsStructKind(kind): |
| 275 return "decodeStructPointer(%s)" % self._JavaScriptType(kind) |
| 276 if mojom.IsMapKind(kind): |
| 277 return "decodeMapPointer(%s, %s)" % ( |
| 278 self._ElementCodecType(kind.key_kind), |
| 279 self._ElementCodecType(kind.value_kind)) |
| 280 if mojom.IsArrayKind(kind) and mojom.IsBoolKind(kind.kind): |
| 281 return "decodeArrayPointer(codec.PackedBool)" |
| 282 if mojom.IsArrayKind(kind): |
| 283 return "decodeArrayPointer(%s)" % self._CodecType(kind.kind) |
| 284 if mojom.IsUnionKind(kind): |
| 285 return "decodeUnion(%s)" % self._CodecType(kind) |
| 286 if mojom.IsEnumKind(kind): |
| 287 return self._JavaScriptDecodeSnippet(mojom.INT32) |
| 288 raise Exception("No decode snippet for %s" % kind) |
| 289 |
| 290 def _JavaScriptEncodeSnippet(self, kind): |
| 291 if (kind in mojom.PRIMITIVES or mojom.IsUnionKind(kind) or |
| 292 mojom.IsAnyInterfaceKind(kind)): |
| 293 return "encodeStruct(%s, " % self._CodecType(kind) |
| 294 if mojom.IsUnionKind(kind): |
| 295 return "encodeStruct(%s, " % self._JavaScriptType(kind) |
| 296 if mojom.IsStructKind(kind): |
| 297 return "encodeStructPointer(%s, " % self._JavaScriptType(kind) |
| 298 if mojom.IsMapKind(kind): |
| 299 return "encodeMapPointer(%s, %s, " % ( |
| 300 self._ElementCodecType(kind.key_kind), |
| 301 self._ElementCodecType(kind.value_kind)) |
| 302 if mojom.IsArrayKind(kind) and mojom.IsBoolKind(kind.kind): |
| 303 return "encodeArrayPointer(codec.PackedBool, "; |
| 304 if mojom.IsArrayKind(kind): |
| 305 return "encodeArrayPointer(%s, " % self._CodecType(kind.kind) |
| 306 if mojom.IsEnumKind(kind): |
| 307 return self._JavaScriptEncodeSnippet(mojom.INT32) |
| 308 raise Exception("No encode snippet for %s" % kind) |
| 309 |
| 310 def _JavaScriptUnionDecodeSnippet(self, kind): |
| 311 if mojom.IsUnionKind(kind): |
| 312 return "decodeStructPointer(%s)" % self._JavaScriptType(kind) |
| 313 return self._JavaScriptDecodeSnippet(kind) |
| 314 |
| 315 def _JavaScriptUnionEncodeSnippet(self, kind): |
| 316 if mojom.IsUnionKind(kind): |
| 317 return "encodeStructPointer(%s, " % self._JavaScriptType(kind) |
| 318 return self._JavaScriptEncodeSnippet(kind) |
| 319 |
| 320 def _JavaScriptNullableParam(self, field): |
| 321 return "true" if mojom.IsNullableKind(field.kind) else "false" |
| 322 |
| 323 def _JavaScriptValidateArrayParams(self, field): |
| 324 nullable = self._JavaScriptNullableParam(field) |
| 325 element_kind = field.kind.kind |
| 326 element_size = pack.PackedField.GetSizeForKind(element_kind) |
| 327 expected_dimension_sizes = GetArrayExpectedDimensionSizes( |
| 328 field.kind) |
| 329 element_type = self._ElementCodecType(element_kind) |
| 330 return "%s, %s, %s, %s, 0" % \ |
| 331 (element_size, element_type, nullable, |
| 332 expected_dimension_sizes) |
| 333 |
| 334 def _JavaScriptValidateEnumParams(self, field): |
| 335 return self._JavaScriptType(field.kind) |
| 336 |
| 337 def _JavaScriptValidateStructParams(self, field): |
| 338 nullable = self._JavaScriptNullableParam(field) |
| 339 struct_type = self._JavaScriptType(field.kind) |
| 340 return "%s, %s" % (struct_type, nullable) |
| 341 |
| 342 def _JavaScriptValidateUnionParams(self, field): |
| 343 nullable = self._JavaScriptNullableParam(field) |
| 344 union_type = self._JavaScriptType(field.kind) |
| 345 return "%s, %s" % (union_type, nullable) |
| 346 |
| 347 def _JavaScriptValidateMapParams(self, field): |
| 348 nullable = self._JavaScriptNullableParam(field) |
| 349 keys_type = self._ElementCodecType(field.kind.key_kind) |
| 350 values_kind = field.kind.value_kind; |
| 351 values_type = self._ElementCodecType(values_kind) |
| 352 values_nullable = "true" if mojom.IsNullableKind(values_kind) else "false" |
| 353 return "%s, %s, %s, %s" % \ |
| 354 (nullable, keys_type, values_type, values_nullable) |
| 355 |
| 356 def _TranslateConstants(self, token): |
| 357 if isinstance(token, (mojom.EnumValue, mojom.NamedValue)): |
| 358 # Both variable and enum constants are constructed like: |
| 359 # NamespaceUid.Struct[.Enum].CONSTANT_NAME |
| 360 name = [] |
| 361 if token.module and token.module.path != self.module.path: |
| 362 name.append(token.module.unique_name) |
| 363 if token.parent_kind: |
| 364 name.append(token.parent_kind.name) |
| 365 if isinstance(token, mojom.EnumValue): |
| 366 name.append(token.enum.name) |
| 367 name.append(token.name) |
| 368 return ".".join(name) |
| 369 |
| 370 if isinstance(token, mojom.BuiltinValue): |
| 371 if token.value == "double.INFINITY" or token.value == "float.INFINITY": |
| 372 return "Infinity"; |
| 373 if token.value == "double.NEGATIVE_INFINITY" or \ |
| 374 token.value == "float.NEGATIVE_INFINITY": |
| 375 return "-Infinity"; |
| 376 if token.value == "double.NAN" or token.value == "float.NAN": |
| 377 return "NaN"; |
| 378 |
| 379 return token |
| 380 |
| 381 def _ExpressionToText(self, value): |
| 382 return self._TranslateConstants(value) |
| 383 |
OLD | NEW |