# Building and running code

* Prefer to run `build/gen.py --debug` unless you need a release build.
* **NEVER** run `ninja` without an explicit list of targets to build
  * Build `gn_unittests` if you want to run unittests
    * You can manually run them with a filter in the hot-path of the
      development loop (eg. `./out/gn_unittests --gtest_filter=Functions.*`)
  * Build `gn` if you want to run gn itself (but if you want to run it on
    chromium, prefer building GN in a separate output directory with
    `--release`, as the debug build is very slow on a project of chromium's
    size).
* Before uploading code, make sure to:
  * Run the *full* test suite via building the target `run_tests`
  * Run `tools/run_formatter.sh` to format the code
  * Run `tools/update_reference.sh` to ensure documentation is up to date.
  * If you changed rust code, also run `tools/run_linter.sh`
* **NEVER** delete the build output directory without permission to fix build
  errors. If you feel the need to do so, there is likely a *far* more
  fundamental issue.

# Rust Style Guidelines & Best Practices

Please adhere to the following conventions and best practices when writing or
modifying Rust code in this repository:

## Code Structure & Formatting

* **Code Ordering**: Be consistent about the layout within a file.
  * The structure should generally be:
    1. `mod` statements
    2. `use` statements
    3. Core code (structs, enums, impls, functions)
    4. Test module at the bottom: `#[cfg(test)]`
  * Structs should always come immediately before their impl and impl traits.
  * Full types should be defined before reference types (e.g. if we were
    writing the standard library, String before str)
* **Inlining**: If you only use a variable once, prefer inlining it rather
  than assigning it to a separate binding.
* **Collect**: Prefer using `.collect()` over manually iterating and
  adding/pushing to data structures when possible.
* **Unused Variables**: Variables starting with `_` (e.g. `_var`) should only
  be used if they are truly never used. If you begin using a variable that was
  prefixed with an underscore, rename it to remove the underscore prefix.
* **Unsafe Code**: All `unsafe` blocks must be prefixed with a
  `// Safety: <reason>` comment explaining why the usage is safe.
* **Warnings**: The code (including the tests) should compile with no warnings
  and no clippy lint errors.
* If you ever believe that #[allow] is required to bypass the linter:
  * You *must* get permission from the user.
  * You *must* write a comment above the allow saying why we need it.
  * You *must* put it in as specific a place as is feasible. Avoid, for
    example, allowing a lint for a whole file.

## Imports & Use Statements

* **Test-only Imports**: Imports that are only used inside tests should be
  moved into a module block guarded by `#[cfg(test)]`.

## Documentation

* Anything marked as pub should have a docstring (starts with `///`).

## Coding guidelines

* Data members should not be public without good reason
* **FFI Boundary**: No FFI function calls (such as `extern "C"` blocks or raw
  FFI calls) are allowed outside of the `ffi` submodule. The only exception is
  `intern_string`.
* **No Statics**: Do not use global static variables or `thread_local!`
  structures. They hinder concurrency, unit testing isolation, and
  multi-session safety. Always prefer passing state and context explicitly via
  arguments or trait objects.
* **Dynamic dispatch**: Never use dynamic dispatch (`dyn Trait`) in the hot
  path (any code that could be called an arbitrary number of times by a
  starlark rule).
  * Avoid using dynamic dispatch (`dyn Trait`) in general if you can, but
    you may use it to increase testability of code if it is not in the hot
    path.
    * Eg. Using `dyn Trait` to support a "real" version in production code and
      a fake one in test code.
* `collect_repr` and `collect_str`
  * collect_repr should be defined on starlark types iff `Debug` is
    available on a type. It should just `write!(collector, "{:?}").unwrap()`
  * collect_str should be defined on starlark types iff `Display` is
    available on a type. It should just `write!(collector, "{}").unwrap()`
* **Error Handling**: Prefer using custom error enums with `thiserror` for
  crate-level errors, rather than generic strings or custom hand-written
  Display implementations. Let exceptions and failures bubble up naturally.
* **Crate Encapsulation**: Keep modules, structs, and fields private or
  `pub(crate)` by default to maintain clean boundaries. Only use `pub` for APIs
  that are intended to be consumed by other crates.

# C++ Style guidelines and best practices

* Never use `#pragma once` - use header guards instead.
