Bug 979665 - Properly detect WebIDL type changes; r=froydnj

This patch fixes a bug in WebIDL code generation that could be triggered
if an input file changed locations but the original file remained on
disk. When computing the set of source .webidl files to perform code
generation on, we failed to prune files that were no longer part of the
active set of input files. References to files in old locations would
get pulled in to the regeneration set, leading to a cryptic KeyError
during code generation.

--HG--
extra : rebase_source : 23f1b973133960cfa954d44b20175fc7a369169a
This commit is contained in:
Gregory Szorc 2014-03-05 23:21:02 -08:00
parent 391fb744d1
commit 6eb43615b4
2 changed files with 32 additions and 3 deletions

View File

@ -389,9 +389,10 @@ class WebIDLCodegenManager(LoggingMixin):
if any(dep for dep in v['inputs'] if dep in changed_inputs):
changed_inputs.add(v['filename'])
# Ensure all changed inputs actually exist (some changed inputs could
# have been from deleted files).
return set(f for f in changed_inputs if os.path.exists(f))
# Only use paths that are known to our current state.
# This filters out files that were deleted or changed type (e.g. from
# static to preprocessed).
return changed_inputs & self._input_paths
def _binding_info(self, p):
"""Compute binding metadata for an input path.

View File

@ -274,6 +274,34 @@ class TestWebIDLCodegenManager(unittest.TestCase):
os.path.exists = old_exists
del sys.modules['mozwebidlcodegen.fakemodule']
def test_copy_input(self):
"""Ensure a copied .webidl file is handled properly."""
# This test simulates changing the type of a WebIDL from static to
# preprocessed. In that scenario, the original file still exists but
# it should no longer be consulted during codegen.
args = self._get_manager_args()
m1 = WebIDLCodegenManager(**args)
m1.generate_build_files()
old_path = None
for p in args['inputs'][0]:
if p.endswith('Parent.webidl'):
old_path = p
break
self.assertIsNotNone(old_path)
new_path = mozpath.join(args['cache_dir'], 'Parent.webidl')
shutil.copy2(old_path, new_path)
args['inputs'][0].remove(old_path)
args['inputs'][0].add(new_path)
m2 = WebIDLCodegenManager(**args)
result = m2.generate_build_files()
self.assertEqual(len(result.updated), 0)
if __name__ == '__main__':
main()