在我的VSPackage中,我需要将代码中的属性的引用替换为其实际值。例如
public static void Main(string[] args) {
Console.WriteLine(Resource.HelloWorld);
}
我想要的是用它的实际值替换“Resource.HelloWorld” - 即找到类Resource并获取其静态属性HelloWorld的值。 Visual Studio是否公开任何API来处理项目的代码模型?它绝对有一个,因为这与重命名变量的常见任务非常相似。我不想在输出程序集上使用反射,因为它很慢并且它会将文件锁定一段时间。
答案 0 :(得分:3)
我知道没有直接的方法来做到这一点。可靠地从Visual Studio中获取AST(以及对其进行更改)始终是一个大问题。 Rosalyn项目的部分目标是创建一种统一的方法,因为许多工具窗口都有自己的方式来做这种事情。
有四种方法可以做到这一点:
<强>符号强>
我相信大多数工具窗口(如CodeView)和Code Element Search之类的东西都使用从编译的构建中创建的符号。这并不理想,因为它的重量更重,很难保持同步。您必须缓存符号才能使其变慢。使用反射器,您可以看到CodeView如何实现它。
此方法使用私有程序集。获取符号的代码如下所示:
var compilerHost = new IDECompilerHost();
var typeEnumerator = (from compiler in compilerHost.Compilers.Cast<IDECompiler>()
from type in compiler.GetCompilation().MainAssembly.Types
select new Tuple<IDECompiler, CSharpType>(compiler, type));
foreach (var typeTuple in typeEnumerator)
{
Trace.WriteLine(typeTuple.Item2.Name);
var csType = typeTuple.Item2;
foreach (var loc in csType.SourceLocations)
{
var file = loc.FileName.Value;
var line = loc.Position.Line;
var charPos = loc.Position.Character;
}
}
FileCodeModel + CodeDOM
您可以尝试使用EnvDTE服务来获取与代码文档关联的FileCodeModel。这将让你获得类和方法。但它不支持获取方法体。你搞乱了错误的COM。这很难看,因为对CodeFunction或CodeClass的COM对象引用可能会在您不知情的情况下被无效,这意味着您必须保留自己的镜像。
<强> Rosalyn AST 强>
这允许提供与FileCodeModel和Symbols相同的功能。我一直在玩这个,实际上并不太糟糕。
未经探索的方法
您可以尝试获取与代码文档关联的基础LanguageServiceProvider。但这真的很难实现,并且给你留下了许多问题。