OLD | NEW |
| (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 from generate import mojom | |
8 from generate import mojom_pack | |
9 from generate import mojom_generator | |
10 | |
11 from generate.template_expander import UseJinja | |
12 | |
13 _kind_to_javascript_default_value = { | |
14 mojom.BOOL: "false", | |
15 mojom.INT8: "0", | |
16 mojom.UINT8: "0", | |
17 mojom.INT16: "0", | |
18 mojom.UINT16: "0", | |
19 mojom.INT32: "0", | |
20 mojom.UINT32: "0", | |
21 mojom.FLOAT: "0", | |
22 mojom.HANDLE: "core.kInvalidHandle", | |
23 mojom.DCPIPE: "core.kInvalidHandle", | |
24 mojom.DPPIPE: "core.kInvalidHandle", | |
25 mojom.MSGPIPE: "core.kInvalidHandle", | |
26 mojom.SHAREDBUFFER: "core.kInvalidHandle", | |
27 mojom.INT64: "0", | |
28 mojom.UINT64: "0", | |
29 mojom.DOUBLE: "0", | |
30 mojom.STRING: '""', | |
31 } | |
32 | |
33 | |
34 def JavaScriptDefaultValue(field): | |
35 if field.default: | |
36 raise Exception("Default values should've been handled in jinja.") | |
37 if field.kind in mojom.PRIMITIVES: | |
38 return _kind_to_javascript_default_value[field.kind] | |
39 if isinstance(field.kind, mojom.Struct): | |
40 return "null"; | |
41 if isinstance(field.kind, mojom.Array): | |
42 return "[]"; | |
43 if isinstance(field.kind, mojom.Interface): | |
44 return _kind_to_javascript_default_value[mojom.MSGPIPE] | |
45 if isinstance(field.kind, mojom.Enum): | |
46 return "0" | |
47 | |
48 | |
49 def JavaScriptPayloadSize(packed): | |
50 packed_fields = packed.packed_fields | |
51 if not packed_fields: | |
52 return 0; | |
53 last_field = packed_fields[-1] | |
54 offset = last_field.offset + last_field.size | |
55 pad = mojom_pack.GetPad(offset, 8) | |
56 return offset + pad; | |
57 | |
58 | |
59 _kind_to_javascript_type = { | |
60 mojom.BOOL: "codec.Uint8", | |
61 mojom.INT8: "codec.Int8", | |
62 mojom.UINT8: "codec.Uint8", | |
63 mojom.INT16: "codec.Int16", | |
64 mojom.UINT16: "codec.Uint16", | |
65 mojom.INT32: "codec.Int32", | |
66 mojom.UINT32: "codec.Uint32", | |
67 mojom.FLOAT: "codec.Float", | |
68 mojom.HANDLE: "codec.Handle", | |
69 mojom.DCPIPE: "codec.Handle", | |
70 mojom.DPPIPE: "codec.Handle", | |
71 mojom.MSGPIPE: "codec.Handle", | |
72 mojom.SHAREDBUFFER: "codec.Handle", | |
73 mojom.INT64: "codec.Int64", | |
74 mojom.UINT64: "codec.Uint64", | |
75 mojom.DOUBLE: "codec.Double", | |
76 mojom.STRING: "codec.String", | |
77 } | |
78 | |
79 | |
80 def GetJavaScriptType(kind): | |
81 if kind in mojom.PRIMITIVES: | |
82 return _kind_to_javascript_type[kind] | |
83 if isinstance(kind, mojom.Struct): | |
84 return "new codec.PointerTo(%s)" % GetJavaScriptType(kind.name) | |
85 if isinstance(kind, mojom.Array): | |
86 return "new codec.ArrayOf(%s)" % GetJavaScriptType(kind.kind) | |
87 if isinstance(kind, mojom.Interface): | |
88 return GetJavaScriptType(mojom.MSGPIPE) | |
89 if isinstance(kind, mojom.Enum): | |
90 return _kind_to_javascript_type[mojom.INT32] | |
91 return kind | |
92 | |
93 | |
94 _kind_to_javascript_decode_snippet = { | |
95 mojom.BOOL: "read8() & 1", | |
96 mojom.INT8: "read8()", | |
97 mojom.UINT8: "read8()", | |
98 mojom.INT16: "read16()", | |
99 mojom.UINT16: "read16()", | |
100 mojom.INT32: "read32()", | |
101 mojom.UINT32: "read32()", | |
102 mojom.FLOAT: "decodeFloat()", | |
103 mojom.HANDLE: "decodeHandle()", | |
104 mojom.DCPIPE: "decodeHandle()", | |
105 mojom.DPPIPE: "decodeHandle()", | |
106 mojom.MSGPIPE: "decodeHandle()", | |
107 mojom.SHAREDBUFFER: "decodeHandle()", | |
108 mojom.INT64: "read64()", | |
109 mojom.UINT64: "read64()", | |
110 mojom.DOUBLE: "decodeDouble()", | |
111 mojom.STRING: "decodeStringPointer()", | |
112 } | |
113 | |
114 | |
115 def JavaScriptDecodeSnippet(kind): | |
116 if kind in mojom.PRIMITIVES: | |
117 return _kind_to_javascript_decode_snippet[kind] | |
118 if isinstance(kind, mojom.Struct): | |
119 return "decodeStructPointer(%s)" % GetJavaScriptType(kind.name); | |
120 if isinstance(kind, mojom.Array): | |
121 return "decodeArrayPointer(%s)" % GetJavaScriptType(kind.kind); | |
122 if isinstance(kind, mojom.Interface): | |
123 return JavaScriptDecodeSnippet(mojom.MSGPIPE) | |
124 if isinstance(kind, mojom.Enum): | |
125 return _kind_to_javascript_decode_snippet[mojom.INT32] | |
126 | |
127 | |
128 _kind_to_javascript_encode_snippet = { | |
129 mojom.BOOL: "write8(1 & ", | |
130 mojom.INT8: "write8(", | |
131 mojom.UINT8: "write8(", | |
132 mojom.INT16: "write16(", | |
133 mojom.UINT16: "write16(", | |
134 mojom.INT32: "write32(", | |
135 mojom.UINT32: "write32(", | |
136 mojom.FLOAT: "encodeFloat(", | |
137 mojom.HANDLE: "encodeHandle(", | |
138 mojom.DCPIPE: "encodeHandle(", | |
139 mojom.DPPIPE: "encodeHandle(", | |
140 mojom.MSGPIPE: "encodeHandle(", | |
141 mojom.SHAREDBUFFER: "encodeHandle(", | |
142 mojom.INT64: "write64(", | |
143 mojom.UINT64: "write64(", | |
144 mojom.DOUBLE: "encodeDouble(", | |
145 mojom.STRING: "encodeStringPointer(", | |
146 } | |
147 | |
148 | |
149 def JavaScriptEncodeSnippet(kind): | |
150 if kind in mojom.PRIMITIVES: | |
151 return _kind_to_javascript_encode_snippet[kind] | |
152 if isinstance(kind, mojom.Struct): | |
153 return "encodeStructPointer(%s, " % GetJavaScriptType(kind.name); | |
154 if isinstance(kind, mojom.Array): | |
155 return "encodeArrayPointer(%s, " % GetJavaScriptType(kind.kind); | |
156 if isinstance(kind, mojom.Interface): | |
157 return JavaScriptEncodeSnippet(mojom.MSGPIPE) | |
158 if isinstance(kind, mojom.Enum): | |
159 return _kind_to_javascript_encode_snippet[mojom.INT32] | |
160 | |
161 def TranslateConstants(token, module): | |
162 if isinstance(token, mojom.Constant): | |
163 # Enum constants are constructed like: | |
164 # NamespaceUid.Struct_Enum.FIELD_NAME | |
165 name = [] | |
166 if token.imported_from: | |
167 name.append(token.imported_from["unique_name"]) | |
168 if token.parent_kind: | |
169 name.append(token.parent_kind.name + "_" + token.name[0]) | |
170 else: | |
171 name.append(token.name[0]) | |
172 name.append(token.name[1]) | |
173 return ".".join(name) | |
174 return token | |
175 | |
176 | |
177 def ExpressionToText(value, module): | |
178 if value[0] != "EXPRESSION": | |
179 raise Exception("Expected EXPRESSION, got" + value) | |
180 return "".join(mojom_generator.ExpressionMapper(value, | |
181 lambda token: TranslateConstants(token, module))) | |
182 | |
183 | |
184 def JavascriptType(kind): | |
185 if kind.imported_from: | |
186 return kind.imported_from["unique_name"] + "." + kind.name | |
187 return kind.name | |
188 | |
189 | |
190 class Generator(mojom_generator.Generator): | |
191 | |
192 js_filters = { | |
193 "default_value": JavaScriptDefaultValue, | |
194 "payload_size": JavaScriptPayloadSize, | |
195 "decode_snippet": JavaScriptDecodeSnippet, | |
196 "encode_snippet": JavaScriptEncodeSnippet, | |
197 "expression_to_text": ExpressionToText, | |
198 "is_object_kind": mojom_generator.IsObjectKind, | |
199 "is_string_kind": mojom_generator.IsStringKind, | |
200 "is_array_kind": lambda kind: isinstance(kind, mojom.Array), | |
201 "js_type": JavascriptType, | |
202 "stylize_method": mojom_generator.StudlyCapsToCamel, | |
203 "verify_token_type": mojom_generator.VerifyTokenType, | |
204 } | |
205 | |
206 @UseJinja("js_templates/module.js.tmpl", filters=js_filters) | |
207 def GenerateJsModule(self): | |
208 return { | |
209 "imports": self.GetImports(), | |
210 "kinds": self.module.kinds, | |
211 "enums": self.module.enums, | |
212 "module": self.module, | |
213 "structs": self.GetStructs() + self.GetStructsFromMethods(), | |
214 "interfaces": self.module.interfaces, | |
215 } | |
216 | |
217 def GenerateFiles(self): | |
218 self.Write(self.GenerateJsModule(), "%s.js" % self.module.name) | |
219 | |
220 def GetImports(self): | |
221 # Since each import is assigned a variable in JS, they need to have unique | |
222 # names. | |
223 counter = 1 | |
224 for each in self.module.imports: | |
225 each["unique_name"] = "import" + str(counter) | |
226 counter += 1 | |
227 return self.module.imports | |
OLD | NEW |