# Kobo.Lang.BuildTools

**NuGet package:** `thinkmine.kobo.lang.buildtools`

Install the analyzer package in an SDK-style C# project:

```sh
dotnet add package thinkmine.kobo.lang.buildtools --prerelease
```

This preview requires a .NET 11 compiler host with Roslyn 5.9 or newer,
including IDE compilation. Older .NET Framework-based Visual Studio analyzer
hosts are not supported. The consumer's target framework does not select the
analyzer host runtime.

The package automatically includes recursive `**/*.kobo` files as Roslyn
`AdditionalFiles`, excluding `bin`, `obj`, configured output/intermediate paths,
SDK default exclusions, and files already included as `AdditionalFiles`.
Existing additional-file metadata is preserved. Use `AdditionalFiles Remove`
after the package targets import to explicitly exclude individual Kobo files.

For example, create `Person.kobo`:

```text
module Example;
[public] class:Person
{
    [public] property:string Name { get; set; }
}
```

The same project's C# code can use `new Example.Person()` immediately. No
separate Kobo compilation step is needed. Kobo source follows the language's
established syntax, inference rules, and per-file semantics. C# type checking
and cross-file type references are resolved in the consuming compilation.

Single-file app directives (`#:sdk`, `#:property`, and `#:package`) are for
standalone CLI apps, not generator inputs. Configure these settings in the
consuming project instead. BuildTools reports an error if app directives appear
in a Kobo input.

Enable standard Roslyn output inspection with:

```xml
<PropertyGroup>
  <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
```

Generated names contain the readable Kobo filename and a SHA-256 digest of its
normalized full input path, so equal filenames in different directories do not
collide. Names are stable for the same input path; moving a checkout changes the
digest. Generated content has no timestamps and uses LF line endings.

Diagnostics:

| Code | Severity | Meaning |
| --- | --- | --- |
| KOBO0001 | Error | Kobo source contains a language error |
| KOBO0002 | Error | An additional file could not be read |
| KOBO0003 | Error | An unexpected compiler exception occurred |
| KOBO0004 | Warning | Semantic inference failed and the compiler used its existing simpler inference fallback |

Kobo diagnostics identify the original file and its one-based compiler line and
column (clamped to the available source). C# compiler diagnostics retain their
normal codes and point to the relevant project compilation locations. Full Kobo
source-level debugging is not implemented, so compiler locations may differ
from the corresponding Kobo declarations.

Union-typed variables such as `var:union(int,string) value = 42` use a shared
public union named `union_of_int_string` in the module namespace.
Union syntax is only allowed in variable type declarations (including nested
union case types). Standalone declarations such as `union:Hello {}` are rejected
with a Kobo diagnostic. Definitions are deduplicated across Kobo files in the
same namespace, with the contributing files' imports merged. Imported case
types must resolve consistently across those files. Variable modifiers remain
on variables, and initializers are still required. Union support requires a
compatible compiler host and consuming project configuration.

Global functions also share one `Global` class per namespace, using the same
compilation context as the multi-file compiler API.
Functions are retained rather than deduplicated by name, so C# can check
overloads and report duplicate signatures. Conflicting import aliases in shared
declarations are reported as Kobo errors.

Each file is analyzed independently and cached by path/content and metadata
references. Unchanged files are not reanalyzed when other Kobo files or ordinary
C# source change. Cancellation is propagated through file reads, compiler
phases, semantic-model construction, and source emission.

The analyzer embeds the existing compiler sources at build time; its only
non-framework dependencies are the Roslyn assemblies supplied by the compiler
host. It does not require the CLI tool, Zaria packages, or Kobo runtime libraries.

## BuildTools versus the command-line compiler

With this package installed, use normal `dotnet build` operations in the
consuming C# project. Kobo files are discovered recursively automatically; no
`kobo build` command or `--recursive` option is needed.

For standalone Kobo assemblies, the separate CLI supports `kobo build` for the
current folder, `kobo build ./src` for a selected folder, and
`kobo build ./main.kobo` for one file. CLI folder builds are nonrecursive unless
`--recursive` is supplied, and compile discovered files together into one
assembly. See the [command-line compiler guide](../Kobo.Lang.Compiler/README.md)
for installation and output options.

## Building and testing the package

Build the package from the repository:

```sh
dotnet pack Kobo.Lang.BuildTools/Kobo.Lang.BuildTools.csproj -c Release -o artifacts
```

Run the generator-driver and real NuGet consumer regression checks:

```sh
dotnet run --project KoboLang.TestHarness -- --build-tools-self-test
dotnet run --project KoboLang.TestHarness -- --build-tools-package-test
```
