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

Unified 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, 5 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 side-by-side diff with in-line comments
Download patch
Index: Source/bindings/scripts/code_generator_v8.py
diff --git a/Source/bindings/scripts/code_generator_v8.py b/Source/bindings/scripts/code_generator_v8.py
index d2f933044a5a171b5f1109ef2dc94fa95f660842..1dd1a8d598e696fd19458fd482b1e27130fe7b85 100644
--- a/Source/bindings/scripts/code_generator_v8.py
+++ b/Source/bindings/scripts/code_generator_v8.py
@@ -30,12 +30,127 @@
Input: An object of class IdlDefinitions, containing an IDL interface X
Output: V8X.h and V8X.cpp
-
-FIXME: Currently a stub, as part of landing the parser and code generator
-incrementally. Only implements generation of dummy .cpp and .h files.
"""
-import os.path
+import os
+import posixpath
+import re
+import sys
+
+import idl_definitions
+
+# jinja2 is in chromium's third_party directory.
+module_path, module_name = os.path.split(__file__)
+third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir)
+sys.path.append(third_party)
+import jinja2
+
+
+def apply_template(path_to_template, contents):
+ dirname, basename = os.path.split(path_to_template)
+ jinja_env = jinja2.Environment(trim_blocks=True, loader=jinja2.FileSystemLoader([dirname]))
+ template = jinja_env.get_template(basename)
+ return template.render(contents)
+
+
+def v8_class_name(interface):
+ return 'V8' + interface.name
+
+
+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
+ return interface_or_function.name
+
+
+def cpp_type(data_type):
+ """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
+ if data_type == 'boolean':
+ return 'bool'
+ raise Exception('Not supported')
+
+
+def callback_argument_declaration(operation):
+ 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
+ return ', '.join(parameters)
+
+
+class CodeGeneratorV8:
+ def __init__(self, definitions, interface_name, output_directory, idl_directories, verbose=False):
+ self.idl_definitions = definitions
+ self.interface_name = interface_name
+ self.idl_directories = idl_directories
+ self.output_directory = output_directory
+ self.verbose = verbose
+ self.header_file_text = ''
+ 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
+ self.interface = None
+
+ 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
+ """Returns relative path from bindings/ of webcore header of the interface"""
+ # FIXME: parser will prepare posix form relative path from Source/bindings in IdlInterface.file_name
Nils Barth (inactive) 2013/07/26 10:27:47 Exactly. I'll probably call it IdlInterface.rel_pa
+ idl_filename = self.idl_definitions.file_name
+ idl_rel_path_local = os.path.relpath(idl_filename)
+ idl_rel_path_posix = idl_rel_path_local.replace(os.path.sep, posixpath.sep)
+
+ idl_dir_posix = posixpath.join('bindings', posixpath.dirname(idl_rel_path_posix))
+ 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
+
+ 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.
+ if self.interface_name not in self.idl_definitions.interfaces:
+ raise Exception('%s not in IDL definitions' % self.interface_name)
+ 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.
+ if self.interface.is_callback:
+ template_contents = {}
+ 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
+ self.header_file_text = apply_template('templates/callback.h', template_contents)
+ self.cpp_file_text = apply_template('templates/callback.cpp', template_contents)
+ else:
+ # FIXME: Implement.
+ self.header_file_text = ""
+ self.cpp_file_text = ""
+ 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
+ with open(header_filename, 'w') as header_file:
+ header_file.write(self.header_file_text)
+ cpp_filename = os.path.join(self.output_directory, v8_class_name(self.interface) + '.cpp')
+ with open(cpp_filename, 'w') as cpp_file:
+ cpp_file.write(self.cpp_file_text)
+
+ 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.
+ 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
+ cpp_includes = set([
+ 'core/dom/ScriptExecutionContext.h',
+ 'bindings/v8/V8Binding.h',
+ 'bindings/v8/V8Callback.h',
+ 'wtf/Assertions.h',
+ ])
+ header_includes = set([
+ 'bindings/v8/ActiveDOMCallback.h',
+ 'bindings/v8/DOMWrapperWorld.h',
+ 'bindings/v8/ScopedPersistent.h',
+ ])
+ header_includes.add(self.cpp_class_header())
+ for operation in self.interface.operations:
+ custom = 'Custom' in operation.extended_attributes
haraken 2013/07/26 07:47:11 Remove this.
+ method = {}
+ if 'Custom' not in operation.extended_attributes:
+ if operation.data_type != 'boolean':
+ raise Exception("We don't yet support callbacks that return non-boolean values.")
+ if len(operation.arguments):
+ raise Exception('Not supported')
+ method = {
+ '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).
+ 'name': operation.name,
+ 'parameter_declaration': callback_argument_declaration(operation),
+ 'custom': custom,
haraken 2013/07/26 07:47:11 'custom': None
+ }
+ methods.append(method)
+ template_contents = {
+ 'cpp_class_name': cpp_class_name(self.interface),
Nils Barth (inactive) 2013/07/26 10:27:47 self.interface_name?
+ 'v8_class_name': v8_class_name(self.interface),
Nils Barth (inactive) 2013/07/26 10:27:47 'V8' + self.interface_name ?
+ 'cpp_includes': sorted(list(cpp_includes)),
+ 'header_includes': sorted(list(header_includes)),
+ 'methods': methods,
+ }
+ return template_contents
def generate_dummy_header_and_cpp(target_interface_name, output_directory):

Powered by Google App Engine
This is Rietveld 408576698