# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/compute_inputs_for_analyze.gni")
import("//build/config/rust.gni")

if (compute_inputs_for_analyze) {
  template("analyze_rust") {
    _target_name = target_name
    assert(defined(invoker.crate_root))

    action("${_target_name}_collect_sources") {
      forward_variables_from(invoker,
                             "*",
                             TESTONLY_AND_VISIBILITY + [
                                   "inputs",
                                   "script",
                                   "sources",
                                   "depfile",
                                   "outputs",
                                   "args",
                                 ])
      forward_variables_from(invoker, [ "testonly" ])

      script = "//build/rust/collect_rust_sources.py"
      depfile = "${target_gen_dir}/${target_name}.verify.d"
      outputs = [ depfile ]

      args = [
        "--generate-depfile",
        "${rust_sysroot}/bin/rustc",
        rebase_path(crate_root, root_build_dir),
        rebase_path(depfile, root_build_dir),
        "{{rustflags}}",
      ]
    }

    action(_target_name) {
      forward_variables_from(invoker, [ "testonly" ])

      # Constructs a depfile of all rust sources in the crate.
      deps = [ ":${_target_name}_collect_sources" ]

      # This target is reached once during `gn gen` and then again during
      # `gn analyze`.
      #
      # 1. When doing `gn gen`, the ':${_target_name}_collect_sources'
      #    target generates a depfile containing all the rust sources of
      #    the crate. The exec_script() below runs first, and it produces an
      #    empty result.
      # 2. When doing `gn analyze`, the exec_script() reads the depfile that
      #    was written during `gn gen` and puts each Rust file in the crate
      #    into `inputs`.
      depfile_path = []
      foreach(d, get_target_outputs(":${_target_name}_collect_sources")) {
        depfile_path += [ rebase_path(d, root_build_dir) ]
      }

      # Here we read the depfile from `gn gen` when doing `gn analyze`, and
      # add all the rust files in the crate to `inputs`. This ensures that
      # analyze considers them as affecting tests that depend on the crate.
      rust_srcs = exec_script("//build/rust/collect_rust_sources.py",
                              [ "--read-depfile" ] + depfile_path,
                              "list lines")
      inputs = []
      foreach(s, rust_srcs) {
        inputs += [ rebase_path(s, "//", root_build_dir) ]
      }
      script = "//build/rust/collect_rust_sources.py"
      args = [
        "--stamp",
        rebase_path("${target_gen_dir}/${target_name}.verify.stamp",
                    root_build_dir),
      ]
      outputs = [ "${target_gen_dir}/${target_name}.verify.stamp" ]
    }
  }
}