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

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

Powered by Google App Engine
This is Rietveld 408576698