OLD | NEW |
1 # Copyright (C) 2011 Google Inc. All rights reserved. | 1 # Copyright (C) 2011 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 | 4 # modification, are permitted provided that the following conditions |
5 # are met: | 5 # are met: |
6 # 1. Redistributions of source code must retain the above copyright | 6 # 1. Redistributions of source code must retain the above copyright |
7 # notice, this list of conditions and the following disclaimer. | 7 # notice, this list of conditions and the following disclaimer. |
8 # 2. Redistributions in binary form must reproduce the above copyright | 8 # 2. Redistributions in binary form must reproduce the above copyright |
9 # notice, this list of conditions and the following disclaimer in the | 9 # notice, this list of conditions and the following disclaimer in the |
10 # documentation and/or other materials provided with the distribution. | 10 # documentation and/or other materials provided with the distribution. |
11 # | 11 # |
12 # THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | 12 # THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
13 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 13 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
14 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 14 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
15 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | 15 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
16 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 16 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
17 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 17 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
18 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 18 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
19 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 19 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
20 # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 20 # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
21 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 21 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
22 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 22 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
23 # | 23 # |
24 | 24 |
| 25 |
25 from contextlib import contextmanager | 26 from contextlib import contextmanager |
26 import filecmp | 27 import filecmp |
27 import fnmatch | 28 import fnmatch |
28 import os | 29 import os |
29 import shutil | 30 import shutil |
30 import sys | 31 import sys |
31 import tempfile | 32 import tempfile |
32 | 33 |
33 from webkitpy.common.system.executive import Executive | 34 from webkitpy.common.system.executive import Executive |
34 | 35 |
35 # Source/ path is needed both to find input IDL files, and to import other | 36 from webkitpy.bindings import bindings_path_finder |
36 # Python modules. | 37 sys.path.append(bindings_path_finder.get_bindings_scripts()) |
37 module_path = os.path.dirname(__file__) | |
38 source_path = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir, | |
39 os.pardir, os.pardir, 'Source')) | |
40 bindings_script_path = os.path.join(source_path, 'bindings', 'scripts') | |
41 sys.path.append(bindings_script_path) # for Source/bindings imports | |
42 | 38 |
43 from code_generator_v8 import CodeGeneratorDictionaryImpl | 39 from code_generator_v8 import CodeGeneratorDictionaryImpl |
44 from code_generator_v8 import CodeGeneratorV8 | 40 from code_generator_v8 import CodeGeneratorV8 |
45 from code_generator_v8 import CodeGeneratorUnionType | 41 from code_generator_v8 import CodeGeneratorUnionType |
46 from code_generator_v8 import CodeGeneratorCallbackFunction | 42 from code_generator_v8 import CodeGeneratorCallbackFunction |
47 from code_generator_web_module import CodeGeneratorWebModule | 43 from code_generator_web_module import CodeGeneratorWebModule |
48 from compute_interfaces_info_individual import InterfaceInfoCollector | 44 from compute_interfaces_info_individual import InterfaceInfoCollector |
49 from compute_interfaces_info_overall import (compute_interfaces_info_overall, | 45 from compute_interfaces_info_overall import (compute_interfaces_info_overall, |
50 interfaces_info) | 46 interfaces_info) |
51 from idl_compiler import (generate_bindings, | 47 from idl_compiler import (generate_bindings, |
(...skipping 29 matching lines...) Expand all Loading... |
81 'TestInterface2Partial2.idl', | 77 'TestInterface2Partial2.idl', |
82 ]) | 78 ]) |
83 | 79 |
84 # core/inspector/InspectorInstrumentation.idl is not a valid Blink IDL. | 80 # core/inspector/InspectorInstrumentation.idl is not a valid Blink IDL. |
85 NON_BLINK_IDL_FILES = frozenset([ | 81 NON_BLINK_IDL_FILES = frozenset([ |
86 'InspectorInstrumentation.idl', | 82 'InspectorInstrumentation.idl', |
87 ]) | 83 ]) |
88 | 84 |
89 COMPONENT_DIRECTORY = frozenset(['core', 'modules']) | 85 COMPONENT_DIRECTORY = frozenset(['core', 'modules']) |
90 | 86 |
91 test_input_directory = os.path.join(source_path, 'bindings', 'tests', 'idls') | 87 SOURCE_PATH = bindings_path_finder.get_blink_source() |
92 reference_directory = os.path.join(source_path, 'bindings', 'tests', 'results') | 88 |
| 89 TEST_INPUT_DIRECTORY = bindings_path_finder.get_test_input() |
| 90 REFERENCE_DIRECTORY = bindings_path_finder.get_test_results() |
93 | 91 |
94 # component -> ComponentInfoProvider. | 92 # component -> ComponentInfoProvider. |
95 # Note that this dict contains information about testing idl files, which live | 93 # Note that this dict contains information about testing idl files, which live |
96 # in Source/bindings/tests/idls/{core,modules}, not in Source/{core,modules}. | 94 # in Source/bindings/tests/idls/{core,modules}, not in Source/{core,modules}. |
97 component_info_providers = {} | 95 component_info_providers = {} |
98 | 96 |
99 | 97 |
100 @contextmanager | 98 @contextmanager |
101 def TemporaryDirectory(): | 99 def TemporaryDirectory(): |
102 """Wrapper for tempfile.mkdtemp() so it's usable with 'with' statement. | 100 """Wrapper for tempfile.mkdtemp() so it's usable with 'with' statement. |
(...skipping 17 matching lines...) Expand all Loading... |
120 idl_paths = [] | 118 idl_paths = [] |
121 for dirpath, _, files in os.walk(directory): | 119 for dirpath, _, files in os.walk(directory): |
122 idl_paths.extend(os.path.join(dirpath, filename) | 120 idl_paths.extend(os.path.join(dirpath, filename) |
123 for filename in fnmatch.filter(files, '*.idl')) | 121 for filename in fnmatch.filter(files, '*.idl')) |
124 return idl_paths | 122 return idl_paths |
125 | 123 |
126 def collect_blink_idl_paths(): | 124 def collect_blink_idl_paths(): |
127 """Returns IDL file paths which blink actually uses.""" | 125 """Returns IDL file paths which blink actually uses.""" |
128 idl_paths = [] | 126 idl_paths = [] |
129 for component in COMPONENT_DIRECTORY: | 127 for component in COMPONENT_DIRECTORY: |
130 directory = os.path.join(source_path, component) | 128 directory = os.path.join(SOURCE_PATH, component) |
131 idl_paths.extend(idl_paths_recursive(directory)) | 129 idl_paths.extend(idl_paths_recursive(directory)) |
132 return idl_paths | 130 return idl_paths |
133 | 131 |
134 def collect_interfaces_info(idl_path_list): | 132 def collect_interfaces_info(idl_path_list): |
135 info_collector = InterfaceInfoCollector() | 133 info_collector = InterfaceInfoCollector() |
136 for idl_path in idl_path_list: | 134 for idl_path in idl_path_list: |
137 if os.path.basename(idl_path) in NON_BLINK_IDL_FILES: | 135 if os.path.basename(idl_path) in NON_BLINK_IDL_FILES: |
138 continue | 136 continue |
139 info_collector.collect_info(idl_path) | 137 info_collector.collect_info(idl_path) |
140 info = info_collector.get_info_as_dict() | 138 info = info_collector.get_info_as_dict() |
(...skipping 17 matching lines...) Expand all Loading... |
158 # from Node, we also need to know that these inherit from EventTarget, | 156 # from Node, we also need to know that these inherit from EventTarget, |
159 # since this is also special-cased and Node inherits from EventTarget, | 157 # since this is also special-cased and Node inherits from EventTarget, |
160 # but this inheritance information requires computing dependencies for | 158 # but this inheritance information requires computing dependencies for |
161 # the real Node.idl file. | 159 # the real Node.idl file. |
162 non_test_idl_paths = collect_blink_idl_paths() | 160 non_test_idl_paths = collect_blink_idl_paths() |
163 # For bindings test IDL files, we collect interfaces info for each | 161 # For bindings test IDL files, we collect interfaces info for each |
164 # component so that we can generate union type containers separately. | 162 # component so that we can generate union type containers separately. |
165 test_idl_paths = {} | 163 test_idl_paths = {} |
166 for component in COMPONENT_DIRECTORY: | 164 for component in COMPONENT_DIRECTORY: |
167 test_idl_paths[component] = idl_paths_recursive( | 165 test_idl_paths[component] = idl_paths_recursive( |
168 os.path.join(test_input_directory, component)) | 166 os.path.join(TEST_INPUT_DIRECTORY, component)) |
169 # 2nd-stage computation: individual, then overall | 167 # 2nd-stage computation: individual, then overall |
170 # | 168 # |
171 # Properly should compute separately by component (currently test | 169 # Properly should compute separately by component (currently test |
172 # includes are invalid), but that's brittle (would need to update this file | 170 # includes are invalid), but that's brittle (would need to update this file |
173 # for each new component) and doesn't test the code generator any better | 171 # for each new component) and doesn't test the code generator any better |
174 # than using a single component. | 172 # than using a single component. |
175 non_test_interfaces_info, non_test_component_info = collect_interfaces_info(
non_test_idl_paths) | 173 non_test_interfaces_info, non_test_component_info = collect_interfaces_info(
non_test_idl_paths) |
176 test_interfaces_info = {} | 174 test_interfaces_info = {} |
177 test_component_info = {} | 175 test_component_info = {} |
178 for component, paths in test_idl_paths.iteritems(): | 176 for component, paths in test_idl_paths.iteritems(): |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 # so only run diff if cmp detects a difference | 249 # so only run diff if cmp detects a difference |
252 print 'FAIL: %s' % reference_basename | 250 print 'FAIL: %s' % reference_basename |
253 print diff(reference_filename, output_filename) | 251 print diff(reference_filename, output_filename) |
254 return False | 252 return False |
255 | 253 |
256 if verbose: | 254 if verbose: |
257 print 'PASS: %s' % reference_basename | 255 print 'PASS: %s' % reference_basename |
258 return True | 256 return True |
259 | 257 |
260 def identical_output_files(output_files): | 258 def identical_output_files(output_files): |
261 reference_files = [os.path.join(reference_directory, | 259 reference_files = [os.path.join(REFERENCE_DIRECTORY, |
262 os.path.relpath(path, output_directory)) | 260 os.path.relpath(path, output_directory)) |
263 for path in output_files] | 261 for path in output_files] |
264 return all([identical_file(reference_filename, output_filename) | 262 return all([identical_file(reference_filename, output_filename) |
265 for (reference_filename, output_filename) in zip(reference_f
iles, output_files)]) | 263 for (reference_filename, output_filename) in zip(reference_f
iles, output_files)]) |
266 | 264 |
267 def no_excess_files(output_files): | 265 def no_excess_files(output_files): |
268 generated_files = set([os.path.relpath(path, output_directory) | 266 generated_files = set([os.path.relpath(path, output_directory) |
269 for path in output_files]) | 267 for path in output_files]) |
270 # Add subversion working copy directories in core and modules. | 268 # Add subversion working copy directories in core and modules. |
271 for component in COMPONENT_DIRECTORY: | 269 for component in COMPONENT_DIRECTORY: |
272 generated_files.add(os.path.join(component, '.svn')) | 270 generated_files.add(os.path.join(component, '.svn')) |
273 | 271 |
274 excess_files = [] | 272 excess_files = [] |
275 for path in list_files(reference_directory): | 273 for path in list_files(REFERENCE_DIRECTORY): |
276 relpath = os.path.relpath(path, reference_directory) | 274 relpath = os.path.relpath(path, REFERENCE_DIRECTORY) |
277 if relpath not in generated_files: | 275 if relpath not in generated_files: |
278 excess_files.append(relpath) | 276 excess_files.append(relpath) |
279 if excess_files: | 277 if excess_files: |
280 print ('Excess reference files! ' | 278 print ('Excess reference files! ' |
281 '(probably cruft from renaming or deleting):\n' + | 279 '(probably cruft from renaming or deleting):\n' + |
282 '\n'.join(excess_files)) | 280 '\n'.join(excess_files)) |
283 return False | 281 return False |
284 return True | 282 return True |
285 | 283 |
286 try: | 284 try: |
(...skipping 16 matching lines...) Expand all Loading... |
303 os.makedirs(partial_interface_output_dir) | 301 os.makedirs(partial_interface_output_dir) |
304 partial_interface_options = IdlCompilerOptions( | 302 partial_interface_options = IdlCompilerOptions( |
305 output_directory=partial_interface_output_dir, | 303 output_directory=partial_interface_output_dir, |
306 impl_output_directory=None, | 304 impl_output_directory=None, |
307 cache_directory=None, | 305 cache_directory=None, |
308 target_component='modules') | 306 target_component='modules') |
309 | 307 |
310 idl_filenames = [] | 308 idl_filenames = [] |
311 dictionary_impl_filenames = [] | 309 dictionary_impl_filenames = [] |
312 partial_interface_filenames = [] | 310 partial_interface_filenames = [] |
313 input_directory = os.path.join(test_input_directory, component) | 311 input_directory = os.path.join(TEST_INPUT_DIRECTORY, component) |
314 for filename in os.listdir(input_directory): | 312 for filename in os.listdir(input_directory): |
315 if (filename.endswith('.idl') and | 313 if (filename.endswith('.idl') and |
316 # Dependencies aren't built | 314 # Dependencies aren't built |
317 # (they are used by the dependent) | 315 # (they are used by the dependent) |
318 filename not in DEPENDENCY_IDL_FILES): | 316 filename not in DEPENDENCY_IDL_FILES): |
319 idl_path = os.path.realpath( | 317 idl_path = os.path.realpath( |
320 os.path.join(input_directory, filename)) | 318 os.path.join(input_directory, filename)) |
321 idl_filenames.append(idl_path) | 319 idl_filenames.append(idl_path) |
322 idl_basename = os.path.basename(idl_path) | 320 idl_basename = os.path.basename(idl_path) |
323 definition_name, _ = os.path.splitext(idl_basename) | 321 definition_name, _ = os.path.splitext(idl_basename) |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 print | 371 print |
374 print FAIL_MESSAGE | 372 print FAIL_MESSAGE |
375 return 1 | 373 return 1 |
376 | 374 |
377 | 375 |
378 def run_bindings_tests(reset_results, verbose): | 376 def run_bindings_tests(reset_results, verbose): |
379 # Generate output into the reference directory if resetting results, or | 377 # Generate output into the reference directory if resetting results, or |
380 # a temp directory if not. | 378 # a temp directory if not. |
381 if reset_results: | 379 if reset_results: |
382 print 'Resetting results' | 380 print 'Resetting results' |
383 return bindings_tests(reference_directory, verbose) | 381 return bindings_tests(REFERENCE_DIRECTORY, verbose) |
384 with TemporaryDirectory() as temp_dir: | 382 with TemporaryDirectory() as temp_dir: |
385 return bindings_tests(temp_dir, verbose) | 383 return bindings_tests(temp_dir, verbose) |
OLD | NEW |