Chromium Code Reviews| 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): |