Roslyn Identifies Source Code Modifications

2023年11月21日 132点热度 0人点赞 0条评论
内容目录

Create a new project that only uses netstandard2. The complete content of its csproj file is as follows:

<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>

Then create a type that implements 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);

			// Add generated file to compilation; the file is temporary
			context.AddSource("AAA.cs", newRoot.GetText());

			var updatedDoc = syntaxTree.WithChangedText(newRoot.GetText());

			// Persist the file
			using (var fileStream = new FileStream("BBB.cs", FileMode.Truncate))
			{
				updatedDoc.GetTextAsync().Result.Write(new StreamWriter(fileStream));
			}
		}
	}

	// Responsible for modifying code
	class AOPRewriter : CSharpSyntaxRewriter
	{
		public override SyntaxNode VisitBinaryExpression(BinaryExpressionSyntax node)
		{
			if (node.OperatorToken.IsKind(SyntaxKind.AsteriskToken))
			{
				// Replace x * x with x + x
				var newNode = node.WithOperatorToken(SyntaxFactory.Token(SyntaxKind.PlusToken));
				return newNode;
			}
			return base.VisitBinaryExpression(node);
		}
	}
}

痴者工良

高级程序员劝退师

文章评论