def scan_all(
        self,
        targets: list,
        changed_files: list[Path] | None = None,
        use_json: bool = False,
    ):
        """Scan all targets for class inheriting Component and generate the .pyi files.

        Args:
            targets: the list of file/folders to scan.
            changed_files (optional): the list of changed files since the last run.
            use_json: whether to use json to store the hashes.
        """
        file_targets = []
        for target in targets:
            target_path = Path(target)
            if (
                target_path.is_file()
                and target_path.suffix == ".py"
                and target_path.name not in EXCLUDED_FILES
            ):
                file_targets.append(target_path)
                continue
            if not target_path.is_dir():
                continue
            for file_path in _walk_files(target_path):
                relative = _relative_to_pwd(file_path)
                if relative.name in EXCLUDED_FILES or file_path.suffix != ".py":
                    continue
                if (
                    changed_files is not None
                    and _relative_to_pwd(file_path) not in changed_files
                ):
                    continue
                file_targets.append(file_path)

        # check if pyi changed but not the source
        if changed_files is not None:
            for changed_file in changed_files:
                if changed_file.suffix != ".pyi":
                    continue
                py_file_path = changed_file.with_suffix(".py")
                if not py_file_path.exists() and changed_file.exists():
                    changed_file.unlink()
                if py_file_path in file_targets:
                    continue
                subprocess.run(["git", "checkout", changed_file])

        if True:
            self._scan_files(file_targets)
        else:
            self._scan_files_multiprocess(file_targets)

        file_paths, hashes = (
            [f[0] for f in self.written_files],
            [f[1] for f in self.written_files],
        )

        # Fix generated pyi files with ruff.
        if file_paths:
            subprocess.run(["ruff", "format", *file_paths])
            subprocess.run(["ruff", "check", "--fix", *file_paths])

        # For some reason, we need to format the __init__.pyi files again after fixing...
        init_files = [f for f in file_paths if "/__init__.pyi" in f]
        subprocess.run(["ruff", "format", *init_files])

        if use_json:
            if file_paths and changed_files is None:
                file_paths = list(map(Path, file_paths))
                top_dir = file_paths[0].parent
                for file_path in file_paths:
                    file_parent = file_path.parent
                    while len(file_parent.parts) > len(top_dir.parts):
                        file_parent = file_parent.parent
                    while len(top_dir.parts) > len(file_parent.parts):
                        top_dir = top_dir.parent
                    while not file_parent.samefile(top_dir):
                        file_parent = file_parent.parent
                        top_dir = top_dir.parent

                while (
                    not top_dir.samefile(top_dir.parent)
                    and not (top_dir / PYI_HASHES).exists()
                ):
                    top_dir = top_dir.parent

                pyi_hashes_file = top_dir / PYI_HASHES

                if pyi_hashes_file.exists():
                    pyi_hashes_file.write_text(
                        json.dumps(
                            dict(
                                zip(
                                    [
                                        f.relative_to(pyi_hashes_file.parent).as_posix()
                                        for f in file_paths
                                    ],
                                    hashes,
                                    strict=True,
                                )
                            ),
                            indent=2,
                            sort_keys=True,
                        )
                        + "\n",
                    )
            elif file_paths:
                file_paths = list(map(Path, file_paths))
                pyi_hashes_parent = file_paths[0].parent
                while (
                    not pyi_hashes_parent.samefile(pyi_hashes_parent.parent)
                    and not (pyi_hashes_parent / PYI_HASHES).exists()
                ):
                    pyi_hashes_parent = pyi_hashes_parent.parent

                pyi_hashes_file = pyi_hashes_parent / PYI_HASHES
                if pyi_hashes_file.exists():
                    pyi_hashes = json.loads(pyi_hashes_file.read_text())
                    for file_path, hashed_content in zip(
                        file_paths, hashes, strict=False
                    ):
                        formatted_path = file_path.relative_to(
                            pyi_hashes_parent
                        ).as_posix()
                        pyi_hashes[formatted_path] = hashed_content

                    pyi_hashes_file.write_text(
                        json.dumps(pyi_hashes, indent=2, sort_keys=True) + "\n"
                    )

        # Post-process the generated pyi files to add hacky type: ignore comments
        for file_path in file_paths:
            with FileInput(file_path, inplace=True) as f:
                for line in f:
                    # Hack due to ast not supporting comments in the tree.
                    if (
                        "def create(" in line
                        or "Var[Figure]" in line
                        or "Var[Template]" in line
                    ):
                        line = line.rstrip() + "  # type: ignore\n"
                    print(line, end="")  # noqa: T201
Scan all targets for class inheriting Component and generate the .pyi files.

        Args:
            targets: the list of file/folders to scan.
            changed_files (optional): the list of changed files since the last run.
            use_json: whether to use json to store the hashes.
        
reflex/utils/pyi_generator.py