Plan Phase
The Plan phase analyzes cross-namespace dependencies and plans all import/export statements.
Components
| Component | File | Purpose |
|---|---|---|
| ImportGraphBuilder | ImportGraphBuilder.cs |
Build dependency graph |
| ImportPlanner | ImportPlanner.cs |
Generate import statements |
| EmissionPlanner | EmissionPlanner.cs |
Plan file generation order |
| SCCBucketer | SCCBucketer.cs |
Handle circular dependencies |
| PhaseGate | PhaseGate.cs |
Validate invariants |
ImportGraphBuilder
Builds a graph of cross-namespace type references.
public sealed record ImportGraphData
{
// Namespace A depends on Namespace B
public Dictionary<string, HashSet<string>> NamespaceDependencies { get; }
// Detailed references: source ns, target ns, target type, reference kind
public List<CrossNamespaceReference> CrossNamespaceReferences { get; }
}
public enum ReferenceKind
{
BaseClass, // extends clause (needs value import)
Interface, // implements clause (needs value import)
ReturnType, // method return type (type-only import)
Parameter, // method parameter (type-only import)
PropertyType, // property type (type-only import)
Constraint // generic constraint (type-only import)
}
ImportPlanner
Generates import statements for each namespace. Uses FacadeFamilyIndex for drift-proof multi-arity family resolution.
public sealed record ImportPlan
{
// Per-namespace imports
public Dictionary<string, List<ImportStatement>> NamespaceImports { get; }
// Per-namespace exports
public Dictionary<string, List<ExportStatement>> NamespaceExports { get; }
// Qualified names for value imports (base classes)
public Dictionary<(string, string), string> ValueImportQualifiedNames { get; }
}
public sealed record ImportStatement(
string ImportPath, // "../../System/internal/index.js"
string TargetNamespace, // "System"
List<TypeImport> TypeImports,
string NamespaceAlias); // "System_Internal"
public sealed record TypeImport(
string TypeName,
string? Alias,
bool IsValueImport); // true for extends/implements
Import Classification
Value imports (need runtime value):
- Base classes in
extendsclause - Interfaces used in
extends(for merged interface pattern)
Type-only imports:
- Return types
- Parameter types
- Property types
- Generic constraints
// Value import - needed for extends
import * as System_Internal from '../../System/internal/index.js';
// Type-only import - just for type annotations
import type { IEnumerable_1 } from '../../System.Collections/internal/index.js';
EmissionPlanner
Plans the order of file generation.
public sealed record EmissionPlan
{
public SymbolGraph Graph { get; }
public ImportPlan Imports { get; }
public EmissionOrder EmissionOrder { get; }
// Shape pass results
public StaticFlatteningPlan StaticFlattening { get; }
public StaticConflictPlan StaticConflicts { get; }
public OverrideConflictPlan OverrideConflicts { get; }
public PropertyOverridePlan PropertyOverrides { get; }
public SafeToExtendResult SafeToExtend { get; }
}
public sealed record EmissionOrder
{
public ImmutableArray<NamespaceEmitOrder> Namespaces { get; }
}
public sealed record NamespaceEmitOrder
{
public NamespaceSymbol Namespace { get; }
public ImmutableArray<TypeEmitOrder> OrderedTypes { get; }
}
PhaseGate Validation
Validates 50+ invariants before emission:
public static void Validate(BuildContext ctx, EmissionPlan plan)
{
// PG_TYPE_001: All types have final names
// PG_MEMBER_001: All members have final names
// PG_IMPORT_001: No circular imports
// PG_SCOPE_001: Correct scope usage
// ... 46 more rules
}
Validation categories:
- Type naming invariants
- Member naming invariants
- Import/export consistency
- Scope correctness
- Generic constraint validity
Circular Dependency Handling
SCCBucketer handles circular namespace dependencies using Tarjan's algorithm:
// If A imports B and B imports A:
// 1. Detect strongly connected component {A, B}
// 2. Emit types in topological order within SCC
// 3. Use forward declarations where needed