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

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

Issue 429853002: IDL: Add build target for IDL dictionary impl generation in core (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 3 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 import idl_types 73 import idl_types
74 from idl_types import IdlType 74 from idl_types import IdlType
75 import v8_callback_interface 75 import v8_callback_interface
76 import v8_dictionary 76 import v8_dictionary
77 from v8_globals import includes, interfaces 77 from v8_globals import includes, interfaces
78 import v8_interface 78 import v8_interface
79 import v8_types 79 import v8_types
80 from v8_utilities import capitalize, cpp_name, conditional_string, v8_class_name 80 from v8_utilities import capitalize, cpp_name, conditional_string, v8_class_name
81 81
82 82
83 KNOWN_COMPONENTS = frozenset(['core', 'modules'])
84
85
83 def render_template(interface_info, header_template, cpp_template, 86 def render_template(interface_info, header_template, cpp_template,
84 template_context): 87 template_context):
85 template_context['code_generator'] = module_pyname 88 template_context['code_generator'] = module_pyname
86 89
87 # Add includes for any dependencies 90 # Add includes for any dependencies
88 template_context['header_includes'] = sorted( 91 template_context['header_includes'] = sorted(
89 template_context['header_includes']) 92 template_context['header_includes'])
90 includes.update(interface_info.get('dependencies_include_paths', [])) 93 includes.update(interface_info.get('dependencies_include_paths', []))
91 template_context['cpp_includes'] = sorted(includes) 94 template_context['cpp_includes'] = sorted(includes)
92 95
93 header_text = header_template.render(template_context) 96 header_text = header_template.render(template_context)
94 cpp_text = cpp_template.render(template_context) 97 cpp_text = cpp_template.render(template_context)
95 return header_text, cpp_text 98 return header_text, cpp_text
96 99
97 100
98 class CodeGeneratorV8(object): 101 class CodeGeneratorBase(object):
102 """Base class for v8 bindings generator and IDL dictionary impl generator"""
103
99 def __init__(self, interfaces_info, cache_dir, output_dir): 104 def __init__(self, interfaces_info, cache_dir, output_dir):
100 interfaces_info = interfaces_info or {} 105 interfaces_info = interfaces_info or {}
101 self.interfaces_info = interfaces_info 106 self.interfaces_info = interfaces_info
102 self.jinja_env = initialize_jinja_env(cache_dir) 107 self.jinja_env = initialize_jinja_env(cache_dir)
103 self.output_dir = output_dir 108 self.output_dir = output_dir
104 109
105 # Set global type info 110 # Set global type info
106 idl_types.set_ancestors(dict( 111 idl_types.set_ancestors(dict(
107 (interface_name, interface_info['ancestors']) 112 (interface_name, interface_info['ancestors'])
108 for interface_name, interface_info in interfaces_info.iteritems() 113 for interface_name, interface_info in interfaces_info.iteritems()
(...skipping 15 matching lines...) Expand all
124 for interface_name, interface_info in interfaces_info.iteritems() 129 for interface_name, interface_info in interfaces_info.iteritems()
125 if 'GarbageCollected' in interface_info['inherited_extended_attribut es'])) 130 if 'GarbageCollected' in interface_info['inherited_extended_attribut es']))
126 IdlType.set_will_be_garbage_collected_types(set( 131 IdlType.set_will_be_garbage_collected_types(set(
127 interface_name 132 interface_name
128 for interface_name, interface_info in interfaces_info.iteritems() 133 for interface_name, interface_info in interfaces_info.iteritems()
129 if 'WillBeGarbageCollected' in interface_info['inherited_extended_at tributes'])) 134 if 'WillBeGarbageCollected' in interface_info['inherited_extended_at tributes']))
130 v8_types.set_component_dirs(dict( 135 v8_types.set_component_dirs(dict(
131 (interface_name, interface_info['component_dir']) 136 (interface_name, interface_info['component_dir'])
132 for interface_name, interface_info in interfaces_info.iteritems())) 137 for interface_name, interface_info in interfaces_info.iteritems()))
133 138
134 def output_paths_for_bindings(self, definition_name): 139 def generate_code(self, definitions, definition_name):
140 """Returns .h/.cpp code as ((path, content)...)."""
141 # Set local type info
142 IdlType.set_callback_functions(definitions.callback_functions.keys())
143 IdlType.set_enums((enum.name, enum.values)
144 for enum in definitions.enumerations.values())
145 return self.generate_code_internal(definitions, definition_name)
146
147 def generate_code_internal(self, definitions, definition_name):
148 # This should be implemented in subclasses.
149 raise NotImplementedError()
150
151
152 class CodeGeneratorV8(CodeGeneratorBase):
153 def __init__(self, interfaces_info, cache_dir, output_dir):
154 CodeGeneratorBase.__init__(self, interfaces_info, cache_dir, output_dir)
155
156 def output_paths(self, definition_name):
135 header_path = posixpath.join(self.output_dir, 157 header_path = posixpath.join(self.output_dir,
136 'V8%s.h' % definition_name) 158 'V8%s.h' % definition_name)
137 cpp_path = posixpath.join(self.output_dir, 'V8%s.cpp' % definition_name) 159 cpp_path = posixpath.join(self.output_dir, 'V8%s.cpp' % definition_name)
138 return header_path, cpp_path 160 return header_path, cpp_path
139 161
140 def output_paths_for_impl(self, definition_name): 162 def generate_code_internal(self, definitions, definition_name):
141 header_path = posixpath.join(self.output_dir, '%s.h' % definition_name)
142 cpp_path = posixpath.join(self.output_dir, '%s.cpp' % definition_name)
143 return header_path, cpp_path
144
145 def generate_code(self, definitions, definition_name):
146 """Returns .h/.cpp code as (header_text, cpp_text)."""
147 # Set local type info
148 IdlType.set_callback_functions(definitions.callback_functions.keys())
149 IdlType.set_enums((enum.name, enum.values)
150 for enum in definitions.enumerations.values())
151
152 if definition_name in definitions.interfaces: 163 if definition_name in definitions.interfaces:
153 return self.generate_interface_code( 164 return self.generate_interface_code(
154 definitions, definition_name, 165 definitions, definition_name,
155 definitions.interfaces[definition_name]) 166 definitions.interfaces[definition_name])
156 if definition_name in definitions.dictionaries: 167 if definition_name in definitions.dictionaries:
157 return self.generate_dictionary_code( 168 return self.generate_dictionary_code(
158 definitions, definition_name, 169 definitions, definition_name,
159 definitions.dictionaries[definition_name]) 170 definitions.dictionaries[definition_name])
160 raise ValueError('%s is not in IDL definitions' % definition_name) 171 raise ValueError('%s is not in IDL definitions' % definition_name)
161 172
(...skipping 13 matching lines...) Expand all
175 header_template = self.jinja_env.get_template(header_template_filename) 186 header_template = self.jinja_env.get_template(header_template_filename)
176 cpp_template = self.jinja_env.get_template(cpp_template_filename) 187 cpp_template = self.jinja_env.get_template(cpp_template_filename)
177 188
178 interface_info = self.interfaces_info[interface_name] 189 interface_info = self.interfaces_info[interface_name]
179 190
180 template_context = interface_context(interface) 191 template_context = interface_context(interface)
181 # Add the include for interface itself 192 # Add the include for interface itself
182 template_context['header_includes'].add(interface_info['include_path']) 193 template_context['header_includes'].add(interface_info['include_path'])
183 header_text, cpp_text = render_template( 194 header_text, cpp_text = render_template(
184 interface_info, header_template, cpp_template, template_context) 195 interface_info, header_template, cpp_template, template_context)
185 header_path, cpp_path = self.output_paths_for_bindings(interface_name) 196 header_path, cpp_path = self.output_paths(interface_name)
186 return ( 197 return (
187 (header_path, header_text), 198 (header_path, header_text),
188 (cpp_path, cpp_text), 199 (cpp_path, cpp_text),
189 ) 200 )
190 201
191 def generate_dictionary_code(self, definitions, dictionary_name, 202 def generate_dictionary_code(self, definitions, dictionary_name,
192 dictionary): 203 dictionary):
193 interface_info = self.interfaces_info[dictionary_name]
194 bindings_results = self.generate_dictionary_bindings(
195 dictionary_name, interface_info, dictionary)
196 impl_results = self.generate_dictionary_impl(
197 dictionary_name, interface_info, dictionary)
198 return bindings_results + impl_results
199
200 def generate_dictionary_bindings(self, dictionary_name,
201 interface_info, dictionary):
202 header_template = self.jinja_env.get_template('dictionary_v8.h') 204 header_template = self.jinja_env.get_template('dictionary_v8.h')
203 cpp_template = self.jinja_env.get_template('dictionary_v8.cpp') 205 cpp_template = self.jinja_env.get_template('dictionary_v8.cpp')
204 template_context = v8_dictionary.dictionary_context(dictionary) 206 template_context = v8_dictionary.dictionary_context(dictionary)
207 interface_info = self.interfaces_info[dictionary_name]
205 # Add the include for interface itself 208 # Add the include for interface itself
206 template_context['header_includes'].add(interface_info['include_path']) 209 template_context['header_includes'].add(interface_info['include_path'])
207 header_text, cpp_text = render_template( 210 header_text, cpp_text = render_template(
208 interface_info, header_template, cpp_template, template_context) 211 interface_info, header_template, cpp_template, template_context)
209 header_path, cpp_path = self.output_paths_for_bindings(dictionary_name) 212 header_path, cpp_path = self.output_paths(dictionary_name)
210 return ( 213 return (
211 (header_path, header_text), 214 (header_path, header_text),
212 (cpp_path, cpp_text), 215 (cpp_path, cpp_text),
213 ) 216 )
214 217
215 def generate_dictionary_impl(self, dictionary_name, 218
216 interface_info, dictionary): 219 class CodeGeneratorDictionaryImpl(CodeGeneratorBase):
220 def __init__(self, interfaces_info, cache_dir, output_dir):
221 CodeGeneratorBase.__init__(self, interfaces_info, cache_dir, output_dir)
222
223 def output_paths(self, definition_name, interface_info):
224 if interface_info['component_dir'] in KNOWN_COMPONENTS:
225 output_dir = posixpath.join(self.output_dir,
226 interface_info['relative_dir'])
227 else:
228 output_dir = self.output_dir
229 header_path = posixpath.join(output_dir, '%s.h' % definition_name)
230 cpp_path = posixpath.join(output_dir, '%s.cpp' % definition_name)
231 return header_path, cpp_path
232
233 def generate_code_internal(self, definitions, definition_name):
234 if not definition_name in definitions.dictionaries:
235 raise ValueError('%s is not an IDL dictionary')
236 dictionary = definitions.dictionaries[definition_name]
237 interface_info = self.interfaces_info[definition_name]
217 header_template = self.jinja_env.get_template('dictionary_impl.h') 238 header_template = self.jinja_env.get_template('dictionary_impl.h')
218 cpp_template = self.jinja_env.get_template('dictionary_impl.cpp') 239 cpp_template = self.jinja_env.get_template('dictionary_impl.cpp')
219 template_context = v8_dictionary.dictionary_impl_context( 240 template_context = v8_dictionary.dictionary_impl_context(
220 dictionary, self.interfaces_info) 241 dictionary, self.interfaces_info)
221 header_text, cpp_text = render_template( 242 header_text, cpp_text = render_template(
222 interface_info, header_template, cpp_template, template_context) 243 interface_info, header_template, cpp_template, template_context)
223 header_path, cpp_path = self.output_paths_for_impl(dictionary_name) 244 header_path, cpp_path = self.output_paths(
245 definition_name, interface_info)
224 return ( 246 return (
225 (header_path, header_text), 247 (header_path, header_text),
226 (cpp_path, cpp_text), 248 (cpp_path, cpp_text),
227 ) 249 )
228 250
229 251
230 def initialize_jinja_env(cache_dir): 252 def initialize_jinja_env(cache_dir):
231 jinja_env = jinja2.Environment( 253 jinja_env = jinja2.Environment(
232 loader=jinja2.FileSystemLoader(templates_dir), 254 loader=jinja2.FileSystemLoader(templates_dir),
233 # Bytecode cache is not concurrency-safe unless pre-cached: 255 # Bytecode cache is not concurrency-safe unless pre-cached:
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 328
307 # Create a dummy file as output for the build system, 329 # Create a dummy file as output for the build system,
308 # since filenames of individual cache files are unpredictable and opaque 330 # since filenames of individual cache files are unpredictable and opaque
309 # (they are hashes of the template path, which varies based on environment) 331 # (they are hashes of the template path, which varies based on environment)
310 with open(dummy_filename, 'w') as dummy_file: 332 with open(dummy_filename, 'w') as dummy_file:
311 pass # |open| creates or touches the file 333 pass # |open| creates or touches the file
312 334
313 335
314 if __name__ == '__main__': 336 if __name__ == '__main__':
315 sys.exit(main(sys.argv)) 337 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « Source/bindings/scripts/aggregate_generated_bindings.py ('k') | Source/bindings/scripts/compute_interfaces_info_individual.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698