Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: Source/bindings/scripts/code_generator_v8.py

Issue 19607011: Generate binding code for VoidCallback.idl with code generator in python (Closed) Base URL: https://chromium.googlesource.com/chromium/blink@master
Patch Set: smaller Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
47
48
49 def apply_template(path_to_template, contents):
50 dirname, basename = os.path.split(path_to_template)
51 jinja_env = jinja2.Environment(trim_blocks=True, loader=jinja2.FileSystemLoa der([dirname]))
52 template = jinja_env.get_template(basename)
53 return template.render(contents)
54
55
56 def v8_class_name(interface):
57 return 'V8' + interface.name
58
59
60 def cpp_class_name(interface_or_function):
haraken 2013/07/26 07:47:11 interface_or_function => interface (or interface_o
do-not-use 2013/07/26 07:55:41 The naming cpp_class_name() only makes sense if th
kojih 2013/07/26 10:04:31 This function will return [ImplementedAs] value or
61 return interface_or_function.name
62
63
64 def cpp_type(data_type):
65 """Returns the cpp type corresponds to the IDL type."""
haraken 2013/07/26 07:47:11 Nit: corresponds => corresponding
Nils Barth (inactive) 2013/07/26 10:27:47 cpp → C++ (Only need cpp in variable names, not co
66 if data_type == 'boolean':
67 return 'bool'
68 raise Exception('Not supported')
69
70
71 def callback_argument_declaration(operation):
72 parameters = ['%s %s' % (cpp_type(parameter.data_type), parameter.name) for parameter in operation.arguments]
haraken 2013/07/26 07:47:11 Did you decide to use "argument" in the IDL side a
kojih 2013/07/26 10:04:31 ok I'll use 'argument' also in C++.
Nils Barth (inactive) 2013/07/26 10:27:47 This function's names + signature is weird: usuall
73 return ', '.join(parameters)
74
75
76 class CodeGeneratorV8:
77 def __init__(self, definitions, interface_name, output_directory, idl_direct ories, verbose=False):
78 self.idl_definitions = definitions
79 self.interface_name = interface_name
80 self.idl_directories = idl_directories
81 self.output_directory = output_directory
82 self.verbose = verbose
83 self.header_file_text = ''
84 self.cpp_file_text = ''
haraken 2013/07/26 07:47:11 Do you need to make these instance variables?
kojih 2013/07/26 10:04:31 No, made those local variables.
Nils Barth (inactive) 2013/07/26 10:27:47 Agreed, these should just be local variables in ge
85 self.interface = None
86
87 def cpp_class_header(self):
haraken 2013/07/26 07:47:11 Nit: cpp_class_header_filename ?
kojih 2013/07/26 10:04:31 done.
Nils Barth (inactive) 2013/07/26 10:27:47 In fact, how about putting this in __init__ as wel
kojih 2013/07/29 03:43:21 I'd like to leave this part as it is. Because I th
Nils Barth (inactive) 2013/07/29 04:11:09 Got it -- once we compute the path name in the par
88 """Returns relative path from bindings/ of webcore header of the interfa ce"""
89 # FIXME: parser will prepare posix form relative path from Source/bindin gs in IdlInterface.file_name
Nils Barth (inactive) 2013/07/26 10:27:47 Exactly. I'll probably call it IdlInterface.rel_pa
90 idl_filename = self.idl_definitions.file_name
91 idl_rel_path_local = os.path.relpath(idl_filename)
92 idl_rel_path_posix = idl_rel_path_local.replace(os.path.sep, posixpath.s ep)
93
94 idl_dir_posix = posixpath.join('bindings', posixpath.dirname(idl_rel_pat h_posix))
95 return posixpath.join(idl_dir_posix, cpp_class_name(self.interface) + '. h')
Nils Barth (inactive) 2013/07/26 10:27:47 self.interface_name instead of cpp_class_name(self
96
97 def generate_header_and_cpp(self):
Nils Barth (inactive) 2013/07/26 10:27:47 Shall we call this (and the generate_dummy functio
kojih 2013/07/29 03:43:21 ok.
98 if self.interface_name not in self.idl_definitions.interfaces:
99 raise Exception('%s not in IDL definitions' % self.interface_name)
100 self.interface = self.idl_definitions.interfaces[self.interface_name]
haraken 2013/07/26 07:47:11 How about moving these 3 lines into __init__ ?
kojih 2013/07/26 10:04:31 done.
101 if self.interface.is_callback:
102 template_contents = {}
103 template_contents.update(self.generate_callback_functions())
Nils Barth (inactive) 2013/07/26 10:27:47 How about: template_contents = self.generate_callb
kojih 2013/07/29 03:43:21 done. (but I'll use template_contents.update again
104 self.header_file_text = apply_template('templates/callback.h', templ ate_contents)
105 self.cpp_file_text = apply_template('templates/callback.cpp', templa te_contents)
106 else:
107 # FIXME: Implement.
108 self.header_file_text = ""
109 self.cpp_file_text = ""
110 header_filename = os.path.join(self.output_directory, v8_class_name(self .interface) + '.h')
haraken 2013/07/26 07:47:11 You might want to factor out the code to write_gen
kojih 2013/07/26 10:04:31 done.
Nils Barth (inactive) 2013/07/26 10:27:47 BTW, this is clearest as nested functions at the t
111 with open(header_filename, 'w') as header_file:
112 header_file.write(self.header_file_text)
113 cpp_filename = os.path.join(self.output_directory, v8_class_name(self.in terface) + '.cpp')
114 with open(cpp_filename, 'w') as cpp_file:
115 cpp_file.write(self.cpp_file_text)
116
117 def generate_callback_functions(self):
haraken 2013/07/26 07:47:11 generate_callback_functions => generate_callback_i
kojih 2013/07/26 10:04:31 done.
118 methods = []
Nils Barth (inactive) 2013/07/26 10:27:47 I'd put methods = [] *directly* before the loop: t
kojih 2013/07/29 03:43:21 I agree, I think list comprehension has a good poi
119 cpp_includes = set([
120 'core/dom/ScriptExecutionContext.h',
121 'bindings/v8/V8Binding.h',
122 'bindings/v8/V8Callback.h',
123 'wtf/Assertions.h',
124 ])
125 header_includes = set([
126 'bindings/v8/ActiveDOMCallback.h',
127 'bindings/v8/DOMWrapperWorld.h',
128 'bindings/v8/ScopedPersistent.h',
129 ])
130 header_includes.add(self.cpp_class_header())
131 for operation in self.interface.operations:
132 custom = 'Custom' in operation.extended_attributes
haraken 2013/07/26 07:47:11 Remove this.
133 method = {}
134 if 'Custom' not in operation.extended_attributes:
135 if operation.data_type != 'boolean':
136 raise Exception("We don't yet support callbacks that return non-boolean values.")
137 if len(operation.arguments):
138 raise Exception('Not supported')
139 method = {
140 'return_type': cpp_type(operation.data_type),
haraken 2013/07/26 07:47:11 nbarth: Probably do you want to rename operation.d
Nils Barth (inactive) 2013/07/26 10:27:47 Good point. Will do (in followup).
141 'name': operation.name,
142 'parameter_declaration': callback_argument_declaration(opera tion),
143 'custom': custom,
haraken 2013/07/26 07:47:11 'custom': None
144 }
145 methods.append(method)
146 template_contents = {
147 'cpp_class_name': cpp_class_name(self.interface),
Nils Barth (inactive) 2013/07/26 10:27:47 self.interface_name?
148 'v8_class_name': v8_class_name(self.interface),
Nils Barth (inactive) 2013/07/26 10:27:47 'V8' + self.interface_name ?
149 'cpp_includes': sorted(list(cpp_includes)),
150 'header_includes': sorted(list(header_includes)),
151 'methods': methods,
152 }
153 return template_contents
39 154
40 155
41 def generate_dummy_header_and_cpp(target_interface_name, output_directory): 156 def generate_dummy_header_and_cpp(target_interface_name, output_directory):
42 header_basename = 'V8%s.h' % target_interface_name 157 header_basename = 'V8%s.h' % target_interface_name
43 cpp_basename = 'V8%s.cpp' % target_interface_name 158 cpp_basename = 'V8%s.cpp' % target_interface_name
44 header_fullname = os.path.join(output_directory, header_basename) 159 header_fullname = os.path.join(output_directory, header_basename)
45 cpp_fullname = os.path.join(output_directory, cpp_basename) 160 cpp_fullname = os.path.join(output_directory, cpp_basename)
46 contents = """/* 161 contents = """/*
47 This file is generated just to tell build scripts that {header_basename} and 162 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 163 {cpp_basename} are created for {target_interface_name}.idl, and thus
49 prevent the build scripts from trying to generate {header_basename} and 164 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. 165 {cpp_basename} at every build. This file must not be tried to compile.
51 */ 166 */
52 """.format(**locals()) 167 """.format(**locals())
53 with open(header_fullname, 'w') as header_file: 168 with open(header_fullname, 'w') as header_file:
54 header_file.write(contents) 169 header_file.write(contents)
55 with open(cpp_fullname, 'w') as cpp_file: 170 with open(cpp_fullname, 'w') as cpp_file:
56 cpp_file.write(contents) 171 cpp_file.write(contents)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698