Пример #1
0
def PatchMojomAst(mojom_abspath, ast, enabled_features):
  """Search for mojom file in 'chromium_src' and apply AST changes.

  Can add imports, enums, interfaces, structs, unions.
  Can extend enum values, interface members, struct fields, union members.

  To be more strict with patching, attributes [BraveAdd] or [BraveExtend] should be used.
  """

  # Get this script absolute location.
  this_py_path = os.path.realpath(__file__)

  # Get the original chromium dir location.
  chromium_original_dir = os.path.abspath(os.path.join(this_py_path,
                                                       *[os.pardir] * 10))

  if len(chromium_original_dir) >= len(mojom_abspath) + 1:
    raise RuntimeError("Could not get original chromium src dir")

  # Build brave/chromium_src path.
  chromium_src_abspath = os.path.join(chromium_original_dir, 'brave', 'chromium_src')
  if not os.path.isdir(chromium_src_abspath):
    raise RuntimeError("Could not find brave/chromium_src. %s is not a dir" % chromium_src_abspath)

  # Relative path.
  mojom_relpath = mojom_abspath[len(chromium_original_dir) + 1:]

  # Build possible brave/chromium_src/**/*.mojom path.
  brave_mojom_abspath = os.path.join(chromium_src_abspath, mojom_relpath)
  if not os.path.isfile(brave_mojom_abspath):
    # Nothing to patch.
    return

  # Open and parse brave/chromium_src/**/*.mojom file.
  with codecs.open(brave_mojom_abspath, encoding='utf-8') as f:
    brave_ast = parser.Parse(f.read(), brave_mojom_abspath)
    conditional_features.RemoveDisabledDefinitions(brave_ast, enabled_features)

    _ApplyBraveAstChanges(brave_ast, ast)
Пример #2
0
def _ParseMojoms(mojom_files,
                 input_root_paths,
                 output_root_path,
                 enabled_features,
                 allowed_imports=None):
  """Parses a set of mojom files and produces serialized module outputs.

  Args:
    mojom_files: A list of mojom files to process. Paths must be absolute paths
        which fall within one of the input or output root paths.
    input_root_paths: A list of absolute filesystem paths which may be used to
        resolve relative mojom file paths.
    output_root_path: An absolute filesystem path which will service as the root
        for all emitted artifacts. Artifacts produced from a given mojom file
        are based on the mojom's relative path, rebased onto this path.
        Additionally, the script expects this root to contain already-generated
        modules for any transitive dependencies not listed in mojom_files.
    enabled_features: A list of enabled feature names, controlling which AST
        nodes are filtered by [EnableIf] attributes.

  Returns:
    None.

    Upon completion, a mojom-module file will be saved for each input mojom.
  """
  assert input_root_paths
  assert output_root_path

  loaded_mojom_asts = {}
  loaded_modules = {}
  input_dependencies = defaultdict(set)
  mojom_files_to_parse = dict((abs_path,
                               _RebaseAbsolutePath(abs_path, input_root_paths))
                              for abs_path in mojom_files)
  abs_paths = dict(
      (path, abs_path) for abs_path, path in mojom_files_to_parse.items())
  for mojom_abspath, _ in mojom_files_to_parse.items():
    with open(mojom_abspath) as f:
      ast = parser.Parse(''.join(f.readlines()), mojom_abspath)
      conditional_features.RemoveDisabledDefinitions(ast, enabled_features)
      loaded_mojom_asts[mojom_abspath] = ast
      invalid_imports = []
      for imp in ast.import_list:
        import_abspath = _ResolveRelativeImportPath(imp.import_filename,
                                                    input_root_paths)
        if allowed_imports and import_abspath not in allowed_imports:
          invalid_imports.append(imp.import_filename)

        abs_paths[imp.import_filename] = import_abspath
        if import_abspath in mojom_files_to_parse:
          # This import is in the input list, so we're going to translate it
          # into a module below; however it's also a dependency of another input
          # module. We retain record of dependencies to help with input
          # processing later.
          input_dependencies[mojom_abspath].add((import_abspath,
                                                 imp.import_filename))
        else:
          # We have an import that isn't being parsed right now. It must already
          # be parsed and have a module file sitting in a corresponding output
          # location.
          module_path = _GetModuleFilename(imp.import_filename)
          module_abspath = _ResolveRelativeImportPath(module_path,
                                                      [output_root_path])
          with open(module_abspath, 'rb') as module_file:
            loaded_modules[import_abspath] = module.Module.Load(module_file)

      if invalid_imports:
        raise ValueError(
            '\nThe file %s imports the following files not allowed by build '
            'dependencies:\n\n%s\n' % (mojom_abspath,
                                       '\n'.join(invalid_imports)))


  # At this point all transitive imports not listed as inputs have been loaded
  # and we have a complete dependency tree of the unprocessed inputs. Now we can
  # load all the inputs, resolving dependencies among them recursively as we go.
  num_existing_modules_loaded = len(loaded_modules)
  for mojom_abspath, mojom_path in mojom_files_to_parse.items():
    _EnsureInputLoaded(mojom_abspath, mojom_path, abs_paths, loaded_mojom_asts,
                       input_dependencies, loaded_modules)
  assert (num_existing_modules_loaded +
          len(mojom_files_to_parse) == len(loaded_modules))

  # Now we have fully translated modules for every input and every transitive
  # dependency. We can dump the modules to disk for other tools to use.
  for mojom_abspath, mojom_path in mojom_files_to_parse.items():
    module_path = os.path.join(output_root_path, _GetModuleFilename(mojom_path))
    module_dir = os.path.dirname(module_path)
    if not os.path.exists(module_dir):
      try:
        # Python 2 doesn't support exist_ok on makedirs(), so we just ignore
        # that failure if it happens. It's possible during build due to races
        # among build steps with module outputs in the same directory.
        os.makedirs(module_dir)
      except OSError as e:
        if e.errno != errno.EEXIST:
          raise
    with open(module_path, 'wb') as f:
      loaded_modules[mojom_abspath].Dump(f)
 def parseAndAssertEqual(self, source, expected_source):
     definition = parser.Parse(source, "my_file.mojom")
     conditional_features.RemoveDisabledDefinitions(definition,
                                                    ENABLED_FEATURES)
     expected = parser.Parse(expected_source, "my_file.mojom")
     self.assertEquals(definition, expected)
Пример #4
0
def _ParseAstHelper(args):
    mojom_abspath, enabled_features = args
    with codecs.open(mojom_abspath, encoding='utf-8') as f:
        ast = parser.Parse(f.read(), mojom_abspath)
        conditional_features.RemoveDisabledDefinitions(ast, enabled_features)
        return mojom_abspath, ast