def _GenerateModule(self, args, remaining_args, generator_modules, rel_filename): # Return the already-generated module. if rel_filename.path in self._processed_files: return self._processed_files[rel_filename.path] tree = self._parsed_files[rel_filename.path] dirname = os.path.dirname(rel_filename.path) # Process all our imports first and collect the module object for each. # We use these to generate proper type info. imports = {} for parsed_imp in tree.import_list: rel_import_file = FindImportFile( RelativePath(dirname, rel_filename.source_root), parsed_imp.import_filename, args.import_directories) imports[parsed_imp.import_filename] = self._GenerateModule( args, remaining_args, generator_modules, rel_import_file) # Set the module path as relative to the source root. # Normalize to unix-style path here to keep the generators simpler. module_path = rel_filename.relative_path().replace('\\', '/') module = translate.OrderedModule(tree, module_path, imports) if args.scrambled_message_id_salt_paths: salt = ''.join([ ReadFileContents(f) for f in args.scrambled_message_id_salt_paths ]) ScrambleMethodOrdinals(module.interfaces, salt) if self._should_generate(rel_filename.path): AddComputedData(module) for language, generator_module in generator_modules.iteritems(): generator = generator_module.Generator( module, args.output_dir, typemap=self._typemap.get(language, {}), variant=args.variant, bytecode_path=args.bytecode_path, for_blink=args.for_blink, use_once_callback=args.use_once_callback, js_bindings_mode=args.js_bindings_mode, export_attribute=args.export_attribute, export_header=args.export_header, generate_non_variant_code=args.generate_non_variant_code, support_lazy_serialization=args.support_lazy_serialization, allow_native_structs=args.allow_native_structs) filtered_args = [] if hasattr(generator_module, 'GENERATOR_PREFIX'): prefix = '--' + generator_module.GENERATOR_PREFIX + '_' filtered_args = [ arg for arg in remaining_args if arg.startswith(prefix) ] generator.GenerateFiles(filtered_args) # Save result. self._processed_files[rel_filename.path] = module return module
def parseMojom(mojom, file_overrides, override_modules): if mojom in unmodified_modules or mojom in override_modules: return contents = file_overrides.get(mojom) if contents: modules = override_modules else: modules = unmodified_modules with io.open(os.path.join(root, mojom), encoding='utf-8') as f: contents = f.read() try: ast = parser.Parse(contents, mojom) except Exception as e: six.reraise( ParseError, 'encountered exception {0} while parsing {1}'.format(e, mojom), sys.exc_info()[2]) for imp in ast.import_list: parseMojom(imp.import_filename, file_overrides, override_modules) # Now that the transitive set of dependencies has been imported and parsed # above, translate each mojom AST into a Module so that all types are fully # defined and can be inspected. all_modules = {} all_modules.update(unmodified_modules) all_modules.update(override_modules) modules[mojom] = translate.OrderedModule(ast, mojom, all_modules)
def testSelfRecursiveUnions(self): """Verifies _UnionField() raises when a union is self-recursive.""" tree = ast.Mojom(None, ast.ImportList(), [ ast.Union( "SomeUnion", None, ast.UnionBody([ast.UnionField("a", None, None, "SomeUnion")])) ]) with self.assertRaises(Exception): translate.OrderedModule(tree, "mojom_tree", []) tree = ast.Mojom(None, ast.ImportList(), [ ast.Union( "SomeUnion", None, ast.UnionBody([ast.UnionField("a", None, None, "SomeUnion?")])) ]) with self.assertRaises(Exception): translate.OrderedModule(tree, "mojom_tree", [])
def _GenerateModule(self, args, remaining_args, generator_modules, rel_filename): # Return the already-generated module. if rel_filename.path in self._processed_files: return self._processed_files[rel_filename.path] tree = self._parsed_files[rel_filename.path] dirname, name = os.path.split(rel_filename.path) # Process all our imports first and collect the module object for each. # We use these to generate proper type info. imports = {} for parsed_imp in tree.import_list: rel_import_file = FindImportFile( RelativePath(dirname, rel_filename.source_root), parsed_imp.import_filename, args.import_directories) imports[parsed_imp.import_filename] = self._GenerateModule( args, remaining_args, generator_modules, rel_import_file) module = translate.OrderedModule(tree, name, imports) # Set the path as relative to the source root. module.path = rel_filename.relative_path() # Normalize to unix-style path here to keep the generators simpler. module.path = module.path.replace('\\', '/') if self._should_generate(rel_filename.path): for language, generator_module in generator_modules.iteritems(): generator = generator_module.Generator( module, args.output_dir, typemap=self._typemap.get(language, {}), variant=args.variant, bytecode_path=args.bytecode_path, for_blink=args.for_blink, use_once_callback=args.use_once_callback, use_new_js_bindings=args.use_new_js_bindings, export_attribute=args.export_attribute, export_header=args.export_header, generate_non_variant_code=args.generate_non_variant_code) filtered_args = [] if hasattr(generator_module, 'GENERATOR_PREFIX'): prefix = '--' + generator_module.GENERATOR_PREFIX + '_' filtered_args = [ arg for arg in remaining_args if arg.startswith(prefix) ] generator.GenerateFiles(filtered_args) # Save result. self._processed_files[rel_filename.path] = module return module
def _GenerateModule(tree, module_path): imports = {} for parsed_imp in tree.import_list: filename = parsed_imp.import_filename print("imported file " + filename) import_tree = _UnpickleAST( os.path.join( ast_root_dir, os.path.splitext(os.path.basename( parsed_imp.import_filename))[0] + '.p')) imports[filename] = _GenerateModule(import_tree, filename) # Set the module path as relative to the source root. # Normalize to unix-style path here to keep the generators simpler. # module_path = rel_filename.relative_path().replace('\\', '/') path = os.path.basename(module_path) return translate.OrderedModule(tree, path, imports)
def _EnsureInputLoaded(mojom_abspath, module_path, abs_paths, asts, dependencies, loaded_modules): """Recursively ensures that a module and its dependencies are loaded. Args: mojom_abspath: An absolute file path pointing to a mojom file to load. module_path: The relative path used to identify mojom_abspath. abs_paths: A mapping from module paths to absolute file paths for all inputs given to this execution of the script. asts: A map from each input mojom's absolute path to its parsed AST. dependencies: A mapping of which input mojoms depend on each other, indexed by absolute file path. loaded_modules: A mapping of all modules loaded so far, including non-input modules that were pulled in as transitive dependencies of the inputs. import_set: The working set of mojom imports processed so far in this call stack. Used to detect circular dependencies. import_stack: An ordered list of imports processed so far in this call stack. Used to report circular dependencies. Returns: None On return, loaded_modules will be populated with the loaded input mojom's Module as well as the Modules of all of its transitive dependencies.""" if mojom_abspath in loaded_modules: # Already done. return for dep_abspath, dep_path in dependencies[mojom_abspath]: if dep_abspath not in loaded_modules: _EnsureInputLoaded(dep_abspath, dep_path, abs_paths, asts, dependencies, loaded_modules) imports = {} for imp in asts[mojom_abspath].import_list: path = imp.import_filename imports[path] = loaded_modules[abs_paths[path]] loaded_modules[mojom_abspath] = translate.OrderedModule( asts[mojom_abspath], module_path, imports)
def _EnsureInputLoaded(mojom_abspath, module_path, abs_paths, asts, dependencies, loaded_modules, module_metadata): """Recursively ensures that a module and its dependencies are loaded. Args: mojom_abspath: An absolute file path pointing to a mojom file to load. module_path: The relative path used to identify mojom_abspath. abs_paths: A mapping from module paths to absolute file paths for all inputs given to this execution of the script. asts: A map from each input mojom's absolute path to its parsed AST. dependencies: A mapping of which input mojoms depend on each other, indexed by absolute file path. loaded_modules: A mapping of all modules loaded so far, including non-input modules that were pulled in as transitive dependencies of the inputs. module_metadata: Metadata to be attached to every module loaded by this helper. Returns: None On return, loaded_modules will be populated with the loaded input mojom's Module as well as the Modules of all of its transitive dependencies.""" if mojom_abspath in loaded_modules: # Already done. return for dep_abspath, dep_path in sorted(dependencies[mojom_abspath]): if dep_abspath not in loaded_modules: _EnsureInputLoaded(dep_abspath, dep_path, abs_paths, asts, dependencies, loaded_modules, module_metadata) imports = {} for imp in asts[mojom_abspath].import_list: path = imp.import_filename imports[path] = loaded_modules[abs_paths[path]] loaded_modules[mojom_abspath] = translate.OrderedModule( asts[mojom_abspath], module_path, imports) loaded_modules[mojom_abspath].metadata = dict(module_metadata)
def testTranslateSimpleUnions(self): """Makes sure that a simple union is translated correctly.""" tree = ast.Mojom(None, ast.ImportList(), [ ast.Union( "SomeUnion", None, ast.UnionBody([ ast.UnionField("a", None, None, "int32"), ast.UnionField("b", None, None, "string") ])) ]) translation = translate.OrderedModule(tree, "mojom_tree", []) self.assertEqual(1, len(translation.unions)) union = translation.unions[0] self.assertTrue(isinstance(union, mojom.Union)) self.assertEqual("SomeUnion", union.mojom_name) self.assertEqual(2, len(union.fields)) self.assertEqual("a", union.fields[0].mojom_name) self.assertEqual(mojom.INT32.spec, union.fields[0].kind.spec) self.assertEqual("b", union.fields[1].mojom_name) self.assertEqual(mojom.STRING.spec, union.fields[1].kind.spec)
def _GenerateModule(self, args, remaining_args, generator_modules, rel_filename, imported_filename_stack): # Return the already-generated module. if rel_filename.path in self._processed_files: return self._processed_files[rel_filename.path] if rel_filename.path in imported_filename_stack: print("%s: Error: Circular dependency" % rel_filename.path + \ MakeImportStackMessage(imported_filename_stack + [rel_filename.path])) sys.exit(1) tree = _UnpickleAST( _FindPicklePath(rel_filename, args.gen_directories + [args.output_dir])) dirname = os.path.dirname(rel_filename.path) # Process all our imports first and collect the module object for each. # We use these to generate proper type info. imports = {} for parsed_imp in tree.import_list: rel_import_file = FindImportFile( RelativePath(dirname, rel_filename.source_root), parsed_imp.import_filename, args.import_directories) imports[parsed_imp.import_filename] = self._GenerateModule( args, remaining_args, generator_modules, rel_import_file, imported_filename_stack + [rel_filename.path]) # Set the module path as relative to the source root. # Normalize to unix-style path here to keep the generators simpler. module_path = rel_filename.relative_path().replace('\\', '/') module = translate.OrderedModule(tree, module_path, imports) if args.scrambled_message_id_salt_paths: salt = ''.join( map(ReadFileContents, args.scrambled_message_id_salt_paths)) ScrambleMethodOrdinals(module.interfaces, salt) if self._should_generate(rel_filename.path): AddComputedData(module) for language, generator_module in generator_modules.items(): generator = generator_module.Generator( module, args.output_dir, typemap=self._typemap.get(language, {}), variant=args.variant, bytecode_path=args.bytecode_path, for_blink=args.for_blink, js_bindings_mode=args.js_bindings_mode, use_old_js_lite_bindings_names=args. use_old_js_lite_bindings_names, export_attribute=args.export_attribute, export_header=args.export_header, generate_non_variant_code=args.generate_non_variant_code, support_lazy_serialization=args.support_lazy_serialization, disallow_native_types=args.disallow_native_types, disallow_interfaces=args.disallow_interfaces, generate_message_ids=args.generate_message_ids, generate_fuzzing=args.generate_fuzzing, enable_kythe_annotations=args.enable_kythe_annotations) filtered_args = [] if hasattr(generator_module, 'GENERATOR_PREFIX'): prefix = '--' + generator_module.GENERATOR_PREFIX + '_' filtered_args = [ arg for arg in remaining_args if arg.startswith(prefix) ] generator.GenerateFiles(filtered_args) # Save result. self._processed_files[rel_filename.path] = module return module