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

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

Issue 468713002: JavaScript bindings for Mojo message validation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Updates per yzshen's second round of feedback 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
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 from mojom.generate.template_expander import UseJinja 10 from mojom.generate.template_expander import UseJinja
(...skipping 28 matching lines...) Expand all
39 def JavaScriptDefaultValue(field): 39 def JavaScriptDefaultValue(field):
40 if field.default: 40 if field.default:
41 if mojom.IsStructKind(field.kind): 41 if mojom.IsStructKind(field.kind):
42 assert field.default == "default" 42 assert field.default == "default"
43 return "new %s()" % JavascriptType(field.kind) 43 return "new %s()" % JavascriptType(field.kind)
44 return ExpressionToText(field.default) 44 return ExpressionToText(field.default)
45 if field.kind in mojom.PRIMITIVES: 45 if field.kind in mojom.PRIMITIVES:
46 return _kind_to_javascript_default_value[field.kind] 46 return _kind_to_javascript_default_value[field.kind]
47 if mojom.IsStructKind(field.kind): 47 if mojom.IsStructKind(field.kind):
48 return "null" 48 return "null"
49 if mojom.IsArrayKind(field.kind): 49 if mojom.IsAnyArrayKind(field.kind):
50 return "null" 50 return "null"
51 if mojom.IsInterfaceKind(field.kind) or \ 51 if mojom.IsInterfaceKind(field.kind) or \
52 mojom.IsInterfaceRequestKind(field.kind): 52 mojom.IsInterfaceRequestKind(field.kind):
53 return _kind_to_javascript_default_value[mojom.MSGPIPE] 53 return _kind_to_javascript_default_value[mojom.MSGPIPE]
54 if mojom.IsEnumKind(field.kind): 54 if mojom.IsEnumKind(field.kind):
55 return "0" 55 return "0"
56 56
57 57
58 def JavaScriptPayloadSize(packed): 58 def JavaScriptPayloadSize(packed):
59 packed_fields = packed.packed_fields 59 packed_fields = packed.packed_fields
(...skipping 30 matching lines...) Expand all
90 mojom.STRING: "codec.String", 90 mojom.STRING: "codec.String",
91 mojom.NULLABLE_STRING: "codec.String", 91 mojom.NULLABLE_STRING: "codec.String",
92 } 92 }
93 93
94 94
95 def CodecType(kind): 95 def CodecType(kind):
96 if kind in mojom.PRIMITIVES: 96 if kind in mojom.PRIMITIVES:
97 return _kind_to_codec_type[kind] 97 return _kind_to_codec_type[kind]
98 if mojom.IsStructKind(kind): 98 if mojom.IsStructKind(kind):
99 return "new codec.PointerTo(%s)" % CodecType(kind.name) 99 return "new codec.PointerTo(%s)" % CodecType(kind.name)
100 if mojom.IsArrayKind(kind) and mojom.IsBoolKind(kind.kind): 100 if mojom.IsAnyArrayKind(kind) and mojom.IsBoolKind(kind.kind):
101 return "new codec.ArrayOf(new codec.ArrayOf(codec.PackedBool))" 101 return "new codec.ArrayOf(codec.PackedBool)"
102 if mojom.IsArrayKind(kind): 102 if mojom.IsAnyArrayKind(kind):
103 return "new codec.ArrayOf(%s)" % CodecType(kind.kind) 103 return "new codec.ArrayOf(%s)" % CodecType(kind.kind)
104 if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind): 104 if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind):
105 return CodecType(mojom.MSGPIPE) 105 return CodecType(mojom.MSGPIPE)
106 if mojom.IsEnumKind(kind): 106 if mojom.IsEnumKind(kind):
107 return _kind_to_codec_type[mojom.INT32] 107 return _kind_to_codec_type[mojom.INT32]
108 return kind 108 return kind
109 109
110 110
111 def JavaScriptDecodeSnippet(kind): 111 def JavaScriptDecodeSnippet(kind):
112 if kind in mojom.PRIMITIVES: 112 if kind in mojom.PRIMITIVES:
113 return "decodeStruct(%s)" % CodecType(kind) 113 return "decodeStruct(%s)" % CodecType(kind)
114 if mojom.IsStructKind(kind): 114 if mojom.IsStructKind(kind):
115 return "decodeStructPointer(%s)" % CodecType(kind.name) 115 return "decodeStructPointer(%s)" % CodecType(kind.name)
116 if mojom.IsArrayKind(kind) and mojom.IsBoolKind(kind.kind): 116 if mojom.IsAnyArrayKind(kind) and mojom.IsBoolKind(kind.kind):
117 return "decodeArrayPointer(new codec.ArrayOf(codec.PackedBool))" 117 return "decodeArrayPointer(codec.PackedBool)"
118 if mojom.IsArrayKind(kind): 118 if mojom.IsAnyArrayKind(kind):
119 return "decodeArrayPointer(%s)" % CodecType(kind.kind) 119 return "decodeArrayPointer(%s)" % CodecType(kind.kind)
120 if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind): 120 if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind):
121 return JavaScriptDecodeSnippet(mojom.MSGPIPE) 121 return JavaScriptDecodeSnippet(mojom.MSGPIPE)
122 if mojom.IsEnumKind(kind): 122 if mojom.IsEnumKind(kind):
123 return JavaScriptDecodeSnippet(mojom.INT32) 123 return JavaScriptDecodeSnippet(mojom.INT32)
124 124
125 125
126 def JavaScriptEncodeSnippet(kind): 126 def JavaScriptEncodeSnippet(kind):
127 if kind in mojom.PRIMITIVES: 127 if kind in mojom.PRIMITIVES:
128 return "encodeStruct(%s, " % CodecType(kind) 128 return "encodeStruct(%s, " % CodecType(kind)
129 if mojom.IsStructKind(kind): 129 if mojom.IsStructKind(kind):
130 return "encodeStructPointer(%s, " % CodecType(kind.name) 130 return "encodeStructPointer(%s, " % CodecType(kind.name)
131 if mojom.IsArrayKind(kind) and mojom.IsBoolKind(kind.kind): 131 if mojom.IsAnyArrayKind(kind) and mojom.IsBoolKind(kind.kind):
132 return "encodeArrayPointer(new codec.ArrayOf(codec.PackedBool), "; 132 return "encodeArrayPointer(codec.PackedBool, ";
133 if mojom.IsAnyArrayKind(kind): 133 if mojom.IsAnyArrayKind(kind):
134 return "encodeArrayPointer(%s, " % CodecType(kind.kind) 134 return "encodeArrayPointer(%s, " % CodecType(kind.kind)
135 if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind): 135 if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind):
136 return JavaScriptEncodeSnippet(mojom.MSGPIPE) 136 return JavaScriptEncodeSnippet(mojom.MSGPIPE)
137 if mojom.IsEnumKind(kind): 137 if mojom.IsEnumKind(kind):
138 return JavaScriptEncodeSnippet(mojom.INT32) 138 return JavaScriptEncodeSnippet(mojom.INT32)
139 139
140 140
141 def JavaScriptFieldOffset(packed_field):
142 return "offset + codec.kStructHeaderSize + %s" % packed_field.offset
143
144 def JavaScriptValidateArrayParams(pf):
145 elementKind = pf.field.kind.kind
146 elementSize = pack.PackedField.GetSizeForKind(elementKind)
147 elementCount = generator.ExpectedArraySize(pf.field.kind)
148 elementType = "codec.PackedBool" if mojom.IsBoolKind(elementKind) \
149 else CodecType(elementKind)
150 return "%s, %s, %s, %s" % \
151 (JavaScriptFieldOffset(pf), elementSize, elementCount, elementType)
152
153 def JavaScriptValidateStructParams(pf):
154 return "%s, %s" % (JavaScriptFieldOffset(pf), pf.field.kind.name)
155
156
141 def TranslateConstants(token): 157 def TranslateConstants(token):
142 if isinstance(token, (mojom.EnumValue, mojom.NamedValue)): 158 if isinstance(token, (mojom.EnumValue, mojom.NamedValue)):
143 # Both variable and enum constants are constructed like: 159 # Both variable and enum constants are constructed like:
144 # NamespaceUid.Struct[.Enum].CONSTANT_NAME 160 # NamespaceUid.Struct[.Enum].CONSTANT_NAME
145 name = [] 161 name = []
146 if token.imported_from: 162 if token.imported_from:
147 name.append(token.imported_from["unique_name"]) 163 name.append(token.imported_from["unique_name"])
148 if token.parent_kind: 164 if token.parent_kind:
149 name.append(token.parent_kind.name) 165 name.append(token.parent_kind.name)
150 if isinstance(token, mojom.EnumValue): 166 if isinstance(token, mojom.EnumValue):
151 name.append(token.enum_name) 167 name.append(token.enum_name)
152 name.append(token.name) 168 name.append(token.name)
153 return ".".join(name) 169 return ".".join(name)
154 return token 170 return token
155 171
156 172
157 def ExpressionToText(value): 173 def ExpressionToText(value):
158 return TranslateConstants(value) 174 return TranslateConstants(value)
159 175
160 176
161 def JavascriptType(kind): 177 def JavascriptType(kind):
162 if kind.imported_from: 178 if kind.imported_from:
163 return kind.imported_from["unique_name"] + "." + kind.name 179 return kind.imported_from["unique_name"] + "." + kind.name
164 return kind.name 180 return kind.name
165 181
182 def IsArrayPointerField(field):
183 return mojom.IsAnyArrayKind(field.kind)
184
185 def IsStringPointerField(field):
186 return mojom.IsStringKind(field.kind)
187
188 def IsStructPointerField(field):
189 return mojom.IsStructKind(field.kind)
190
191 def IsHandleField(field):
192 return mojom.IsAnyHandleKind(field.kind)
193
166 194
167 class Generator(generator.Generator): 195 class Generator(generator.Generator):
168 196
169 js_filters = { 197 js_filters = {
170 "default_value": JavaScriptDefaultValue, 198 "default_value": JavaScriptDefaultValue,
171 "payload_size": JavaScriptPayloadSize, 199 "payload_size": JavaScriptPayloadSize,
172 "decode_snippet": JavaScriptDecodeSnippet, 200 "decode_snippet": JavaScriptDecodeSnippet,
173 "encode_snippet": JavaScriptEncodeSnippet, 201 "encode_snippet": JavaScriptEncodeSnippet,
174 "expression_to_text": ExpressionToText, 202 "expression_to_text": ExpressionToText,
203 "field_offset": JavaScriptFieldOffset,
204 "has_callbacks": mojom.HasCallbacks,
205 "is_array_pointer_field": IsArrayPointerField,
206 "is_struct_pointer_field": IsStructPointerField,
207 "is_string_pointer_field": IsStringPointerField,
208 "is_handle_field": IsHandleField,
175 "js_type": JavascriptType, 209 "js_type": JavascriptType,
176 "stylize_method": generator.StudlyCapsToCamel, 210 "stylize_method": generator.StudlyCapsToCamel,
211 "validate_array_params": JavaScriptValidateArrayParams,
212 "validate_struct_params": JavaScriptValidateStructParams,
177 } 213 }
178 214
179 @UseJinja("js_templates/module.js.tmpl", filters=js_filters) 215 @UseJinja("js_templates/module.js.tmpl", filters=js_filters)
180 def GenerateJsModule(self): 216 def GenerateJsModule(self):
181 return { 217 return {
182 "namespace": self.module.namespace, 218 "namespace": self.module.namespace,
183 "imports": self.GetImports(), 219 "imports": self.GetImports(),
184 "kinds": self.module.kinds, 220 "kinds": self.module.kinds,
185 "enums": self.module.enums, 221 "enums": self.module.enums,
186 "module": self.module, 222 "module": self.module,
187 "structs": self.GetStructs() + self.GetStructsFromMethods(), 223 "structs": self.GetStructs() + self.GetStructsFromMethods(),
188 "interfaces": self.module.interfaces, 224 "interfaces": self.module.interfaces,
189 } 225 }
190 226
191 def GenerateFiles(self, args): 227 def GenerateFiles(self, args):
192 self.Write(self.GenerateJsModule(), "%s.js" % self.module.name) 228 self.Write(self.GenerateJsModule(), "%s.js" % self.module.name)
193 229
194 def GetImports(self): 230 def GetImports(self):
195 # Since each import is assigned a variable in JS, they need to have unique 231 # Since each import is assigned a variable in JS, they need to have unique
196 # names. 232 # names.
197 counter = 1 233 counter = 1
198 for each in self.module.imports: 234 for each in self.module.imports:
199 each["unique_name"] = "import" + str(counter) 235 each["unique_name"] = "import" + str(counter)
200 counter += 1 236 counter += 1
201 return self.module.imports 237 return self.module.imports
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698