OLD | NEW |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 java source files from a mojom.Module.""" | 5 """Generates java source files from a mojom.Module.""" |
6 | 6 |
7 import argparse | 7 import argparse |
8 import ast | 8 import ast |
9 import os | 9 import os |
10 import re | 10 import re |
11 | 11 |
12 from jinja2 import contextfilter | 12 from jinja2 import contextfilter |
13 | 13 |
14 import mojom.generate.generator as generator | 14 import mojom.generate.generator as generator |
15 import mojom.generate.module as mojom | 15 import mojom.generate.module as mojom |
16 from mojom.generate.template_expander import UseJinja | 16 from mojom.generate.template_expander import UseJinja |
17 | 17 |
18 | 18 |
19 GENERATOR_PREFIX = 'java' | 19 GENERATOR_PREFIX = 'java' |
20 | 20 |
21 _HEADER_SIZE = 8 | 21 _HEADER_SIZE = 8 |
22 | 22 |
23 _spec_to_java_type = { | 23 _spec_to_java_type = { |
24 'b': 'boolean', | 24 mojom.BOOL.spec: 'boolean', |
25 'd': 'double', | 25 mojom.DCPIPE.spec: 'org.chromium.mojo.system.DataPipe.ConsumerHandle', |
26 'f': 'float', | 26 mojom.DOUBLE.spec: 'double', |
27 'h:d:c': 'org.chromium.mojo.system.DataPipe.ConsumerHandle', | 27 mojom.DPPIPE.spec: 'org.chromium.mojo.system.DataPipe.ProducerHandle', |
28 'h:d:p': 'org.chromium.mojo.system.DataPipe.ProducerHandle', | 28 mojom.FLOAT.spec: 'float', |
29 'h:m': 'org.chromium.mojo.system.MessagePipeHandle', | 29 mojom.HANDLE.spec: 'org.chromium.mojo.system.UntypedHandle', |
30 'h': 'org.chromium.mojo.system.UntypedHandle', | 30 mojom.INT16.spec: 'short', |
31 'h:s': 'org.chromium.mojo.system.SharedBufferHandle', | 31 mojom.INT32.spec: 'int', |
32 'i16': 'short', | 32 mojom.INT64.spec: 'long', |
33 'i32': 'int', | 33 mojom.INT8.spec: 'byte', |
34 'i64': 'long', | 34 mojom.MSGPIPE.spec: 'org.chromium.mojo.system.MessagePipeHandle', |
35 'i8': 'byte', | 35 mojom.NULLABLE_DCPIPE.spec: |
36 's': 'String', | 36 'org.chromium.mojo.system.DataPipe.ConsumerHandle', |
37 'u16': 'short', | 37 mojom.NULLABLE_DPPIPE.spec: |
38 'u32': 'int', | 38 'org.chromium.mojo.system.DataPipe.ProducerHandle', |
39 'u64': 'long', | 39 mojom.NULLABLE_HANDLE.spec: 'org.chromium.mojo.system.UntypedHandle', |
40 'u8': 'byte', | 40 mojom.NULLABLE_MSGPIPE.spec: 'org.chromium.mojo.system.MessagePipeHandle', |
| 41 mojom.NULLABLE_SHAREDBUFFER.spec: |
| 42 'org.chromium.mojo.system.SharedBufferHandle', |
| 43 mojom.NULLABLE_STRING.spec: 'String', |
| 44 mojom.SHAREDBUFFER.spec: 'org.chromium.mojo.system.SharedBufferHandle', |
| 45 mojom.STRING.spec: 'String', |
| 46 mojom.UINT16.spec: 'short', |
| 47 mojom.UINT32.spec: 'int', |
| 48 mojom.UINT64.spec: 'long', |
| 49 mojom.UINT8.spec: 'byte', |
41 } | 50 } |
42 | 51 |
43 _spec_to_decode_method = { | 52 _spec_to_decode_method = { |
44 'b': 'readBoolean', | 53 mojom.BOOL.spec: 'readBoolean', |
45 'd': 'readDouble', | 54 mojom.DCPIPE.spec: 'readConsumerHandle', |
46 'f': 'readFloat', | 55 mojom.DOUBLE.spec: 'readDouble', |
47 'h:d:c': 'readConsumerHandle', | 56 mojom.DPPIPE.spec: 'readProducerHandle', |
48 'h:d:p': 'readProducerHandle', | 57 mojom.FLOAT.spec: 'readFloat', |
49 'h:m': 'readMessagePipeHandle', | 58 mojom.HANDLE.spec: 'readUntypedHandle', |
50 'h': 'readUntypedHandle', | 59 mojom.INT16.spec: 'readShort', |
51 'h:s': 'readSharedBufferHandle', | 60 mojom.INT32.spec: 'readInt', |
52 'i16': 'readShort', | 61 mojom.INT64.spec: 'readLong', |
53 'i32': 'readInt', | 62 mojom.INT8.spec: 'readByte', |
54 'i64': 'readLong', | 63 mojom.MSGPIPE.spec: 'readMessagePipeHandle', |
55 'i8': 'readByte', | 64 mojom.NULLABLE_DCPIPE.spec: 'readConsumerHandle', |
56 's': 'readString', | 65 mojom.NULLABLE_DPPIPE.spec: 'readProducerHandle', |
57 'u16': 'readShort', | 66 mojom.NULLABLE_HANDLE.spec: 'readUntypedHandle', |
58 'u32': 'readInt', | 67 mojom.NULLABLE_MSGPIPE.spec: 'readMessagePipeHandle', |
59 'u64': 'readLong', | 68 mojom.NULLABLE_SHAREDBUFFER.spec: 'readSharedBufferHandle', |
60 'u8': 'readByte', | 69 mojom.NULLABLE_STRING.spec: 'readString', |
| 70 mojom.SHAREDBUFFER.spec: 'readSharedBufferHandle', |
| 71 mojom.STRING.spec: 'readString', |
| 72 mojom.UINT16.spec: 'readShort', |
| 73 mojom.UINT32.spec: 'readInt', |
| 74 mojom.UINT64.spec: 'readLong', |
| 75 mojom.UINT8.spec: 'readByte', |
61 } | 76 } |
62 | 77 |
63 _java_primitive_to_boxed_type = { | 78 _java_primitive_to_boxed_type = { |
64 'boolean': 'Boolean', | 79 'boolean': 'Boolean', |
65 'byte': 'Byte', | 80 'byte': 'Byte', |
66 'double': 'Double', | 81 'double': 'Double', |
67 'float': 'Float', | 82 'float': 'Float', |
68 'int': 'Integer', | 83 'int': 'Integer', |
69 'long': 'Long', | 84 'long': 'Long', |
70 'short': 'Short', | 85 'short': 'Short', |
(...skipping 19 matching lines...) Expand all Loading... |
90 uccc = UpperCamelCase(name) | 105 uccc = UpperCamelCase(name) |
91 return uccc[0].lower() + uccc[1:] | 106 return uccc[0].lower() + uccc[1:] |
92 | 107 |
93 def ConstantStyle(name): | 108 def ConstantStyle(name): |
94 components = NameToComponent(name) | 109 components = NameToComponent(name) |
95 if components[0] == 'k': | 110 if components[0] == 'k': |
96 components = components[1:] | 111 components = components[1:] |
97 return '_'.join([x.upper() for x in components]) | 112 return '_'.join([x.upper() for x in components]) |
98 | 113 |
99 def GetNameForElement(element): | 114 def GetNameForElement(element): |
100 if isinstance(element, (mojom.Enum, | 115 if (mojom.IsEnumKind(element) or mojom.IsInterfaceKind(element) or |
101 mojom.Interface, | 116 mojom.IsStructKind(element)): |
102 mojom.Struct)): | |
103 return UpperCamelCase(element.name) | 117 return UpperCamelCase(element.name) |
104 if isinstance(element, mojom.InterfaceRequest): | 118 if mojom.IsInterfaceRequestKind(element): |
105 return GetNameForElement(element.kind) | 119 return GetNameForElement(element.kind) |
106 if isinstance(element, (mojom.Method, | 120 if isinstance(element, (mojom.Method, |
107 mojom.Parameter, | 121 mojom.Parameter, |
108 mojom.Field)): | 122 mojom.Field)): |
109 return CamelCase(element.name) | 123 return CamelCase(element.name) |
110 if isinstance(element, mojom.EnumValue): | 124 if isinstance(element, mojom.EnumValue): |
111 return (UpperCamelCase(element.enum_name) + '.' + | 125 return (UpperCamelCase(element.enum_name) + '.' + |
112 ConstantStyle(element.name)) | 126 ConstantStyle(element.name)) |
113 if isinstance(element, (mojom.NamedValue, | 127 if isinstance(element, (mojom.NamedValue, |
114 mojom.Constant)): | 128 mojom.Constant)): |
115 return ConstantStyle(element.name) | 129 return ConstantStyle(element.name) |
116 raise Exception("Unexpected element: " % element) | 130 raise Exception("Unexpected element: " % element) |
117 | 131 |
118 def GetInterfaceResponseName(method): | 132 def GetInterfaceResponseName(method): |
119 return UpperCamelCase(method.name + 'Response') | 133 return UpperCamelCase(method.name + 'Response') |
120 | 134 |
121 def ParseStringAttribute(attribute): | 135 def ParseStringAttribute(attribute): |
122 assert isinstance(attribute, basestring) | 136 assert isinstance(attribute, basestring) |
123 return attribute | 137 return attribute |
124 | 138 |
125 def IsArray(kind): | |
126 return isinstance(kind, (mojom.Array, mojom.FixedArray)) | |
127 | |
128 @contextfilter | 139 @contextfilter |
129 def DecodeMethod(context, kind, offset, bit): | 140 def DecodeMethod(context, kind, offset, bit): |
130 def _DecodeMethodName(kind): | 141 def _DecodeMethodName(kind): |
131 if IsArray(kind): | 142 if mojom.IsAnyArrayKind(kind): |
132 return _DecodeMethodName(kind.kind) + 's' | 143 return _DecodeMethodName(kind.kind) + 's' |
133 if isinstance(kind, mojom.Enum): | 144 if mojom.IsEnumKind(kind): |
134 return _DecodeMethodName(mojom.INT32) | 145 return _DecodeMethodName(mojom.INT32) |
135 if isinstance(kind, mojom.InterfaceRequest): | 146 if mojom.IsInterfaceRequestKind(kind): |
136 return "readInterfaceRequest" | 147 return "readInterfaceRequest" |
137 if isinstance(kind, mojom.Interface): | 148 if mojom.IsInterfaceKind(kind): |
138 return "readServiceInterface" | 149 return "readServiceInterface" |
139 return _spec_to_decode_method[kind.spec] | 150 return _spec_to_decode_method[kind.spec] |
140 methodName = _DecodeMethodName(kind) | 151 methodName = _DecodeMethodName(kind) |
141 additionalParams = '' | 152 additionalParams = '' |
142 if (kind == mojom.BOOL): | 153 if (kind == mojom.BOOL): |
143 additionalParams = ', %d' % bit | 154 additionalParams = ', %d' % bit |
144 if isinstance(kind, mojom.Interface): | 155 if mojom.IsInterfaceKind(kind): |
145 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind) | 156 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind) |
146 if IsArray(kind) and isinstance(kind.kind, mojom.Interface): | 157 if mojom.IsAnyArrayKind(kind) and mojom.IsInterfaceKind(kind.kind): |
147 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind.kind) | 158 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind.kind) |
148 return '%s(%s%s)' % (methodName, offset, additionalParams) | 159 return '%s(%s%s)' % (methodName, offset, additionalParams) |
149 | 160 |
150 @contextfilter | 161 @contextfilter |
151 def EncodeMethod(context, kind, variable, offset, bit): | 162 def EncodeMethod(context, kind, variable, offset, bit): |
152 additionalParams = '' | 163 additionalParams = '' |
153 if (kind == mojom.BOOL): | 164 if (kind == mojom.BOOL): |
154 additionalParams = ', %d' % bit | 165 additionalParams = ', %d' % bit |
155 if isinstance(kind, mojom.Interface): | 166 if mojom.IsInterfaceKind(kind): |
156 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind) | 167 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind) |
157 if IsArray(kind) and isinstance(kind.kind, mojom.Interface): | 168 if mojom.IsAnyArrayKind(kind) and mojom.IsInterfaceKind(kind.kind): |
158 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind.kind) | 169 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind.kind) |
159 return 'encode(%s, %s%s)' % (variable, offset, additionalParams) | 170 return 'encode(%s, %s%s)' % (variable, offset, additionalParams) |
160 | 171 |
161 def GetPackage(module): | 172 def GetPackage(module): |
162 if 'JavaPackage' in module.attributes: | 173 if 'JavaPackage' in module.attributes: |
163 return ParseStringAttribute(module.attributes['JavaPackage']) | 174 return ParseStringAttribute(module.attributes['JavaPackage']) |
164 # Default package. | 175 # Default package. |
165 return "org.chromium.mojom." + module.namespace | 176 return "org.chromium.mojom." + module.namespace |
166 | 177 |
167 def GetNameForKind(context, kind): | 178 def GetNameForKind(context, kind): |
(...skipping 14 matching lines...) Expand all Loading... |
182 def GetBoxedJavaType(context, kind): | 193 def GetBoxedJavaType(context, kind): |
183 unboxed_type = GetJavaType(context, kind, False) | 194 unboxed_type = GetJavaType(context, kind, False) |
184 if unboxed_type in _java_primitive_to_boxed_type: | 195 if unboxed_type in _java_primitive_to_boxed_type: |
185 return _java_primitive_to_boxed_type[unboxed_type] | 196 return _java_primitive_to_boxed_type[unboxed_type] |
186 return unboxed_type | 197 return unboxed_type |
187 | 198 |
188 @contextfilter | 199 @contextfilter |
189 def GetJavaType(context, kind, boxed=False): | 200 def GetJavaType(context, kind, boxed=False): |
190 if boxed: | 201 if boxed: |
191 return GetBoxedJavaType(context, kind) | 202 return GetBoxedJavaType(context, kind) |
192 if isinstance(kind, (mojom.Struct, mojom.Interface)): | 203 if mojom.IsStructKind(kind) or mojom.IsInterfaceKind(kind): |
193 return GetNameForKind(context, kind) | 204 return GetNameForKind(context, kind) |
194 if isinstance(kind, mojom.InterfaceRequest): | 205 if mojom.IsInterfaceRequestKind(kind): |
195 return ("org.chromium.mojo.bindings.InterfaceRequest<%s>" % | 206 return ("org.chromium.mojo.bindings.InterfaceRequest<%s>" % |
196 GetNameForKind(context, kind.kind)) | 207 GetNameForKind(context, kind.kind)) |
197 if IsArray(kind): | 208 if mojom.IsAnyArrayKind(kind): |
198 return "%s[]" % GetJavaType(context, kind.kind) | 209 return "%s[]" % GetJavaType(context, kind.kind) |
199 if isinstance(kind, mojom.Enum): | 210 if mojom.IsEnumKind(kind): |
200 return "int" | 211 return "int" |
201 return _spec_to_java_type[kind.spec] | 212 return _spec_to_java_type[kind.spec] |
202 | 213 |
203 def IsHandle(kind): | |
204 return kind.spec[0] == 'h' | |
205 | |
206 @contextfilter | 214 @contextfilter |
207 def DefaultValue(context, field): | 215 def DefaultValue(context, field): |
208 assert field.default | 216 assert field.default |
209 if isinstance(field.kind, mojom.Struct): | 217 if isinstance(field.kind, mojom.Struct): |
210 assert field.default == "default" | 218 assert field.default == "default" |
211 return "new %s()" % GetJavaType(context, field.kind) | 219 return "new %s()" % GetJavaType(context, field.kind) |
212 return "(%s) %s" % ( | 220 return "(%s) %s" % ( |
213 GetJavaType(context, field.kind), | 221 GetJavaType(context, field.kind), |
214 ExpressionToText(context, field.default, kind_spec=field.kind.spec)) | 222 ExpressionToText(context, field.default, kind_spec=field.kind.spec)) |
215 | 223 |
216 @contextfilter | 224 @contextfilter |
217 def ConstantValue(context, constant): | 225 def ConstantValue(context, constant): |
218 return "(%s) %s" % ( | 226 return "(%s) %s" % ( |
219 GetJavaType(context, constant.kind), | 227 GetJavaType(context, constant.kind), |
220 ExpressionToText(context, constant.value, kind_spec=constant.kind.spec)) | 228 ExpressionToText(context, constant.value, kind_spec=constant.kind.spec)) |
221 | 229 |
222 @contextfilter | 230 @contextfilter |
223 def NewArray(context, kind, size): | 231 def NewArray(context, kind, size): |
224 if IsArray(kind.kind): | 232 if mojom.IsAnyArrayKind(kind.kind): |
225 return NewArray(context, kind.kind, size) + '[]' | 233 return NewArray(context, kind.kind, size) + '[]' |
226 return 'new %s[%s]' % (GetJavaType(context, kind.kind), size) | 234 return 'new %s[%s]' % (GetJavaType(context, kind.kind), size) |
227 | 235 |
228 @contextfilter | 236 @contextfilter |
229 def ExpressionToText(context, token, kind_spec=''): | 237 def ExpressionToText(context, token, kind_spec=''): |
230 def _TranslateNamedValue(named_value): | 238 def _TranslateNamedValue(named_value): |
231 entity_name = GetNameForElement(named_value) | 239 entity_name = GetNameForElement(named_value) |
232 if named_value.parent_kind: | 240 if named_value.parent_kind: |
233 return GetJavaType(context, named_value.parent_kind) + '.' + entity_name | 241 return GetJavaType(context, named_value.parent_kind) + '.' + entity_name |
234 # Handle the case where named_value is a module level constant: | 242 # Handle the case where named_value is a module level constant: |
(...skipping 13 matching lines...) Expand all Loading... |
248 raise ValueError('got unexpected type %r for int literal %r' % ( | 256 raise ValueError('got unexpected type %r for int literal %r' % ( |
249 type(number), token)) | 257 type(number), token)) |
250 # If the literal is too large to fit a signed long, convert it to the | 258 # If the literal is too large to fit a signed long, convert it to the |
251 # equivalent signed long. | 259 # equivalent signed long. |
252 if number >= 2 ** 63: | 260 if number >= 2 ** 63: |
253 number -= 2 ** 64 | 261 number -= 2 ** 64 |
254 return '%dL' % number | 262 return '%dL' % number |
255 return token | 263 return token |
256 | 264 |
257 def IsPointerArrayKind(kind): | 265 def IsPointerArrayKind(kind): |
258 if not IsArray(kind): | 266 if not mojom.IsAnyArrayKind(kind): |
259 return False | 267 return False |
260 sub_kind = kind.kind | 268 sub_kind = kind.kind |
261 return generator.IsObjectKind(sub_kind) | 269 return mojom.IsObjectKind(sub_kind) |
262 | 270 |
263 def GetConstantsMainEntityName(module): | 271 def GetConstantsMainEntityName(module): |
264 if 'JavaConstantsClassName' in module.attributes: | 272 if 'JavaConstantsClassName' in module.attributes: |
265 return ParseStringAttribute(module.attributes['JavaConstantsClassName']) | 273 return ParseStringAttribute(module.attributes['JavaConstantsClassName']) |
266 # This constructs the name of the embedding classes for module level constants | 274 # This constructs the name of the embedding classes for module level constants |
267 # by extracting the mojom's filename and prepending it to Constants. | 275 # by extracting the mojom's filename and prepending it to Constants. |
268 return (UpperCamelCase(module.path.split('/')[-1].rsplit('.', 1)[0]) + | 276 return (UpperCamelCase(module.path.split('/')[-1].rsplit('.', 1)[0]) + |
269 'Constants') | 277 'Constants') |
270 | 278 |
271 class Generator(generator.Generator): | 279 class Generator(generator.Generator): |
272 | 280 |
273 java_filters = { | 281 java_filters = { |
274 "interface_response_name": GetInterfaceResponseName, | 282 "interface_response_name": GetInterfaceResponseName, |
275 "constant_value": ConstantValue, | 283 "constant_value": ConstantValue, |
276 "default_value": DefaultValue, | 284 "default_value": DefaultValue, |
277 "decode_method": DecodeMethod, | 285 "decode_method": DecodeMethod, |
278 "expression_to_text": ExpressionToText, | 286 "expression_to_text": ExpressionToText, |
279 "encode_method": EncodeMethod, | 287 "encode_method": EncodeMethod, |
280 "is_handle": IsHandle, | 288 "is_handle": mojom.IsNonInterfaceHandleKind, |
281 "is_pointer_array_kind": IsPointerArrayKind, | 289 "is_pointer_array_kind": IsPointerArrayKind, |
282 "is_struct_kind": lambda kind: isinstance(kind, mojom.Struct), | 290 "is_struct_kind": mojom.IsStructKind, |
283 "java_type": GetJavaType, | 291 "java_type": GetJavaType, |
284 "name": GetNameForElement, | 292 "name": GetNameForElement, |
285 "new_array": NewArray, | 293 "new_array": NewArray, |
286 "struct_size": lambda ps: ps.GetTotalSize() + _HEADER_SIZE, | 294 "struct_size": lambda ps: ps.GetTotalSize() + _HEADER_SIZE, |
287 } | 295 } |
288 | 296 |
289 def GetJinjaExports(self): | 297 def GetJinjaExports(self): |
290 return { | 298 return { |
291 "module": self.module, | 299 "module": self.module, |
292 "package": GetPackage(self.module), | 300 "package": GetPackage(self.module), |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 def GetJinjaParameters(self): | 362 def GetJinjaParameters(self): |
355 return { | 363 return { |
356 'lstrip_blocks': True, | 364 'lstrip_blocks': True, |
357 'trim_blocks': True, | 365 'trim_blocks': True, |
358 } | 366 } |
359 | 367 |
360 def GetGlobals(self): | 368 def GetGlobals(self): |
361 return { | 369 return { |
362 'module': self.module, | 370 'module': self.module, |
363 } | 371 } |
OLD | NEW |