内容目录
新建一个项目,项目只能使用 netstandard2。
其 csproj 文件完整内容如下:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
<IsRoslynComponent>true</IsRoslynComponent>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
</ItemGroup>
</Project>
然后创建一个 实现了 ISourceGenerator 的类型。
[Generator]
public class AOPSourceGenerator : ISourceGenerator
{
public void Initialize(GeneratorInitializationContext context)
{
}
public void Execute(GeneratorExecutionContext context)
{
Debugger.Launch();
SyntaxTree syntaxTree = context.Compilation.SyntaxTrees.FirstOrDefault();
if (syntaxTree != null)
{
var root = syntaxTree.GetCompilationUnitRoot();
var rewriter = new AOPRewriter();
var newRoot = rewriter.Visit(root);
// 生成文件添加到编译中,文件是临时文件
context.AddSource("AAA.cs", newRoot.GetText());
var updatedDoc = syntaxTree.WithChangedText(newRoot.GetText());
// 持久化保存文件
using (var fileStream = new FileStream("BBB.cs", FileMode.Truncate))
{
updatedDoc.GetTextAsync().Result.Write(new StreamWriter(fileStream));
}
}
}
// 负责修改代码
class AOPRewriter : CSharpSyntaxRewriter
{
public override SyntaxNode VisitBinaryExpression(BinaryExpressionSyntax node)
{
if (node.OperatorToken.IsKind( SyntaxKind.AsteriskToken))
{
// 将 x * x 替换为 x + x
var newNode = node.WithOperatorToken(SyntaxFactory.Token(SyntaxKind.PlusToken));
return newNode;
}
return base.VisitBinaryExpression(node);
}
}
}
文章评论