- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想重构(添加前缀)本地声明的方法及其在 .cs
中的用法文件
实现这一目标的最佳实践是什么?
我当前的代码只处理声明
using System;
using System.IO;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace CodeScanner {
internal sealed class Fixer : CSharpSyntaxRewriter {
public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node) {
base.VisitInvocationExpression(node);
// replace usages
return node;
}
public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node) {
base.VisitMethodDeclaration(node);
return node.ReplaceNode(node, SyntaxFactory.MethodDeclaration(
node.AttributeLists,
node.Modifiers,
node.ReturnType,
node.ExplicitInterfaceSpecifier,
SyntaxFactory.Identifier("prefix_" + node.Identifier.Value),
node.TypeParameterList,
node.ParameterList,
node.ConstraintClauses,
node.Body,
node.ExpressionBody));
}
}
class Program {
static void Main(string[] args) {
var tree = CSharpSyntaxTree.ParseText(File.ReadAllText("./test.cs"));
var rewriter = new Fixer();
var result = rewriter.Visit(tree.GetRoot());
Console.WriteLine(result.ToFullString());
}
}
}
输入文件
using System;
namespace TopLevel
{
class Bar {
public void test1(){}
public void test2(){ Console.WriteLine("str"); }
public void Fizz() {
Console.WriteLine(test1());
Console.WriteLine(test1(test2()));
test2();
}
}
}
输出
using System;
namespace TopLevel
{
class Bar {
public void prefix_test1(){}
public void prefix_test2(){ Console.WriteLine("str"); }
public void prefix_Fizz() {
Console.WriteLine(test1());
Console.WriteLine(test1(test2()));
test2();
}
}
}
所需的输出(更改 @ Fizz ):
using System;
namespace TopLevel
{
class Bar {
public void prefix_test1(){}
public void prefix_test2(){ Console.WriteLine("str"); }
public void prefix_Fizz() {
Console.WriteLine(prefix_test1());
Console.WriteLine(prefix_test1(prefix_test2()));
prefix_test2();
}
}
}
最佳答案
我编写了一些符合您设置的要求的代码。
见 .NET Fiddle
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using static Globals;
tree = CSharpSyntaxTree.ParseText(File.ReadAllText("Test.cs"));
compilation = CSharpCompilation.Create("HelloWorld").AddSyntaxTrees(tree);
model = compilation.GetSemanticModel(tree);
new Finder().Visit(tree.GetRoot());
Console.WriteLine(new Rewriter().Visit(tree.GetRoot()).NormalizeWhitespace().ToFullString());
public static class Globals
{
public static SyntaxTree tree;
public static CompilationUnitSyntax root;
public static CSharpCompilation compilation;
public static SemanticModel model;
public static Dictionary<IMethodSymbol, string> renames = new();
}
public sealed class Finder : CSharpSyntaxWalker
{
public override void VisitMethodDeclaration(MethodDeclarationSyntax node)
{
base.VisitMethodDeclaration(node);
renames.Add(model.GetDeclaredSymbol(node), "prefix_" + node.Identifier.Value);
}
}
public sealed class Rewriter : CSharpSyntaxRewriter
{
public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax mds)
{
IMethodSymbol symbol = model.GetDeclaredSymbol(mds);
mds = (MethodDeclarationSyntax)base.VisitMethodDeclaration(mds);
if (renames.TryGetValue(symbol, out string newName))
mds = mds.ReplaceToken(mds.Identifier, SyntaxFactory.Identifier(newName));
return mds;
}
[return: NotNullIfNotNull("node")]
public override SyntaxNode Visit(SyntaxNode node)
{
node = base.Visit(node);
if (node is SimpleNameSyntax sns &&
model.GetSymbolInfo(sns) is { Symbol: IMethodSymbol ms } && renames.TryGetValue(ms, out string newName)
)
node = sns.ReplaceToken(sns.Identifier, SyntaxFactory.Identifier(newName));
return node;
}
}
关于C# Roslyn 替换方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69163967/
最初的问题是我有一个巨大的解决方案,其中项目有不同的选项(例如,x64 或 x86 配置、是否允许不安全代码等等)。我正在尝试使用 Roslyn (2.9.0) 通过 DEBUG x64 配置来编译\
当前的 .Net 编译器是完全独立的。 Roslyn 应该将它们组合成一个编译器。有谁知道这是否会引入在单个项目中使用多种语言的能力?或者甚至可能在单个文件/类中? 目前您能做的最好的事情就是在一个解
我已经开始使用 Roslyn 的语法和语义 API。还没有真正深入挖掘,但是语义 API 是否提供了任何代码优化,例如: 消除死代码,吊装或某种指针分析?或者其他分析? 我知道 roslyn 提供了
Roslyn 似乎提供了新的 API 来公开许多编译器内部数据结构以进行代码分析等。为此目的重写了 C# 和 VB 编译器。那么除了新的 API 之外,我还可以访问编译器源代码吗? 最佳答案 Rosl
我的解决方案在 roslyn 中构建正常,因此应该解析所有类型 我能够像这样获取在元数据程序集中定义的类型: string typeName = "MyCompany.MyLibrary.MyType
Roslyn 项目中的 CaaS(编译器即服务)是什么? 与当前 C# 4.0 编译器相比,使用 Roslyn 功能如何提高 C# 应用程序的性能? Roslyn-CTP 有哪些已知的限制/问题? 最
我们最近将构建系统从 VS 2013 升级到 2015 Update 2,构建时间显着增加。我们的构建环境是独立的,因此我们从包(使用 devpath)而不是从安装位置运行 MSBuild。查看日志,
我正在为 Roslyn 制作一个分析器。我正在做的是一种诊断,可以找到太长的方法。我想对任何被认为“太长”的内容进行可配置,最好是整个解决方案或项目的一种配置。解决这个问题的最佳方法是什么? 我想到的
如果我想在我的应用程序中支持脚本,是否 scriptcs提供比仅使用普通 Vanilla 的任何特殊优势 Roslyn脚本引擎? 最佳答案 不幸的是,目前还没有太多关于托管 scriptcs 的文档,
我创建了这个测试控制台应用程序,以使用 Roslyn 脚本引擎(在 Microsoft.CodeAnalysis.CSharp.Scripting nuget 包中)运行一些 C# 代码。
我对 stackoverflow 做了一些研究,但找不到我需要的结果。 我的问题是“如何使用 Roslyn 确定源文件的行代码位置”。 例如:我有一个源文件(名为:sample.cs)和它看起来像的内
来自 Visual Studio 2015 CTP5 包,如何获取当前的 Roslyn 工作区? 我在看 How to get reference to 'Roslyn' Workspace obje
我想在另一个非脚本 Roslyn 编译中将脚本作为动态程序集重用,但我终究无法弄清楚如何实现它。 例如,假设我以正常方式创建脚本,然后使用类似以下内容将脚本作为程序集发送到字节流: var compi
我使用 VS 2015 模板创建了一个 Roslyn 分析器。假设默认情况下启用了诊断,我的一切正常,包括单元测试。 如果我将DiagnosticDescriptor 上的isEnabledByDef
如何从 ITypeSymbol 获取基础类型对于 IEnumerable ?我明白了ITypeSymbol.OriginalDefinition包含指向 IEnumerable<> 的链接,但是我在哪
我有一个 VS 包项目,我需要从加载的 IVsSolution 访问 Roslyn 或 Microsoft.CodeAnalysis 的工作区或解决方案对象. 我需要知道如何实现这一目标? 我找到了t
我在做什么用一句话 查看分行 Update-1来自 Roslyn github repository ,构建 csc.exe,并使用我自己构建的 csc.exe 版本编译随机解决方案。 预期结果 我希
在我投入大量时间学习 roslyn 编译器服务之前,我想问一下 roslyn 是否可以实现以下场景。是否可以编译程序集而无需将任何内容写入磁盘并执行它?我基于元模型生成完整的解决方案,我想采用它并编译
我有一个带有两个输出 dll 的解决方案(实际上更多,但让我们保持简单)。项目“Special”引用项目“Common”。 我尝试编写一个代码生成器来解析“Special”中的一些文件,并将生成的 s
我创建了几个诊断分析器和代码修复。它们都按照预期在实验 hive 中工作。 我将它们构建为 Nuget 包,并添加到 VS2015 正常实例中的项目中。奇怪的是,分析器/代码修复组合之一可以正常工作,
我是一名优秀的程序员,十分优秀!