OLD | NEW |
1 # Copyright (C) 2013 Google Inc. All rights reserved. | 1 # Copyright (C) 2013 Google Inc. All rights reserved. |
2 # | 2 # |
3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
5 # met: | 5 # met: |
6 # | 6 # |
7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
11 # in the documentation and/or other materials provided with the | 11 # in the documentation and/or other materials provided with the |
12 # distribution. | 12 # distribution. |
13 # * Neither the name of Google Inc. nor the names of its | 13 # * Neither the name of Google Inc. nor the names of its |
14 # contributors may be used to endorse or promote products derived from | 14 # contributors may be used to endorse or promote products derived from |
15 # this software without specific prior written permission. | 15 # this software without specific prior written permission. |
16 # | 16 # |
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 18 # 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 |
29 """Generate Blink V8 bindings (.h and .cpp files). | 29 """Generate Blink V8 bindings (.h and .cpp files). |
30 | 30 |
31 Input: An object of class IdlDefinitions, containing an IDL interface X | 31 Input: An object of class IdlDefinitions, containing an IDL interface X |
32 Output: V8X.h and V8X.cpp | 32 Output: V8X.h and V8X.cpp |
33 """ | 33 """ |
34 | 34 |
35 import os | 35 import os |
36 import posixpath | |
37 import re | |
38 import sys | 36 import sys |
39 | 37 |
40 # jinja2 is in chromium's third_party directory. | 38 # jinja2 is in chromium's third_party directory. |
41 module_path, module_name = os.path.split(__file__) | 39 module_path, module_name = os.path.split(__file__) |
42 third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pard
ir) | 40 third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pard
ir) |
43 sys.path.append(third_party) | 41 sys.path.append(third_party) |
44 import jinja2 | 42 import jinja2 |
45 | 43 |
46 | 44 templates_dir = os.path.join(module_path, os.pardir, 'templates') |
47 CALLBACK_INTERFACE_CPP_INCLUDES = set([ | |
48 'core/dom/ScriptExecutionContext.h', | |
49 'bindings/v8/V8Binding.h', | |
50 'bindings/v8/V8Callback.h', | |
51 'wtf/Assertions.h', | |
52 ]) | |
53 | 45 |
54 | 46 |
55 CALLBACK_INTERFACE_H_INCLUDES = set([ | 47 import v8_attributes |
56 'bindings/v8/ActiveDOMCallback.h', | 48 import v8_includes |
57 'bindings/v8/DOMWrapperWorld.h', | 49 from v8_interface import generate_constants |
58 'bindings/v8/ScopedPersistent.h', | 50 import v8_types |
59 ]) | 51 from v8_types import cpp_type |
| 52 from v8_utilities import generate_conditional_string, implemented_as_cpp_name |
| 53 from v8_values import cpp_value_to_js_value |
60 | 54 |
61 | 55 # WIP |
62 INTERFACE_CPP_INCLUDES = set([ | 56 import code_generator_idl_reader |
63 'RuntimeEnabledFeatures.h', | 57 from v8_interface import generate_implementation |
64 'bindings/v8/ScriptController.h', | 58 import v8_interface_header |
65 'bindings/v8/V8Binding.h', | |
66 'core/dom/ContextFeatures.h', | |
67 'core/dom/Document.h', | |
68 'core/page/Frame.h', | |
69 'core/platform/chromium/TraceEvent.h', | |
70 'wtf/UnusedParam.h', | |
71 ]) | |
72 | |
73 | |
74 INTERFACE_H_INCLUDES = set([ | |
75 'bindings/v8/V8Binding.h', | |
76 ]) | |
77 | |
78 | |
79 CPP_TYPE_SPECIAL_CONVERSION_RULES = { | |
80 'float': 'float', | |
81 'double': 'double', | |
82 'long long': 'long long', | |
83 'unsigned long long': 'unsigned long long', | |
84 'long': 'int', | |
85 'short': 'int', | |
86 'byte': 'int', | |
87 'boolean': 'bool', | |
88 'DOMString': 'const String&', | |
89 } | |
90 | |
91 | |
92 PRIMITIVE_TYPES = set([ | |
93 'boolean', | |
94 'void', | |
95 'Date', | |
96 'byte', | |
97 'octet', | |
98 'short', | |
99 'long', | |
100 'long long', | |
101 'unsigned short', | |
102 'unsigned long', | |
103 'unsigned long long', | |
104 'float', | |
105 'double', | |
106 ]) | |
107 | |
108 | |
109 def apply_template(path_to_template, contents): | |
110 dirname, basename = os.path.split(path_to_template) | |
111 jinja_env = jinja2.Environment(trim_blocks=True, loader=jinja2.FileSystemLoa
der([dirname])) | |
112 template = jinja_env.get_template(basename) | |
113 return template.render(contents) | |
114 | |
115 | |
116 def cpp_value_to_js_value(data_type, cpp_value, isolate, creation_context=''): | |
117 """Returns a expression that represent JS value corresponding to a C++ value
.""" | |
118 if data_type == 'boolean': | |
119 return 'v8Boolean(%s, %s)' % (cpp_value, isolate) | |
120 if data_type in ['long long', 'unsigned long long', 'DOMTimeStamp']: | |
121 # long long and unsigned long long are not representable in ECMAScript. | |
122 return 'v8::Number::New(static_cast<double>(%s))' % cpp_value | |
123 if primitive_type(data_type): | |
124 if data_type not in ['float', 'double']: | |
125 raise Exception('unexpected data_type %s' % data_type) | |
126 return 'v8::Number::New(%s)' % cpp_value | |
127 if data_type == 'DOMString': | |
128 return 'v8String(%s, %s)' % (cpp_value, isolate) | |
129 if array_or_sequence_type(data_type): | |
130 return 'v8Array(%s, %s)' % (cpp_value, isolate) | |
131 return 'toV8(%s, %s, %s)' % (cpp_value, creation_context, isolate) | |
132 | |
133 | |
134 def generate_conditional_string(interface_or_attribute_or_operation): | |
135 if 'Conditional' not in interface_or_attribute_or_operation.extended_attribu
tes: | |
136 return '' | |
137 conditional = interface_or_attribute_or_operation.extended_attributes['Condi
tional'] | |
138 for operator in ['&', '|']: | |
139 if operator in conditional: | |
140 conditions = set(conditional.split(operator)) | |
141 operator_separator = ' %s%s ' % (operator, operator) | |
142 return operator_separator.join(['ENABLE(%s)' % expression for expres
sion in sorted(conditions)]) | |
143 return 'ENABLE(%s)' % conditional | |
144 | |
145 | |
146 def includes_for_type(data_type): | |
147 if primitive_type(data_type) or data_type == 'DOMString': | |
148 return set() | |
149 if array_or_sequence_type(data_type): | |
150 return includes_for_type(array_or_sequence_type(data_type)) | |
151 return set(['V8%s.h' % data_type]) | |
152 | |
153 | |
154 def includes_for_cpp_class(class_name, relative_dir_posix): | |
155 return set([posixpath.join('bindings', relative_dir_posix, class_name + '.h'
)]) | |
156 | |
157 | |
158 def includes_for_operation(operation): | |
159 includes = includes_for_type(operation.data_type) | |
160 for parameter in operation.arguments: | |
161 includes |= includes_for_type(parameter.data_type) | |
162 return includes | |
163 | |
164 | |
165 def primitive_type(data_type): | |
166 return data_type in PRIMITIVE_TYPES | |
167 | |
168 | |
169 def sequence_type(data_type): | |
170 matched = re.match(r'sequence<([\w\d_\s]+)>', data_type) | |
171 if not matched: | |
172 return None | |
173 return matched.group(1) | |
174 | |
175 | |
176 def array_type(data_type): | |
177 matched = re.match(r'([\w\d_\s]+)\[\]', data_type) | |
178 if not matched: | |
179 return None | |
180 return matched.group(1) | |
181 | |
182 | |
183 def array_or_sequence_type(data_type): | |
184 return array_type(data_type) or sequence_type(data_type) | |
185 | |
186 def cpp_type(data_type, pointer_type): | |
187 """Returns the C++ type corresponding to the IDL type. | |
188 | |
189 Args: | |
190 pointer_type: | |
191 'raw': return raw pointer form (e.g. Foo*) | |
192 'RefPtr': return RefPtr form (e.g. RefPtr<Foo>) | |
193 'PassRefPtr': return PassRefPtr form (e.g. RefPtr<Foo>) | |
194 """ | |
195 if data_type in CPP_TYPE_SPECIAL_CONVERSION_RULES: | |
196 return CPP_TYPE_SPECIAL_CONVERSION_RULES[data_type] | |
197 if array_or_sequence_type(data_type): | |
198 return 'const Vector<%s >&' % cpp_type(array_or_sequence_type(data_type)
, 'RefPtr') | |
199 if pointer_type == 'raw': | |
200 return data_type + '*' | |
201 if pointer_type in ['RefPtr', 'PassRefPtr']: | |
202 return '%s<%s>' % (pointer_type, data_type) | |
203 raise Exception('Unrecognized pointer type: "%s"' % pointer_type) | |
204 | |
205 | |
206 def v8_type(data_type): | |
207 return 'V8' + data_type | |
208 | |
209 | |
210 def cpp_method_name(attribute_or_operation): | |
211 return attribute_or_operation.extended_attributes.get('ImplementedAs', attri
bute_or_operation.name) | |
212 | |
213 | |
214 def cpp_class_name(interface): | |
215 return interface.extended_attributes.get('ImplementedAs', interface.name) | |
216 | |
217 | |
218 def v8_class_name(interface): | |
219 return v8_type(interface.name) | |
220 | 59 |
221 | 60 |
222 class CodeGeneratorV8: | 61 class CodeGeneratorV8: |
223 def __init__(self, definitions, interface_name, output_directory, relative_d
ir_posix, idl_directories, verbose=False): | 62 def __init__(self, definitions, interface_name, output_directory, relative_d
ir_posix, idl_directories, verbose=False): |
224 self.idl_definitions = definitions | 63 self.idl_definitions = definitions |
225 self.interface_name = interface_name | 64 self.interface_name = interface_name |
226 self.idl_directories = idl_directories | |
227 self.output_directory = output_directory | 65 self.output_directory = output_directory |
228 self.relative_dir_posix = relative_dir_posix | 66 self.relative_dir_posix = relative_dir_posix |
229 self.verbose = verbose | 67 self.verbose = verbose |
230 self.interface = None | 68 self.interface = None |
231 self.header_includes = set() | 69 self.header_includes = set() |
232 self.cpp_includes = set() | 70 self.cpp_includes = set() |
233 if definitions: # FIXME: remove check when remove write_dummy_header_an
d_cpp | 71 |
234 try: | 72 # WIP = True |
| 73 WIP = False |
| 74 |
| 75 # FIXME: remove check when remove write_dummy_header_and_cpp |
| 76 if not definitions: |
| 77 return |
| 78 |
| 79 try: |
| 80 if definitions.exceptions: |
| 81 # FIXME: support exceptions |
| 82 self.exception = definitions.exceptions[interface_name] |
| 83 raise Exception('Exceptions not supported: "%s"' % interface_nam
e) |
| 84 else: |
235 self.interface = definitions.interfaces[interface_name] | 85 self.interface = definitions.interfaces[interface_name] |
236 except KeyError: | 86 except KeyError: |
237 raise Exception('%s not in IDL definitions' % interface_name) | 87 raise Exception('%s not in IDL definitions' % interface_name) |
| 88 self.v8_class_name = v8_types.get_v8_class_name(self.interface) |
| 89 if self.interface.is_callback: |
| 90 header_template_filename = 'callback_interface.h' |
| 91 cpp_template_filename = 'callback_interface.cpp' |
| 92 self.generate_contents = self.generate_callback_interface |
| 93 else: |
| 94 if WIP: |
| 95 header_template_filename = 'interface_wip.h' |
| 96 cpp_template_filename = 'interface_wip.cpp' |
| 97 self.generate_contents = self.generate_interface_wip |
| 98 else: |
| 99 header_template_filename = 'interface.h' |
| 100 cpp_template_filename = 'interface.cpp' |
| 101 self.generate_contents = self.generate_interface |
| 102 # FIXME: update to Jinja 2.7 and use: |
| 103 # keep_trailing_newline=True, # so generated files are newline-terminat
ed |
| 104 # lstrip_blocks=True, # so can indent expression tags |
| 105 jinja_env = jinja2.Environment( |
| 106 loader=jinja2.FileSystemLoader(templates_dir), |
| 107 trim_blocks=True) |
| 108 self.header_template = jinja_env.get_template(header_template_filename) |
| 109 self.cpp_template = jinja_env.get_template(cpp_template_filename) |
238 | 110 |
239 def generate_cpp_to_js_conversion(self, data_type, cpp_value, format_string,
isolate, creation_context=''): | 111 if WIP: |
240 """Returns a statement that converts a C++ value to a JS value. | 112 v8_types.set_callback_function_types(definitions.callback_functions) |
241 | 113 v8_types.set_enum_types(definitions.enumerations) |
242 Also add necessary includes to self.cpp_includes. | 114 code_generator_idl_reader.find_idl_files(idl_directories) |
243 """ | 115 link_overloaded_functions(self.interface) |
244 self.cpp_includes |= includes_for_type(data_type) | |
245 js_value = cpp_value_to_js_value(data_type, cpp_value, isolate, creation
_context) | |
246 return format_string % js_value | |
247 | 116 |
248 def write_dummy_header_and_cpp(self): | 117 def write_dummy_header_and_cpp(self): |
249 # FIXME: fix GYP so these files aren't needed and remove this method | 118 # FIXME: fix GYP so these files aren't needed and remove this method |
250 target_interface_name = self.interface_name | 119 target_interface_name = self.interface_name |
251 header_basename = 'V8%s.h' % target_interface_name | 120 header_basename = 'V8%s.h' % target_interface_name |
252 cpp_basename = 'V8%s.cpp' % target_interface_name | 121 cpp_basename = 'V8%s.cpp' % target_interface_name |
253 contents = """/* | 122 contents = """/* |
254 This file is generated just to tell build scripts that {header_basename} and | 123 This file is generated just to tell build scripts that {header_basename} and |
255 {cpp_basename} are created for {target_interface_name}.idl, and thus | 124 {cpp_basename} are created for {target_interface_name}.idl, and thus |
256 prevent the build scripts from trying to generate {header_basename} and | 125 prevent the build scripts from trying to generate {header_basename} and |
257 {cpp_basename} at every build. This file must not be tried to compile. | 126 {cpp_basename} at every build. This file must not be tried to compile. |
258 */ | 127 */ |
259 """.format(**locals()) | 128 """.format(**locals()) |
260 self.write_header_code(header_basename, contents) | 129 self.write_file(header_basename, contents) |
261 self.write_cpp_code(cpp_basename, contents) | 130 self.write_file(cpp_basename, contents) |
262 | 131 |
263 def write_header_and_cpp(self): | 132 def write_header_and_cpp(self): |
264 header_basename = v8_class_name(self.interface) + '.h' | 133 template_contents = self.generate_contents() |
265 cpp_basename = v8_class_name(self.interface) + '.cpp' | 134 template_contents.update(self.common_contents()) |
266 if self.interface.is_callback: | |
267 header_template = 'templates/callback_interface.h' | |
268 cpp_template = 'templates/callback_interface.cpp' | |
269 template_contents = self.generate_callback_interface() | |
270 else: | |
271 header_template = 'templates/interface.h' | |
272 cpp_template = 'templates/interface.cpp' | |
273 template_contents = self.generate_interface() | |
274 template_contents['conditional_string'] = generate_conditional_string(se
lf.interface) | |
275 header_file_text = apply_template(header_template, template_contents) | |
276 cpp_file_text = apply_template(cpp_template, template_contents) | |
277 self.write_header_code(header_basename, header_file_text) | |
278 self.write_cpp_code(cpp_basename, cpp_file_text) | |
279 | 135 |
280 def write_header_code(self, header_basename, header_file_text): | 136 header_basename = self.v8_class_name + '.h' |
281 header_filename = os.path.join(self.output_directory, header_basename) | 137 header_file_text = self.header_template.render(template_contents) |
282 with open(header_filename, 'w') as header_file: | 138 self.write_file(header_basename, header_file_text) |
283 header_file.write(header_file_text) | |
284 | 139 |
285 def write_cpp_code(self, cpp_basename, cpp_file_text): | 140 cpp_basename = self.v8_class_name + '.cpp' |
286 cpp_filename = os.path.join(self.output_directory, cpp_basename) | 141 cpp_file_text = self.cpp_template.render(template_contents) |
287 with open(cpp_filename, 'w') as cpp_file: | 142 self.write_file(cpp_basename, cpp_file_text) |
288 cpp_file.write(cpp_file_text) | |
289 | 143 |
290 def generate_attribute(self, attribute): | 144 def write_file(self, basename, file_text): |
291 self.cpp_includes |= includes_for_type(attribute.data_type) | 145 filename = os.path.join(self.output_directory, basename) |
| 146 with open(filename, 'w') as output_file: |
| 147 output_file.write(file_text) |
| 148 |
| 149 def common_contents(self): |
292 return { | 150 return { |
293 'name': attribute.name, | 151 'conditional_string': generate_conditional_string(self.interface), |
294 'conditional_string': generate_conditional_string(attribute), | 152 'v8_class_name': self.v8_class_name, |
295 'cpp_method_name': cpp_method_name(attribute), | 153 } |
296 'cpp_type': cpp_type(attribute.data_type, pointer_type='RefPtr'), | 154 |
297 'v8_type': v8_type(attribute.data_type), | 155 def generate_attributes(self): |
298 } | 156 attributes_contents, attributes_includes = v8_attributes.generate_attrib
utes(self.interface) |
| 157 self.cpp_includes |= attributes_includes |
| 158 return attributes_contents |
299 | 159 |
300 def generate_interface(self): | 160 def generate_interface(self): |
301 self.header_includes = INTERFACE_H_INCLUDES | 161 cpp_class_name = implemented_as_cpp_name(self.interface) |
302 self.header_includes |= includes_for_cpp_class(cpp_class_name(self.inter
face), self.relative_dir_posix) | 162 self.header_includes = v8_includes.INTERFACE_H_INCLUDES |
303 self.cpp_includes = INTERFACE_CPP_INCLUDES | 163 self.header_includes |= v8_includes.includes_for_cpp_class(cpp_class_nam
e, self.relative_dir_posix) |
| 164 self.cpp_includes = v8_includes.INTERFACE_CPP_INCLUDES |
304 | 165 |
305 template_contents = { | 166 template_contents = { |
306 'interface_name': self.interface.name, | 167 'interface_name': self.interface.name, |
307 'cpp_class_name': cpp_class_name(self.interface), | 168 'cpp_class_name': cpp_class_name, |
308 'v8_class_name': v8_class_name(self.interface), | |
309 'attributes': [self.generate_attribute(attribute) for attribute in s
elf.interface.attributes], | |
310 # Size 0 constant array is not allowed in VC++ | |
311 'number_of_attributes': 'WTF_ARRAY_LENGTH(%sAttributes)' % v8_class_
name(self.interface) if self.interface.attributes else '0', | |
312 'attribute_templates': v8_class_name(self.interface) + 'Attributes'
if self.interface.attributes else '0', | |
313 } | 169 } |
314 # Add includes afterwards, as they are modified by generate_attribute et
c. | 170 template_contents.update(self.generate_attributes()) |
315 template_contents['header_includes'] = sorted(list(self.header_includes)
) | 171 template_contents['constants'] = generate_constants(self.interface) |
316 template_contents['cpp_includes'] = sorted(list(self.cpp_includes)) | 172 # Add includes at the end, as they depend on attributes etc. |
| 173 template_contents['header_includes'] = sorted(self.header_includes) |
| 174 template_contents['cpp_includes'] = sorted(self.cpp_includes) |
317 return template_contents | 175 return template_contents |
318 | 176 |
| 177 def generate_cpp_to_js_conversion(self, data_type, cpp_value, format_string,
isolate, creation_context=''): |
| 178 """Returns a statement that converts a C++ value to a JS value. |
| 179 |
| 180 Also add necessary includes to self.cpp_includes. |
| 181 """ |
| 182 self.cpp_includes |= v8_includes.includes_for_type(data_type) |
| 183 # FIXME: Perl legacy, eliminate this |
| 184 if (data_type not in ['DOMString', 'double', 'unsigned long long'] and |
| 185 not v8_types.get_array_or_sequence_type(data_type)): |
| 186 self.cpp_includes |= set(['wtf/GetPtr.h', 'wtf/RefPtr.h']) |
| 187 js_value = cpp_value_to_js_value(data_type, cpp_value, isolate, creation
_context) |
| 188 return format_string % js_value |
| 189 |
319 def generate_callback_interface(self): | 190 def generate_callback_interface(self): |
320 self.header_includes = CALLBACK_INTERFACE_H_INCLUDES | 191 cpp_class_name = implemented_as_cpp_name(self.interface) |
321 self.header_includes |= includes_for_cpp_class(cpp_class_name(self.inter
face), self.relative_dir_posix) | 192 self.header_includes = v8_includes.CALLBACK_INTERFACE_H_INCLUDES |
322 self.cpp_includes = CALLBACK_INTERFACE_CPP_INCLUDES | 193 self.header_includes |= v8_includes.includes_for_cpp_class(cpp_class_nam
e, self.relative_dir_posix) |
| 194 self.cpp_includes = v8_includes.CALLBACK_INTERFACE_CPP_INCLUDES |
323 | 195 |
324 def generate_argument(argument): | 196 def generate_argument(argument): |
325 receiver = 'v8::Handle<v8::Value> %sHandle = %%s;' % argument.name | 197 receiver = 'v8::Handle<v8::Value> %sHandle = %%s;' % argument.name |
326 cpp_to_js_conversion = self.generate_cpp_to_js_conversion(argument.d
ata_type, argument.name, receiver, 'isolate', creation_context='v8::Handle<v8::O
bject>()') | 198 cpp_to_js_conversion = self.generate_cpp_to_js_conversion(argument.d
ata_type, argument.name, receiver, 'isolate', creation_context='v8::Handle<v8::O
bject>()') |
327 return { | 199 return { |
328 'name': argument.name, | 200 'name': argument.name, |
329 'cpp_to_js_conversion': cpp_to_js_conversion, | 201 'cpp_to_js_conversion': cpp_to_js_conversion, |
330 } | 202 } |
331 | 203 |
332 def generate_method(operation): | 204 def generate_method(operation): |
333 def argument_declaration(argument): | 205 def argument_declaration(argument): |
334 return '%s %s' % (cpp_type(argument.data_type, 'raw'), argument.
name) | 206 return '%s %s' % (cpp_type(argument.data_type, 'raw'), argument.
name) |
335 | 207 |
336 arguments = [] | |
337 custom = 'Custom' in operation.extended_attributes | 208 custom = 'Custom' in operation.extended_attributes |
338 if not custom: | 209 if custom: |
339 self.cpp_includes |= includes_for_operation(operation) | 210 arguments = [] |
| 211 else: |
340 if operation.data_type != 'boolean': | 212 if operation.data_type != 'boolean': |
341 raise Exception("We don't yet support callbacks that return
non-boolean values.") | 213 raise Exception("We don't yet support callbacks that return
non-boolean values.") |
| 214 self.cpp_includes |= v8_includes.includes_for_operation(operatio
n) |
342 arguments = [generate_argument(argument) for argument in operati
on.arguments] | 215 arguments = [generate_argument(argument) for argument in operati
on.arguments] |
343 method = { | 216 method = { |
344 'return_cpp_type': cpp_type(operation.data_type, 'RefPtr'), | 217 'return_cpp_type': cpp_type(operation.data_type, 'RefPtr'), |
345 'name': operation.name, | 218 'name': operation.name, |
346 'arguments': arguments, | 219 'arguments': arguments, |
347 'argument_declaration': ', '.join([argument_declaration(argument
) for argument in operation.arguments]), | 220 'argument_declaration': ', '.join([argument_declaration(argument
) for argument in operation.arguments]), |
348 'handles': ', '.join(['%sHandle' % argument.name for argument in
operation.arguments]), | 221 'handles': ',\n'.join(['%sHandle' % argument.name for argument i
n operation.arguments]), |
349 'custom': custom, | 222 'custom': custom, |
350 } | 223 } |
351 return method | 224 return method |
352 | 225 |
353 methods = [generate_method(operation) for operation in self.interface.op
erations] | 226 methods = [generate_method(operation) for operation in self.interface.op
erations] |
354 template_contents = { | 227 template_contents = { |
355 'cpp_class_name': self.interface.name, | 228 'cpp_class_name': self.interface.name, |
356 'v8_class_name': v8_class_name(self.interface), | 229 'cpp_includes': sorted(self.cpp_includes), |
357 'cpp_includes': sorted(list(self.cpp_includes)), | 230 'header_includes': sorted(self.header_includes), |
358 'header_includes': sorted(list(self.header_includes)), | |
359 'methods': methods, | 231 'methods': methods, |
360 } | 232 } |
361 return template_contents | 233 return template_contents |
| 234 |
| 235 ################################################################################ |
| 236 # WIP |
| 237 ################################################################################ |
| 238 |
| 239 def generate_interface_wip(self): |
| 240 template_contents = v8_interface_header.generate_header(self.interface) |
| 241 template_contents.update(generate_implementation(self.interface)) |
| 242 template_contents['constants'] = generate_constants(self.interface) |
| 243 return template_contents |
| 244 |
| 245 |
| 246 def link_overloaded_functions(interface): |
| 247 name_to_operations = {} |
| 248 for operation in interface.operations: |
| 249 name = operation.name |
| 250 if not name: |
| 251 operation.overloads = [] |
| 252 operation.overload_index = 0 |
| 253 continue |
| 254 name_to_operations.setdefault(name, []).append(operation) |
| 255 operation.overloads = name_to_operations[name] |
| 256 operation.overload_index = len(name_to_operations[name]) |
OLD | NEW |