> ## Documentation Index
> Fetch the complete documentation index at: https://ancplua.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Roslyn Utilities

> Utilities for source generators and analyzers.

ANcpLua.Roslyn.Utilities provides utilities for building Roslyn analyzers and source generators.

## What's New in v1.42

**Performance namespace** -- seven zero-allocation primitives for `netstandard2.0`:

* `BitHelpers` -- `PopCount`, `LeadingZeroCount`, `Log2`, `RoundUpToPowerOf2`, rotations
* `AsciiSet` -- 128-bit bitmap for O(1) character membership
* `AsciiHelpers` -- branchless `EqualsIgnoreCase`, `TrimWhiteSpace`, `IsAscii`
* `SpanHelpers` -- `Count`, `ContainsAny`, `IndexOfAny`, `IsWhiteSpace` for spans
* `IntegerParser` -- `TryParseInt32`/`TryParseInt64` from `ReadOnlySpan<char>` and `ReadOnlySpan<byte>`
* `SpanTokenizer` -- `ref struct` allocation-free tokenizer with `foreach` support
* `MemoryHelpers` -- `AsBytes`, `Cast`, `GetReference` wrappers for `MemoryMarshal`

**Directory restructure** -- projects moved from `ANcpLua.Roslyn.Utilities/` to `src/` subfolder.

## What's New in v1.19

**Expanded Guard API** - Comprehensive argument validation:

* **Collections**: `NoDuplicates()` for duplicate detection
* **File System**: `FileExists()`, `DirectoryExists()`, `ValidFileName()`, `ValidPath()`, `ValidExtension()`, `NormalizedExtension()`
* **Type Validation**: `DefinedEnum()`, `NotNullableType()`, `AssignableTo<T>()`, `AssignableFrom<T>()`
* **Member Validation**: `NotNullWithMember()`, `MemberNotNull()` for object + member validation
* **Numeric**: `NotZero`, `NotNegative`, `Positive`, `NotGreaterThan`, `NotLessThan`, `LessThan`, `GreaterThan` (int/long/double/decimal)
* **Double-specific**: `NotNaN()`, `Finite()` for floating-point edge cases
* **Unreachable Code**: `Unreachable()`, `Unreachable<T>()` with caller info capture

All numeric methods use `[MethodImpl(AggressiveInlining)]` for hot paths.

## What's New in v1.18

**API cleanup** - Tightened public surface, renamed methods for clarity:

* `Guard.NotNullOr*` renamed to `Guard.NotNullOrElse*` with new lazy `Func<T>` overloads
* `IndentedStringBuilder.Indent()`/`Outdent()` made private (use `BeginBlock()`)
* Helper extensions reorganized: `NullableExtensions`, `ObjectExtensions`, `TryExtensions`
* Redundant nullability attributes and operators removed

## Install

```shell theme={null}
# For analyzers/generators (source-only, no runtime dependency)
dotnet add package ANcpLua.Roslyn.Utilities.Sources

# For polyfills only (no Roslyn dependency)
dotnet add package ANcpLua.Roslyn.Utilities.Polyfills

# For runtime reference
dotnet add package ANcpLua.Roslyn.Utilities

# For testing
dotnet add package ANcpLua.Roslyn.Utilities.Testing
```

<Warning>
  **Layer 0 Package**: This package cannot depend on ANcpLua.NET.Sdk (circular
  dependency). Uses `Microsoft.NET.Sdk` with built-in polyfills.
</Warning>

## Packages

| Package                            | Target         | Description                                                |
| ---------------------------------- | -------------- | ---------------------------------------------------------- |
| ANcpLua.Roslyn.Utilities           | netstandard2.0 | Core library (DLL reference)                               |
| ANcpLua.Roslyn.Utilities.Sources   | netstandard2.0 | Source-only (embeds as `internal` in analyzers/generators) |
| ANcpLua.Roslyn.Utilities.Polyfills | netstandard2.0 | Source-only polyfills (no Roslyn dependency)               |
| ANcpLua.Roslyn.Utilities.Testing   | net10.0        | Generator testing                                          |

## Features

| Category            | APIs                                          | Docs                                         |
| ------------------- | --------------------------------------------- | -------------------------------------------- |
| Flow Control        | `DiagnosticFlow<T>`, `ReportAndContinue()`    | [DiagnosticFlow](/utilities/diagnostic-flow) |
| Pattern Matching    | `Match.*` (symbols), `Invoke.*` (operations)  | [Patterns](/utilities/patterns)              |
| Guard Clauses       | `Guard.NotNull()`, `Guard.Positive()`, etc.   | [Guard](/utilities/guard)                    |
| Semantic Validation | `SemanticGuard<T>`, `MustBeAsync()`           | [SemanticGuard](/utilities/semantic-guard)   |
| Domain Contexts     | `AwaitableContext`, `AspNetContext`           | [Contexts](/utilities/contexts)              |
| Operations          | `OperationExtensions`, `InvocationExtensions` | [Operations](/utilities/operations)          |
| Code Generation     | `IndentedStringBuilder`                       | [Codegen](/utilities/codegen)                |
| Pipeline            | `GroupBy()`, `Batch()`, `Distinct()`          | [Pipeline](/utilities/pipeline)              |
| Symbol Extensions   | `IsEqualTo()`, `HasAttribute()`               | [Symbols](/utilities/symbols)                |
| Testing             | `Test<TGenerator>.Run()`, caching validation  | [Testing](/utilities/testing)                |
| Performance         | `BitHelpers`, `AsciiSet`, `SpanTokenizer`     | [Performance](/utilities/performance)        |

## Quick Example

```csharp theme={null}
// DiagnosticFlow - never lose diagnostics
symbol.ToFlow(nullDiag)
    .Then(ValidateMethod)
    .Where(m => m.IsAsync, asyncRequired)
    .WarnIf(m => m.IsObsolete, obsoleteWarn)
    .Then(GenerateCode)
    .ReportAndContinue(context);

// Pattern matching - replace 50-line if-statements
Match.Method()
    .Async()
    .ReturningTask()
    .WithCancellationToken()
    .Matches(method);
```
