| 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 |