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