 Chromium Code Reviews
 Chromium Code Reviews Issue 23068032:
  Add constants and primitive type readonly attributes to Python IDL compiler  (Closed) 
  Base URL: svn://svn.chromium.org/blink/trunk
    
  
    Issue 23068032:
  Add constants and primitive type readonly attributes to Python IDL compiler  (Closed) 
  Base URL: svn://svn.chromium.org/blink/trunk| 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 |