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 12 matching lines...) Expand all Loading... |
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 | |
34 FIXME: Currently a stub, as part of landing the parser and code generator | |
35 incrementally. Only implements generation of dummy .cpp and .h files. | |
36 """ | 33 """ |
37 | 34 |
38 import os.path | 35 import os |
| 36 import posixpath |
| 37 import re |
| 38 import sys |
| 39 |
| 40 import idl_definitions |
| 41 |
| 42 # jinja2 is in chromium's third_party directory. |
| 43 module_path, module_name = os.path.split(__file__) |
| 44 third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pard
ir) |
| 45 sys.path.append(third_party) |
| 46 import jinja2 |
39 | 47 |
40 | 48 |
41 def generate_dummy_header_and_cpp(target_interface_name, output_directory): | 49 def apply_template(path_to_template, contents): |
42 header_basename = 'V8%s.h' % target_interface_name | 50 dirname, basename = os.path.split(path_to_template) |
43 cpp_basename = 'V8%s.cpp' % target_interface_name | 51 jinja_env = jinja2.Environment(trim_blocks=True, loader=jinja2.FileSystemLoa
der([dirname])) |
44 header_fullname = os.path.join(output_directory, header_basename) | 52 template = jinja_env.get_template(basename) |
45 cpp_fullname = os.path.join(output_directory, cpp_basename) | 53 return template.render(contents) |
46 contents = """/* | 54 |
| 55 |
| 56 def v8_class_name(interface): |
| 57 return 'V8' + interface.name |
| 58 |
| 59 |
| 60 def cpp_type(data_type): |
| 61 """Returns the C++ type corresponding to the IDL type.""" |
| 62 if data_type == 'boolean': |
| 63 return 'bool' |
| 64 raise Exception('Not supported') |
| 65 |
| 66 |
| 67 def callback_argument_declaration(operation): |
| 68 arguments = ['%s %s' % (cpp_type(argument.data_type), argument.name) for arg
ument in operation.arguments] |
| 69 return ', '.join(arguments) |
| 70 |
| 71 |
| 72 class CodeGeneratorV8: |
| 73 def __init__(self, definitions, interface_name, output_directory, idl_direct
ories, verbose=False): |
| 74 self.idl_definitions = definitions |
| 75 self.interface_name = interface_name |
| 76 self.idl_directories = idl_directories |
| 77 self.output_directory = output_directory |
| 78 self.verbose = verbose |
| 79 self.interface = None |
| 80 |
| 81 def cpp_class_header_filename(self): |
| 82 """Returns relative path from bindings/ of webcore header of the interfa
ce""" |
| 83 # FIXME: parser will prepare posix form relative path from Source/bindin
gs in IdlInterface.rel_path_posix |
| 84 idl_filename = self.idl_definitions.file_name |
| 85 idl_rel_path_local = os.path.relpath(idl_filename) |
| 86 idl_rel_path_posix = idl_rel_path_local.replace(os.path.sep, posixpath.s
ep) |
| 87 |
| 88 idl_dir_posix = posixpath.join('bindings', posixpath.dirname(idl_rel_pat
h_posix)) |
| 89 return posixpath.join(idl_dir_posix, self.interface.name + '.h') |
| 90 |
| 91 def write_dummy_header_and_cpp(self): |
| 92 target_interface_name = self.interface_name |
| 93 header_basename = 'V8%s.h' % target_interface_name |
| 94 cpp_basename = 'V8%s.cpp' % target_interface_name |
| 95 header_fullname = os.path.join(self.output_directory, header_basename) |
| 96 cpp_fullname = os.path.join(self.output_directory, cpp_basename) |
| 97 contents = """/* |
47 This file is generated just to tell build scripts that {header_basename} and | 98 This file is generated just to tell build scripts that {header_basename} and |
48 {cpp_basename} are created for {target_interface_name}.idl, and thus | 99 {cpp_basename} are created for {target_interface_name}.idl, and thus |
49 prevent the build scripts from trying to generate {header_basename} and | 100 prevent the build scripts from trying to generate {header_basename} and |
50 {cpp_basename} at every build. This file must not be tried to compile. | 101 {cpp_basename} at every build. This file must not be tried to compile. |
51 */ | 102 */ |
52 """.format(**locals()) | 103 """.format(**locals()) |
53 with open(header_fullname, 'w') as header_file: | 104 self.write_header_code(header_basename, contents) |
54 header_file.write(contents) | 105 self.write_cpp_code(cpp_basename, contents) |
55 with open(cpp_fullname, 'w') as cpp_file: | 106 |
56 cpp_file.write(contents) | 107 def write_header_and_cpp(self): |
| 108 if self.interface_name not in self.idl_definitions.interfaces: |
| 109 raise Exception('%s not in IDL definitions' % self.interface_name) |
| 110 self.interface = self.idl_definitions.interfaces[self.interface_name] |
| 111 header_basename = v8_class_name(self.interface) + '.h' |
| 112 cpp_basename = v8_class_name(self.interface) + '.cpp' |
| 113 if self.interface.is_callback: |
| 114 template_contents = self.generate_callback_interface() |
| 115 header_file_text = apply_template('templates/callback.h', template_c
ontents) |
| 116 cpp_file_text = apply_template('templates/callback.cpp', template_co
ntents) |
| 117 else: |
| 118 # FIXME: Implement. |
| 119 header_file_text = "" |
| 120 cpp_file_text = "" |
| 121 self.write_header_code(header_basename, header_file_text) |
| 122 self.write_cpp_code(cpp_basename, cpp_file_text) |
| 123 |
| 124 def write_header_code(self, header_basename, header_file_text): |
| 125 header_filename = os.path.join(self.output_directory, header_basename) |
| 126 with open(header_filename, 'w') as header_file: |
| 127 header_file.write(header_file_text) |
| 128 |
| 129 def write_cpp_code(self, cpp_basename, cpp_file_text): |
| 130 cpp_filename = os.path.join(self.output_directory, cpp_basename) |
| 131 with open(cpp_filename, 'w') as cpp_file: |
| 132 cpp_file.write(cpp_file_text) |
| 133 |
| 134 def generate_callback_interface(self): |
| 135 cpp_includes = set([ |
| 136 'core/dom/ScriptExecutionContext.h', |
| 137 'bindings/v8/V8Binding.h', |
| 138 'bindings/v8/V8Callback.h', |
| 139 'wtf/Assertions.h', |
| 140 ]) |
| 141 header_includes = set([ |
| 142 'bindings/v8/ActiveDOMCallback.h', |
| 143 'bindings/v8/DOMWrapperWorld.h', |
| 144 'bindings/v8/ScopedPersistent.h', |
| 145 ]) |
| 146 header_includes.add(self.cpp_class_header_filename()) |
| 147 |
| 148 def operation_to_method(operation): |
| 149 method = {} |
| 150 if 'Custom' not in operation.extended_attributes: |
| 151 if operation.data_type != 'boolean': |
| 152 raise Exception("We don't yet support callbacks that return
non-boolean values.") |
| 153 if len(operation.arguments): |
| 154 raise Exception('Not supported') |
| 155 method = { |
| 156 'return_type': cpp_type(operation.data_type), |
| 157 'name': operation.name, |
| 158 'arguments': [], |
| 159 'argument_declaration': callback_argument_declaration(operat
ion), |
| 160 'custom': None, |
| 161 } |
| 162 return method |
| 163 |
| 164 methods = [operation_to_method(operation) for operation in self.interfac
e.operations] |
| 165 template_contents = { |
| 166 'cpp_class_name': self.interface.name, |
| 167 'v8_class_name': v8_class_name(self.interface), |
| 168 'cpp_includes': sorted(list(cpp_includes)), |
| 169 'header_includes': sorted(list(header_includes)), |
| 170 'methods': methods, |
| 171 } |
| 172 return template_contents |
OLD | NEW |