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