Chromium Code Reviews| 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 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 38 import sys | 38 import sys |
| 39 | 39 |
| 40 # jinja2 is in chromium's third_party directory. | 40 # jinja2 is in chromium's third_party directory. |
| 41 module_path, module_name = os.path.split(__file__) | 41 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) | 42 third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pard ir) |
| 43 sys.path.append(third_party) | 43 sys.path.append(third_party) |
| 44 import jinja2 | 44 import jinja2 |
| 45 | 45 |
| 46 templates_dir = os.path.join(module_path, os.pardir, 'templates') | 46 templates_dir = os.path.join(module_path, os.pardir, 'templates') |
| 47 | 47 |
| 48 ACRONYMS = ['CSS', 'HTML', 'IME', 'JS', 'SVG', 'URL', 'XML', 'XSLT'] | |
| 48 CALLBACK_INTERFACE_CPP_INCLUDES = set([ | 49 CALLBACK_INTERFACE_CPP_INCLUDES = set([ |
| 49 'core/dom/ScriptExecutionContext.h', | 50 'core/dom/ScriptExecutionContext.h', |
| 50 'bindings/v8/V8Binding.h', | 51 'bindings/v8/V8Binding.h', |
| 51 'bindings/v8/V8Callback.h', | 52 'bindings/v8/V8Callback.h', |
| 52 'wtf/Assertions.h', | 53 'wtf/Assertions.h', |
| 53 ]) | 54 ]) |
| 54 | |
| 55 | |
| 56 CALLBACK_INTERFACE_H_INCLUDES = set([ | 55 CALLBACK_INTERFACE_H_INCLUDES = set([ |
| 57 'bindings/v8/ActiveDOMCallback.h', | 56 'bindings/v8/ActiveDOMCallback.h', |
| 58 'bindings/v8/DOMWrapperWorld.h', | 57 'bindings/v8/DOMWrapperWorld.h', |
| 59 'bindings/v8/ScopedPersistent.h', | 58 'bindings/v8/ScopedPersistent.h', |
| 60 ]) | 59 ]) |
| 61 | |
| 62 | |
| 63 INTERFACE_CPP_INCLUDES = set([ | 60 INTERFACE_CPP_INCLUDES = set([ |
| 64 'RuntimeEnabledFeatures.h', | 61 'RuntimeEnabledFeatures.h', |
| 65 'bindings/v8/ScriptController.h', | 62 'bindings/v8/ScriptController.h', |
| 66 'bindings/v8/V8Binding.h', | 63 'bindings/v8/V8Binding.h', |
| 67 'bindings/v8/V8DOMConfiguration.h', | 64 'bindings/v8/V8DOMConfiguration.h', # FIXME: necessary? |
| 68 'bindings/v8/V8DOMWrapper.h', | 65 'bindings/v8/V8DOMWrapper.h', # FIXME: necessary? |
| 69 'core/dom/ContextFeatures.h', | 66 'core/dom/ContextFeatures.h', |
| 70 'core/dom/Document.h', | 67 'core/dom/Document.h', |
| 71 'core/page/Frame.h', | 68 'core/page/Frame.h', |
| 72 'core/platform/chromium/TraceEvent.h', | 69 'core/platform/chromium/TraceEvent.h', |
| 73 'wtf/UnusedParam.h', | 70 'wtf/UnusedParam.h', |
| 74 ]) | 71 ]) |
| 75 | |
| 76 | |
| 77 INTERFACE_H_INCLUDES = set([ | 72 INTERFACE_H_INCLUDES = set([ |
| 78 'bindings/v8/V8Binding.h', | 73 'bindings/v8/V8Binding.h', |
| 79 'bindings/v8/V8DOMWrapper.h', | 74 'bindings/v8/V8DOMWrapper.h', # FIXME: necessary? |
| 80 'bindings/v8/WrapperTypeInfo.h', | 75 'bindings/v8/WrapperTypeInfo.h', # FIXME: necessary? |
| 81 ]) | 76 ]) |
| 82 | |
| 83 | |
| 84 CPP_TYPE_SPECIAL_CONVERSION_RULES = { | 77 CPP_TYPE_SPECIAL_CONVERSION_RULES = { |
| 85 'float': 'float', | 78 'float': 'float', |
| 86 'double': 'double', | 79 'double': 'double', |
| 87 'long long': 'long long', | 80 'long long': 'long long', |
| 88 'unsigned long long': 'unsigned long long', | 81 'unsigned long long': 'unsigned long long', |
| 89 'long': 'int', | 82 'long': 'int', |
| 90 'short': 'int', | 83 'short': 'int', |
| 91 'byte': 'int', | 84 'byte': 'int', |
| 92 'boolean': 'bool', | 85 'boolean': 'bool', |
| 93 'DOMString': 'const String&', | 86 'DOMString': 'const String&', |
| 94 } | 87 } |
| 95 | 88 CPP_UNSIGNED_TYPES = set([ |
| 96 | 89 'octet', |
| 90 'unsigned int', | |
| 91 'unsigned long', | |
| 92 'unsigned short', | |
| 93 ]) | |
| 97 PRIMITIVE_TYPES = set([ | 94 PRIMITIVE_TYPES = set([ |
| 98 'boolean', | 95 'boolean', |
| 99 'void', | 96 'void', |
| 100 'Date', | 97 'Date', |
| 101 'byte', | 98 'byte', |
| 102 'octet', | 99 'octet', |
| 103 'short', | 100 'short', |
| 104 'long', | 101 'long', |
| 105 'long long', | 102 'long long', |
| 106 'unsigned short', | 103 'unsigned short', |
| 107 'unsigned long', | 104 'unsigned long', |
| 108 'unsigned long long', | 105 'unsigned long long', |
| 109 'float', | 106 'float', |
| 110 'double', | 107 'double', |
| 111 ]) | 108 ]) |
| 109 V8_SET_RETURN_VALUE_DICT = { | |
| 110 'unsigned': 'v8SetReturnValueUnsigned({callback_info}, {cpp_value});', | |
| 111 } | |
| 112 | 112 |
| 113 | 113 |
| 114 def apply_template(basename, contents): | 114 def apply_template(basename, contents): |
| 115 jinja_env = jinja2.Environment(trim_blocks=True, loader=jinja2.FileSystemLoa der(templates_dir)) | 115 jinja_env = jinja2.Environment(trim_blocks=True, loader=jinja2.FileSystemLoa der(templates_dir)) |
| 116 template = jinja_env.get_template(basename) | 116 template = jinja_env.get_template(basename) |
| 117 return template.render(contents) | 117 return template.render(contents) |
| 118 | 118 |
| 119 | 119 |
| 120 def cpp_value_to_js_value(data_type, cpp_value, isolate, creation_context=''): | 120 def cpp_value_to_v8_value(data_type, cpp_value, isolate, creation_context=''): |
| 121 """Returns a expression that represent JS value corresponding to a C++ value .""" | 121 """Return an expression converting a C++ value to a V8 value.""" |
| 122 if data_type == 'boolean': | 122 if data_type == 'boolean': |
| 123 return 'v8Boolean(%s, %s)' % (cpp_value, isolate) | 123 return 'v8Boolean(%s, %s)' % (cpp_value, isolate) |
| 124 if data_type in ['long long', 'unsigned long long', 'DOMTimeStamp']: | 124 if data_type in ['long long', 'unsigned long long', 'DOMTimeStamp']: |
| 125 # long long and unsigned long long are not representable in ECMAScript. | 125 # long long and unsigned long long are not representable in ECMAScript. |
| 126 return 'v8::Number::New(static_cast<double>(%s))' % cpp_value | 126 return 'v8::Number::New(static_cast<double>(%s))' % cpp_value |
| 127 if primitive_type(data_type): | 127 if primitive_type(data_type): |
| 128 if data_type not in ['float', 'double']: | 128 if data_type not in ['float', 'double']: |
| 129 raise Exception('unexpected data_type %s' % data_type) | 129 raise Exception('unexpected data_type %s' % data_type) |
| 130 return 'v8::Number::New(%s)' % cpp_value | 130 return 'v8::Number::New(%s)' % cpp_value |
| 131 if data_type == 'DOMString': | 131 if data_type == 'DOMString': |
| 132 return 'v8String(%s, %s)' % (cpp_value, isolate) | 132 return 'v8String(%s, %s)' % (cpp_value, isolate) |
| 133 if array_or_sequence_type(data_type): | 133 if array_or_sequence_type(data_type): |
| 134 return 'v8Array(%s, %s)' % (cpp_value, isolate) | 134 return 'v8Array(%s, %s)' % (cpp_value, isolate) |
| 135 return 'toV8(%s, %s, %s)' % (cpp_value, creation_context, isolate) | 135 return 'toV8(%s, %s, %s)' % (cpp_value, creation_context, isolate) |
| 136 | 136 |
| 137 | 137 |
| 138 def v8_set_return_value(data_type, cpp_value, callback_info=''): | |
| 139 """Return an statement converting a C++ value to a V8 value and setting it a s a return value.""" | |
| 140 this_cpp_type = cpp_type(data_type) | |
| 141 if this_cpp_type in V8_SET_RETURN_VALUE_DICT: | |
| 142 expression_format_string = V8_SET_RETURN_VALUE_DICT[this_cpp_type] | |
|
haraken
2013/08/26 09:33:40
You can just write:
return V8_SET_RETURN_VALUE_
Nils Barth (inactive)
2013/08/27 02:59:27
That would be simpler now (with only one case), bu
| |
| 143 else: | |
| 144 raise Exception('unexpected data_type %s' % data_type) | |
| 145 return expression_format_string.format(callback_info=callback_info, cpp_valu e=cpp_value) | |
| 146 | |
| 147 | |
| 138 def generate_conditional_string(interface_or_attribute_or_operation): | 148 def generate_conditional_string(interface_or_attribute_or_operation): |
| 139 if 'Conditional' not in interface_or_attribute_or_operation.extended_attribu tes: | 149 if 'Conditional' not in interface_or_attribute_or_operation.extended_attribu tes: |
| 140 return '' | 150 return '' |
| 141 conditional = interface_or_attribute_or_operation.extended_attributes['Condi tional'] | 151 conditional = interface_or_attribute_or_operation.extended_attributes['Condi tional'] |
| 142 for operator in ['&', '|']: | 152 for operator in ['&', '|']: |
| 143 if operator in conditional: | 153 if operator in conditional: |
| 144 conditions = set(conditional.split(operator)) | 154 conditions = set(conditional.split(operator)) |
| 145 operator_separator = ' %s%s ' % (operator, operator) | 155 operator_separator = ' %s%s ' % (operator, operator) |
| 146 return operator_separator.join(['ENABLE(%s)' % expression for expres sion in sorted(conditions)]) | 156 return operator_separator.join(['ENABLE(%s)' % expression for expres sion in sorted(conditions)]) |
| 147 return 'ENABLE(%s)' % conditional | 157 return 'ENABLE(%s)' % conditional |
| 148 | 158 |
| 149 | 159 |
| 160 def generate_constants(interface): | |
| 161 return [generate_constant(constant) for constant in interface.constants] | |
| 162 | |
| 163 | |
| 164 def generate_constant(constant): | |
| 165 # Extended Attributes: Conditional, DeprecateAs, EnabledAtRuntime, Reflect | |
| 166 # FIXME: Conditional only used in tests, so remove | |
| 167 # (Blink-only) string literals are unquoted in tokenizer, must be re-quoted | |
| 168 # in C++. | |
| 169 if constant.data_type == 'DOMString': | |
| 170 value = '"%s"' % constant.value | |
| 171 else: | |
| 172 value = constant.value | |
| 173 reflected_name = constant.extended_attributes.get('Reflect', constant.name) | |
| 174 | |
| 175 constant_parameter = { | |
| 176 'name': constant.name, | |
| 177 # FIXME: use 'reflected_name' as correct 'name' | |
| 178 'reflected_name': reflected_name, | |
| 179 'value': value, | |
| 180 # FIXME: remove conditional: only used in tests | |
| 181 'conditional_string': generate_conditional_string(constant), | |
| 182 'enabled_at_runtime': 'EnabledAtRuntime' in constant.extended_attributes , | |
| 183 'enable_function': runtime_enable_function_name(constant), | |
|
haraken
2013/08/26 09:33:40
Nit: enable_function => runtime_enable_function_na
Nils Barth (inactive)
2013/08/27 02:59:27
Good point, done!
| |
| 184 } | |
| 185 return constant_parameter | |
| 186 | |
| 187 | |
| 188 def runtime_enable_function_name(definition_or_member): | |
| 189 """Return the name of the RuntimeEnabledFeatures function. | |
| 190 | |
| 191 The returned function checks if a method/attribute is enabled. | |
| 192 If a parameter is given (e.g. 'EnabledAtRuntime=FeatureName'), return: | |
| 193 RuntimeEnabledFeatures::{featureName}Enabled | |
| 194 Otherwise return: | |
| 195 RuntimeEnabledFeatures::{methodName}Enabled | |
| 196 """ | |
| 197 name = definition_or_member.extended_attributes.get('EnabledAtRuntime') or d efinition_or_member.name | |
| 198 return 'RuntimeEnabledFeatures::%sEnabled' % uncapitalize(name) | |
| 199 | |
| 200 | |
| 201 def uncapitalize(name): | |
| 202 """Uncapitalize first letter or initial acronym (* with some exceptions). | |
| 203 | |
| 204 E.g., 'SetURL' becomes 'setURL', but 'URLFoo' becomes 'urlFoo'. | |
| 205 Used in method names; exceptions differ from capitalize(). | |
| 206 """ | |
| 207 for acronym in ACRONYMS: | |
| 208 if name.startswith(acronym): | |
| 209 name.replace(acronym, acronym.lower()) | |
| 210 return name | |
| 211 return name[0].lower() + name[1:] | |
| 212 | |
| 213 | |
| 150 def includes_for_type(data_type): | 214 def includes_for_type(data_type): |
| 151 if primitive_type(data_type) or data_type == 'DOMString': | 215 if primitive_type(data_type) or data_type == 'DOMString': |
| 152 return set() | 216 return set() |
| 153 if array_or_sequence_type(data_type): | 217 if array_or_sequence_type(data_type): |
| 154 return includes_for_type(array_or_sequence_type(data_type)) | 218 return includes_for_type(array_or_sequence_type(data_type)) |
| 155 return set(['V8%s.h' % data_type]) | 219 return set(['V8%s.h' % data_type]) |
| 156 | 220 |
| 157 | 221 |
| 158 def includes_for_cpp_class(class_name, relative_dir_posix): | 222 def includes_for_cpp_class(class_name, relative_dir_posix): |
| 159 return set([posixpath.join(relative_dir_posix, class_name + '.h')]) | 223 return set([posixpath.join(relative_dir_posix, class_name + '.h')]) |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 180 def array_type(data_type): | 244 def array_type(data_type): |
| 181 matched = re.match(r'([\w\d_\s]+)\[\]', data_type) | 245 matched = re.match(r'([\w\d_\s]+)\[\]', data_type) |
| 182 if not matched: | 246 if not matched: |
| 183 return None | 247 return None |
| 184 return matched.group(1) | 248 return matched.group(1) |
| 185 | 249 |
| 186 | 250 |
| 187 def array_or_sequence_type(data_type): | 251 def array_or_sequence_type(data_type): |
| 188 return array_type(data_type) or sequence_type(data_type) | 252 return array_type(data_type) or sequence_type(data_type) |
| 189 | 253 |
| 190 def cpp_type(data_type, pointer_type): | 254 |
| 255 def cpp_type(idl_type, pointer_type=None): | |
| 191 """Returns the C++ type corresponding to the IDL type. | 256 """Returns the C++ type corresponding to the IDL type. |
| 192 | 257 |
| 258 If unidentified, fall back to a pointer. | |
| 259 | |
| 193 Args: | 260 Args: |
| 194 pointer_type: | 261 idl_type: IDL type |
| 195 'raw': return raw pointer form (e.g. Foo*) | 262 pointer_type: If specified, return 'pointer_type<idl_type>' |
| 196 'RefPtr': return RefPtr form (e.g. RefPtr<Foo>) | 263 (e.g. RefPtr<Foo>, PassRefPtr<Foo>) |
| 197 'PassRefPtr': return PassRefPtr form (e.g. RefPtr<Foo>) | 264 else defaults to returning raw pointer form (e.g. 'Foo*'). |
| 198 """ | 265 """ |
| 199 if data_type in CPP_TYPE_SPECIAL_CONVERSION_RULES: | 266 if idl_type in CPP_TYPE_SPECIAL_CONVERSION_RULES: |
| 200 return CPP_TYPE_SPECIAL_CONVERSION_RULES[data_type] | 267 return CPP_TYPE_SPECIAL_CONVERSION_RULES[idl_type] |
| 201 if array_or_sequence_type(data_type): | 268 if idl_type in CPP_UNSIGNED_TYPES: |
| 202 return 'const Vector<%s >&' % cpp_type(array_or_sequence_type(data_type) , 'RefPtr') | 269 return 'unsigned' |
| 203 if pointer_type == 'raw': | 270 if array_or_sequence_type(idl_type): |
| 204 return data_type + '*' | 271 return 'const Vector<{cpp_type} >&'.format(cpp_type=cpp_type(array_or_se quence_type(idl_type), 'RefPtr')) |
| 205 if pointer_type in ['RefPtr', 'PassRefPtr']: | 272 # Fall back to pointer |
|
haraken
2013/08/26 09:33:40
Nit: I'd drop the comment.
Nils Barth (inactive)
2013/08/27 02:59:27
Done (covered in docstring anyway).
| |
| 206 return '%s<%s>' % (pointer_type, data_type) | 273 if pointer_type: |
| 207 raise Exception('Unrecognized pointer type: "%s"' % pointer_type) | 274 return '{pointer_type}<{idl_type}>'.format(pointer_type=pointer_type, id l_type=idl_type) |
| 275 return idl_type + '*' # raw pointer | |
| 208 | 276 |
| 209 | 277 |
| 210 def v8_type(data_type): | 278 def v8_type(data_type): |
| 211 return 'V8' + data_type | 279 return 'V8' + data_type |
| 212 | 280 |
| 213 | 281 |
| 214 def cpp_method_name(attribute_or_operation): | 282 def cpp_method_name(attribute_or_operation): |
| 215 return attribute_or_operation.extended_attributes.get('ImplementedAs', attri bute_or_operation.name) | 283 return attribute_or_operation.extended_attributes.get('ImplementedAs', attri bute_or_operation.name) |
| 216 | 284 |
| 217 | 285 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 233 self.verbose = verbose | 301 self.verbose = verbose |
| 234 self.interface = None | 302 self.interface = None |
| 235 self.header_includes = set() | 303 self.header_includes = set() |
| 236 self.cpp_includes = set() | 304 self.cpp_includes = set() |
| 237 if definitions: # FIXME: remove check when remove write_dummy_header_an d_cpp | 305 if definitions: # FIXME: remove check when remove write_dummy_header_an d_cpp |
| 238 try: | 306 try: |
| 239 self.interface = definitions.interfaces[interface_name] | 307 self.interface = definitions.interfaces[interface_name] |
| 240 except KeyError: | 308 except KeyError: |
| 241 raise Exception('%s not in IDL definitions' % interface_name) | 309 raise Exception('%s not in IDL definitions' % interface_name) |
| 242 | 310 |
| 243 def generate_cpp_to_js_conversion(self, data_type, cpp_value, format_string, isolate, creation_context=''): | 311 def generate_cpp_to_v8_conversion(self, data_type, cpp_value, format_string, isolate, creation_context=''): |
| 244 """Returns a statement that converts a C++ value to a JS value. | 312 """Returns a statement that converts a C++ value to a V8 value. |
| 245 | 313 |
| 246 Also add necessary includes to self.cpp_includes. | 314 Also add necessary includes to self.cpp_includes. |
| 247 """ | 315 """ |
| 248 self.cpp_includes |= includes_for_type(data_type) | 316 self.cpp_includes |= includes_for_type(data_type) |
| 249 js_value = cpp_value_to_js_value(data_type, cpp_value, isolate, creation _context) | 317 v8_value = cpp_value_to_v8_value(data_type, cpp_value, isolate, creation _context) |
| 250 return format_string % js_value | 318 return format_string % v8_value |
| 251 | 319 |
| 252 def write_dummy_header_and_cpp(self): | 320 def write_dummy_header_and_cpp(self): |
| 253 # FIXME: fix GYP so these files aren't needed and remove this method | 321 # FIXME: fix GYP so these files aren't needed and remove this method |
| 254 target_interface_name = self.interface_name | 322 target_interface_name = self.interface_name |
| 255 header_basename = 'V8%s.h' % target_interface_name | 323 header_basename = 'V8%s.h' % target_interface_name |
| 256 cpp_basename = 'V8%s.cpp' % target_interface_name | 324 cpp_basename = 'V8%s.cpp' % target_interface_name |
| 257 contents = """/* | 325 contents = """/* |
| 258 This file is generated just to tell build scripts that {header_basename} and | 326 This file is generated just to tell build scripts that {header_basename} and |
| 259 {cpp_basename} are created for {target_interface_name}.idl, and thus | 327 {cpp_basename} are created for {target_interface_name}.idl, and thus |
| 260 prevent the build scripts from trying to generate {header_basename} and | 328 prevent the build scripts from trying to generate {header_basename} and |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 285 header_filename = os.path.join(self.output_directory, header_basename) | 353 header_filename = os.path.join(self.output_directory, header_basename) |
| 286 with open(header_filename, 'w') as header_file: | 354 with open(header_filename, 'w') as header_file: |
| 287 header_file.write(header_file_text) | 355 header_file.write(header_file_text) |
| 288 | 356 |
| 289 def write_cpp_code(self, cpp_basename, cpp_file_text): | 357 def write_cpp_code(self, cpp_basename, cpp_file_text): |
| 290 cpp_filename = os.path.join(self.output_directory, cpp_basename) | 358 cpp_filename = os.path.join(self.output_directory, cpp_basename) |
| 291 with open(cpp_filename, 'w') as cpp_file: | 359 with open(cpp_filename, 'w') as cpp_file: |
| 292 cpp_file.write(cpp_file_text) | 360 cpp_file.write(cpp_file_text) |
| 293 | 361 |
| 294 def generate_attribute(self, attribute): | 362 def generate_attribute(self, attribute): |
| 295 self.cpp_includes |= includes_for_type(attribute.data_type) | 363 data_type = attribute.data_type |
| 364 # FIXME: need to check should_keep_attribute_alive, but for now | |
| 365 # sufficient to check if primitive. | |
| 366 should_keep_attribute_alive = not primitive_type(data_type) | |
| 367 if should_keep_attribute_alive: | |
| 368 return_v8_value_statement = None # unused | |
| 369 self.cpp_includes |= includes_for_type(data_type) | |
| 370 self.cpp_includes.add('bindings/v8/V8HiddenPropertyName.h') | |
| 371 else: | |
| 372 cpp_value = 'imp->%s()' % uncapitalize(attribute.name) | |
| 373 return_v8_value_statement = v8_set_return_value(data_type, cpp_value , callback_info='info') | |
| 296 return { | 374 return { |
| 297 'name': attribute.name, | 375 'name': attribute.name, |
| 298 'conditional_string': generate_conditional_string(attribute), | 376 'conditional_string': generate_conditional_string(attribute), |
| 299 'cpp_method_name': cpp_method_name(attribute), | 377 'cpp_method_name': cpp_method_name(attribute), |
| 300 'cpp_type': cpp_type(attribute.data_type, pointer_type='RefPtr'), | 378 'cpp_type': cpp_type(data_type, pointer_type='RefPtr'), |
| 301 'v8_type': v8_type(attribute.data_type), | 379 'should_keep_attribute_alive': should_keep_attribute_alive, |
| 380 'return_v8_value_statement': return_v8_value_statement, | |
| 381 'v8_type': v8_type(data_type), | |
| 302 } | 382 } |
| 303 | 383 |
| 304 def generate_interface(self): | 384 def generate_interface(self): |
| 305 self.header_includes = INTERFACE_H_INCLUDES | 385 self.header_includes = INTERFACE_H_INCLUDES |
| 306 self.header_includes |= includes_for_cpp_class(cpp_class_name(self.inter face), self.relative_dir_posix) | 386 self.header_includes |= includes_for_cpp_class(cpp_class_name(self.inter face), self.relative_dir_posix) |
| 307 self.cpp_includes = INTERFACE_CPP_INCLUDES | 387 self.cpp_includes = INTERFACE_CPP_INCLUDES |
| 308 | 388 |
| 309 template_contents = { | 389 template_contents = { |
| 310 'interface_name': self.interface.name, | 390 'interface_name': self.interface.name, |
| 311 'cpp_class_name': cpp_class_name(self.interface), | 391 'cpp_class_name': cpp_class_name(self.interface), |
| 312 'v8_class_name': v8_class_name(self.interface), | 392 'v8_class_name': v8_class_name(self.interface), |
| 313 'attributes': [self.generate_attribute(attribute) for attribute in s elf.interface.attributes], | 393 'attributes': [self.generate_attribute(attribute) for attribute in s elf.interface.attributes], |
| 314 # Size 0 constant array is not allowed in VC++ | 394 # Size 0 constant array is not allowed in VC++ |
| 315 'number_of_attributes': 'WTF_ARRAY_LENGTH(%sAttributes)' % v8_class_ name(self.interface) if self.interface.attributes else '0', | 395 'number_of_attributes': 'WTF_ARRAY_LENGTH(%sAttributes)' % v8_class_ name(self.interface) if self.interface.attributes else '0', |
| 316 'attribute_templates': v8_class_name(self.interface) + 'Attributes' if self.interface.attributes else '0', | 396 'attribute_templates': v8_class_name(self.interface) + 'Attributes' if self.interface.attributes else '0', |
| 317 } | 397 } |
| 398 template_contents['constants'] = generate_constants(self.interface) | |
| 318 # Add includes afterwards, as they are modified by generate_attribute et c. | 399 # Add includes afterwards, as they are modified by generate_attribute et c. |
| 319 template_contents['header_includes'] = sorted(list(self.header_includes) ) | 400 template_contents['header_includes'] = sorted(list(self.header_includes) ) |
| 320 template_contents['cpp_includes'] = sorted(list(self.cpp_includes)) | 401 template_contents['cpp_includes'] = sorted(list(self.cpp_includes)) |
| 321 return template_contents | 402 return template_contents |
| 322 | 403 |
| 323 def generate_callback_interface(self): | 404 def generate_callback_interface(self): |
| 324 self.header_includes = CALLBACK_INTERFACE_H_INCLUDES | 405 self.header_includes = CALLBACK_INTERFACE_H_INCLUDES |
| 325 self.header_includes |= includes_for_cpp_class(cpp_class_name(self.inter face), self.relative_dir_posix) | 406 self.header_includes |= includes_for_cpp_class(cpp_class_name(self.inter face), self.relative_dir_posix) |
| 326 self.cpp_includes = CALLBACK_INTERFACE_CPP_INCLUDES | 407 self.cpp_includes = CALLBACK_INTERFACE_CPP_INCLUDES |
| 327 | 408 |
| 328 def generate_argument(argument): | 409 def generate_argument(argument): |
| 329 receiver = 'v8::Handle<v8::Value> %sHandle = %%s;' % argument.name | 410 receiver = 'v8::Handle<v8::Value> %sHandle = %%s;' % argument.name |
| 330 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>()') | 411 cpp_to_v8_conversion = self.generate_cpp_to_v8_conversion(argument.d ata_type, argument.name, receiver, 'isolate', creation_context='v8::Handle<v8::O bject>()') |
| 331 return { | 412 return { |
| 332 'name': argument.name, | 413 'name': argument.name, |
| 333 'cpp_to_js_conversion': cpp_to_js_conversion, | 414 'cpp_to_v8_conversion': cpp_to_v8_conversion, |
| 334 } | 415 } |
| 335 | 416 |
| 336 def generate_method(operation): | 417 def generate_method(operation): |
| 337 def argument_declaration(argument): | 418 def argument_declaration(argument): |
| 338 return '%s %s' % (cpp_type(argument.data_type, 'raw'), argument. name) | 419 return '%s %s' % (cpp_type(argument.data_type), argument.name) |
| 339 | 420 |
| 340 arguments = [] | 421 arguments = [] |
| 341 custom = 'Custom' in operation.extended_attributes | 422 custom = 'Custom' in operation.extended_attributes |
| 342 if not custom: | 423 if not custom: |
| 343 self.cpp_includes |= includes_for_operation(operation) | 424 self.cpp_includes |= includes_for_operation(operation) |
| 344 if operation.data_type != 'boolean': | 425 if operation.data_type != 'boolean': |
| 345 raise Exception("We don't yet support callbacks that return non-boolean values.") | 426 raise Exception("We don't yet support callbacks that return non-boolean values.") |
| 346 arguments = [generate_argument(argument) for argument in operati on.arguments] | 427 arguments = [generate_argument(argument) for argument in operati on.arguments] |
| 347 method = { | 428 method = { |
| 348 'return_cpp_type': cpp_type(operation.data_type, 'RefPtr'), | 429 'return_cpp_type': cpp_type(operation.data_type, 'RefPtr'), |
| 349 'name': operation.name, | 430 'name': operation.name, |
| 350 'arguments': arguments, | 431 'arguments': arguments, |
| 351 'argument_declaration': ', '.join([argument_declaration(argument ) for argument in operation.arguments]), | 432 'argument_declaration': ', '.join([argument_declaration(argument ) for argument in operation.arguments]), |
| 352 'handles': ', '.join(['%sHandle' % argument.name for argument in operation.arguments]), | 433 'handles': ', '.join(['%sHandle' % argument.name for argument in operation.arguments]), |
| 353 'custom': custom, | 434 'custom': custom, |
| 354 } | 435 } |
| 355 return method | 436 return method |
| 356 | 437 |
| 357 methods = [generate_method(operation) for operation in self.interface.op erations] | 438 methods = [generate_method(operation) for operation in self.interface.op erations] |
| 358 template_contents = { | 439 template_contents = { |
| 359 'cpp_class_name': self.interface.name, | 440 'cpp_class_name': self.interface.name, |
| 360 'v8_class_name': v8_class_name(self.interface), | 441 'v8_class_name': v8_class_name(self.interface), |
| 361 'cpp_includes': sorted(list(self.cpp_includes)), | 442 'cpp_includes': sorted(list(self.cpp_includes)), |
| 362 'header_includes': sorted(list(self.header_includes)), | 443 'header_includes': sorted(list(self.header_includes)), |
| 363 'methods': methods, | 444 'methods': methods, |
| 364 } | 445 } |
| 365 return template_contents | 446 return template_contents |
| OLD | NEW |