# SourceGenerators.Shared
**Repository Path**: util-core/SourceGenerators.Shared
## Basic Information
- **Project Name**: SourceGenerators.Shared
- **Description**: 源生成器共享源码包
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-11-03
- **Last Updated**: 2026-11-06
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# SourceGenerators.Shared
源生成器共享源码包。包内只有 `.cs` 源码和 `buildTransitive` props,不产生 `lib/`、`ref/` 或 `analyzers/` 资产。
## 使用
在**源生成器项目**引用包:
```xml
```
`PrivateAssets="all"` 防止该包进入生成器发布后的依赖。
props 会把以下源码编入当前项目,命名空间为 `SourceGenerators.Shared.Internal`,类型均为 `internal`:
```
SourceGenerators.Shared\Usings.cs
SourceGenerators.Shared\Internal\CompilationIndex.cs
SourceGenerators.Shared\Internal\GeneratedSource.cs
SourceGenerators.Shared\Internal\HintNameAllocator.cs
SourceGenerators.Shared\Internal\ImportScope.cs
SourceGenerators.Shared\Internal\DefaultValueFormatter.cs
SourceGenerators.Shared\Internal\TypeNameText.cs
```
`Usings.cs` 是全局 using,会作用于当前项目。
### 项目
```xml
netstandard2.0
10.0
true
true
false
```
### 生成器
```csharp
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using SourceGenerators.Shared.Internal;
namespace Demo;
[Generator]
public sealed class CustomerGenerator : IIncrementalGenerator {
public void Initialize( IncrementalGeneratorInitializationContext context ) {
context.RegisterSourceOutput( context.CompilationProvider, static ( context, compilation ) => {
var index = CompilationIndex.From( compilation, context.CancellationToken );
if( index.TypeExists( "Demo.Customer" ) == false )
return;
var customer = compilation.GetTypeByMetadataName( "Demo.Customer" );
if( customer == null )
return;
var scope = new ImportScope( index, new[] { "System" }, new ITypeSymbol[] { customer } );
var body = "internal static class CustomerProbe { internal static System.Type Type => typeof( Customer ); }";
var source = GeneratedSource.Wrap( body, scope.Imports, "Demo.Generated" );
context.AddSource( "CustomerProbe.g.cs", SourceText.From( source, Encoding.UTF8 ) );
} );
}
}
```
`ImportScope` 的第二个参数是预置 `using`,第三个参数是本次生成用到的类型;`GeneratedSource.Wrap` 负责文件头、命名空间和 `using`。
## 兼容性
- 源码使用 `netstandard2.0` 可用的 BCL API 和 C# 10 语法;
- 测试项目使用 **net8.0 + C# 10 + Microsoft.CodeAnalysis.CSharp 4.8.0** 验证,更新版本同样可用;
- 消费方至少需要 C# 10。
## API 说明
### CompilationIndex
`CompilationIndex.From( compilation )` 建立名称索引,用于 `TypeExists`、`ContainsNamespace`、`HasNamespaceMember` 探测。同一 `Compilation` 实例的索引会被缓存,可重复调用;已有索引时优先使用 `ImportScope( index, ... )` 构造重载,避免重复遍历。
### ImportScope
`ImportScope` 按生成产物实际引用的类型动态构建 `using` 清单,并规避短名歧义。短名是优先结果:只有命名空间未导入或短名冲突时,才把头部限定为全名,泛型实参与嵌套类型链仍尽量使用短名。例如:
```csharp
// using Lib; 时
// Outer.Inner
// Lib 未导入或 Outer 冲突时
// global::Lib.Outer.Inner
```
嵌套泛型会完整保留外层类型及其实参;关键字标识符输出为 `@class` 形式。`System` 的 `using` 不会自动覆盖 `System.Text` 等子命名空间,子命名空间需要显式加入框架 using 清单或由引用类型自动带入。
命名空间冲突自动处理:候选命名空间与已导入清单存在重名顶层类型时,自动只保留先进入清单者,被排除命名空间下实际用到的简单类型生成确定性别名,其余类型保留全限定名。例如:
```csharp
// Lib.A 与 Lib.B 都有 Widget 时
// using Lib.A; // 保留优先者
// using LibBWidget = global::Lib.B.Widget; // 被排除侧生成别名
// Reference: Widget / LibBWidget
```
别名只覆盖简单类型名;泛型与嵌套类型在被排除命名空间下仍输出 `global::` 全限定名。框架 using 清单由调用方负责,内部即使存在重名类型也原样保留。
### GeneratedSource
`GeneratedSource.Wrap` 的生成命名空间由调用方传入:
```csharp
var text = GeneratedSource.Wrap( inner, imports, "YourProduct.Internal.Generated" );
```
`GeneratedSource.Reference` 同样遵循“短名优先”:命名空间已导入时使用短名,未导入时只限定头部,类型实参与嵌套链继续缩短。
### HintNameAllocator
`HintNameAllocator` 统一分配生成文件名:短名后接 `.g.cs`,非法字符转为下划线;撞名时在扩展名前追加 `_2`、`_3` 序号。需要预留的固定文件名通过构造参数传入,同样按短名书写。
```csharp
var allocator = new HintNameAllocator( new[] { "SharedInitializer" } );
var fileName = allocator.Allocate( "Order" );
context.AddSource( fileName, SourceText.From( source, Encoding.UTF8 ) );
```
### DefaultValueFormatter
`DefaultValueFormatter.Format( parameter )` 输出参数默认值字面量;无法表达时返回 `null`,或使用 `DefaultValueFormatter.Omitted` 省略默认值。可空类型按基础类型解析和输出(例如 `Level?` 的默认值仍保留枚举转换),字符串与字符字面量会转义控制字符、行分隔符与代理项。
## 作者
何镇汐
## 许可
MIT