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
Esempio n. 2
0
    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)
Esempio n. 3
0
    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
Esempio n. 5
0
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)
Esempio n. 6
0
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)
Esempio n. 7
0
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)
Esempio n. 9
0
    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