OLD | NEW |
| (Empty) |
1 #!/usr/bin/python | |
2 # Copyright (C) 2010 Google Inc. All rights reserved. | |
3 # | |
4 # Redistribution and use in source and binary forms, with or without | |
5 # modification, are permitted provided that the following conditions | |
6 # are met: | |
7 # 1. Redistributions of source code must retain the above copyright | |
8 # notice, this list of conditions and the following disclaimer. | |
9 # 2. Redistributions in binary form must reproduce the above copyright | |
10 # notice, this list of conditions and the following disclaimer in the | |
11 # documentation and/or other materials provided with the distribution. | |
12 # | |
13 # THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | |
14 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
15 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
16 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | |
17 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
18 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
19 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
20 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
21 # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
22 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
23 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
24 # | |
25 | |
26 import traceback | |
27 | |
28 import fnmatch | |
29 from optparse import OptionParser | |
30 import os | |
31 import shutil | |
32 import sys | |
33 import tempfile | |
34 | |
35 import compute_interfaces_info_individual | |
36 from compute_interfaces_info_individual import compute_info_individual, info_ind
ividual | |
37 import compute_interfaces_info_overall | |
38 from compute_interfaces_info_overall import compute_interfaces_info_overall, int
erfaces_info | |
39 from compiler import IdlCompilerDart | |
40 | |
41 # TODO(terry): Temporary solution list of IDLs to parse and IDL as dependencies. | |
42 from idl_files import full_path_core_idl_files,\ | |
43 full_path_core_dependency_idl_files,\ | |
44 full_path_modules_idl_files,\ | |
45 full_path_modules_dependency_idl_files,\ | |
46 full_path_core_dictionary_idl_files,\ | |
47 full_path_modules_dictionary_idl_files | |
48 | |
49 #from dart_tests import run_dart_tests | |
50 | |
51 | |
52 EXTENDED_ATTRIBUTES_FILE = 'bindings/IDLExtendedAttributes.txt' | |
53 | |
54 idl_compiler = None | |
55 | |
56 | |
57 def parse_options(): | |
58 parser = OptionParser() | |
59 | |
60 parser.add_option("--output-directory", | |
61 action="store", | |
62 type="string", | |
63 dest="output_directory", | |
64 help="Generate output to a known directory") | |
65 parser.add_option("-v", "--verbose", | |
66 action="store_true", | |
67 dest="verbose", | |
68 default=False, | |
69 help="Show all information messages") | |
70 parser.add_option("-k", "--keep", | |
71 action="store_true", | |
72 dest="keep", | |
73 default=False, | |
74 help="Don't delete the temporary directory on exit") | |
75 parser.add_option("--compute-idls", type='int', help="Compile IDLs interface
s and dependencies (GYP)") | |
76 parser.add_option('--globals-only', type='int', help="Generate the globals") | |
77 | |
78 options, args = parser.parse_args() | |
79 | |
80 options.compute_idls = bool(options.compute_idls) | |
81 options.globals_only = bool(options.globals_only) | |
82 | |
83 return options | |
84 | |
85 | |
86 class ScopedTempFileProvider(object): | |
87 def __init__(self, keep=False): | |
88 self.keep = keep | |
89 self.dir_paths = [] | |
90 | |
91 def __enter__(self): | |
92 return self | |
93 | |
94 def __exit__(self, exc_type, exc_value, traceback): | |
95 if not self.keep: | |
96 for dir_path in self.dir_paths: | |
97 # Temporary directories are used as output directories, so they | |
98 # contains unknown files (they aren't empty), hence use rmtree | |
99 shutil.rmtree(dir_path) | |
100 | |
101 def new_temp_dir(self): | |
102 dir_path = tempfile.mkdtemp() | |
103 self.dir_paths.append(dir_path) | |
104 return dir_path | |
105 | |
106 | |
107 class DirectoryProvider(object): | |
108 def __init__(self, path=""): | |
109 self.dir_path = path | |
110 | |
111 def __enter__(self): | |
112 return self | |
113 | |
114 def new_temp_dir(self): | |
115 return self.dir_path | |
116 | |
117 | |
118 def idl_paths_recursive(directory): | |
119 idl_paths = [] | |
120 for dirpath, _, files in os.walk(directory): | |
121 idl_paths.extend(os.path.join(dirpath, filename) | |
122 for filename in fnmatch.filter(files, '*.idl')) | |
123 return idl_paths | |
124 | |
125 | |
126 class Build(): | |
127 def __init__(self, provider): | |
128 self.output_directory = provider.new_temp_dir() | |
129 | |
130 attrib_file = os.path.join('Source', EXTENDED_ATTRIBUTES_FILE) | |
131 # Create compiler. | |
132 self.idl_compiler = IdlCompilerDart(self.output_directory, | |
133 attrib_file, | |
134 interfaces_info=interfaces_info, | |
135 only_if_changed=True) | |
136 | |
137 def format_exception(self, e): | |
138 exception_list = traceback.format_stack() | |
139 exception_list = exception_list[:-2] | |
140 exception_list.extend(traceback.format_tb(sys.exc_info()[2])) | |
141 exception_list.extend(traceback.format_exception_only(sys.exc_info()[0],
sys.exc_info()[1])) | |
142 | |
143 exception_str = "Traceback (most recent call last):\n" | |
144 exception_str += "".join(exception_list) | |
145 # Removing the last \n | |
146 exception_str = exception_str[:-1] | |
147 | |
148 return exception_str | |
149 | |
150 def generate_from_idl(self, idl_file): | |
151 try: | |
152 idl_file_fullpath = os.path.realpath(idl_file) | |
153 self.idl_compiler.compile_file(idl_file_fullpath) | |
154 except Exception as err: | |
155 print 'ERROR: idl_compiler.py: ' + os.path.basename(idl_file) | |
156 print err | |
157 print | |
158 print 'Stack Dump:' | |
159 print self.format_exception(err) | |
160 | |
161 return 1 | |
162 | |
163 def generate_global(self): | |
164 try: | |
165 self.idl_compiler.generate_global() | |
166 except Exception as err: | |
167 print 'ERROR: idl_compiler.py generate global' | |
168 print err | |
169 print | |
170 print 'Stack Dump:' | |
171 print self.format_exception(err) | |
172 | |
173 return 1 | |
174 | |
175 return 0 | |
176 | |
177 | |
178 def main(argv): | |
179 ''' | |
180 Runs Dart IDL code generator; IDL files. IDL files same as GYP files in | |
181 Source/bindings/core/core.gypi and Source/bindings/modules/modules.gypi (see | |
182 idl_files.py on list of files). | |
183 | |
184 To run the PYTHONPATH should have the directories: | |
185 | |
186 Source/bindings/scripts | |
187 Source/bindings/scripts/dart | |
188 ''' | |
189 | |
190 options = parse_options() | |
191 | |
192 if options.compute_idls: | |
193 # TODO(terry): Assumes CWD is third_party/WebKit so any call to | |
194 # full_path_NNNN is prefixing 'Source/core' to path. | |
195 core_idls = full_path_core_idl_files() | |
196 core_dependency_idls = full_path_core_dependency_idl_files() | |
197 modules_idls = full_path_modules_idl_files() | |
198 modules_dependency_idls = full_path_modules_dependency_idl_files() | |
199 core_dictionary_idls = full_path_core_dictionary_idl_files() | |
200 modules_dictionary_idls = full_path_modules_dictionary_idl_files() | |
201 | |
202 all_interfaces = core_idls + modules_idls | |
203 all_dependencies = core_dependency_idls + modules_dependency_idls | |
204 all_dictionaries = core_dictionary_idls + modules_dictionary_idls | |
205 all_files = all_interfaces + all_dependencies + all_dictionaries | |
206 | |
207 # 2-stage computation: individual, then overall | |
208 for idl_filename in all_files: | |
209 compute_info_individual(idl_filename) | |
210 info_individuals = [info_individual()] | |
211 compute_interfaces_info_overall(info_individuals) | |
212 | |
213 # Compile just IDLs with interfaces (no dependencies). | |
214 if (options.output_directory == None): | |
215 with ScopedTempFileProvider(keep=options.keep) as provider: | |
216 build = Build(provider) | |
217 else: | |
218 provider = DirectoryProvider(path=options.output_directory) | |
219 build = Build(provider) | |
220 | |
221 if options.verbose and options.keep: | |
222 print 'Output directory %s created' % build.output_directory | |
223 | |
224 # Compile IDLs | |
225 for filename in (all_dictionaries + all_interfaces): | |
226 if not filename.endswith('.idl'): | |
227 continue | |
228 if build.generate_from_idl(filename): | |
229 return False | |
230 | |
231 if options.verbose: | |
232 print '%s IDLs with interfaces processed' % len(all_interfaces) | |
233 | |
234 if options.verbose and not options.keep: | |
235 print 'Output directory %s deleted' % build.output_directory | |
236 | |
237 if options.globals_only: | |
238 if (options.output_directory == None): | |
239 with ScopedTempFileProvider(keep=options.keep) as provider: | |
240 build = Build(provider) | |
241 else: | |
242 provider = DirectoryProvider(path=options.output_directory) | |
243 build = Build(provider) | |
244 | |
245 if options.verbose: | |
246 print 'Generating global...' | |
247 | |
248 build.generate_global() | |
249 | |
250 if options.verbose: | |
251 print 'Created DartWebkitClassIds .h/.cpp' | |
252 | |
253 | |
254 if __name__ == '__main__': | |
255 sys.exit(main(sys.argv)) | |
OLD | NEW |