【发布时间】:2015-03-20 22:10:55
【问题描述】:
我想获取一个项目中所有使用类型的列表,例如:
var x = 1;
var y = x.ToString().GetType();
代码应返回System.Int32、System.String、System.Type。
我所拥有的太慢了...对于每个文件(语法树),我执行以下操作:
var root = await syntaxTree.GetRootAsync();
var nodes = root.DescendantNodes(n => true);
if (nodes != null)
{
var syntaxNodes = nodes as SyntaxNode[] ?? nodes.ToArray();
// IdentifierNameSyntax:
// - var keyword
// - identifiers of any kind (including type names)
var namedTypes = syntaxNodes
.OfType<IdentifierNameSyntax>()
.Select(id => this.compilation
.GetSemanticModel(id.SyntaxTree)
.GetSymbolInfo(id)
.Symbol)
.OfType<INamedTypeSymbol>()
.ToArray();
// add the found types to the list
this.AddRange(namedTypes);
// ExpressionSyntax:
// - method calls
// - property uses
// - field uses
// - all kinds of composite expressions
var expressionSyntaxs = syntaxNodes
.OfType<ExpressionSyntax>()
.ToList();
var typeSymbols = new List<ITypeSymbol>();
for (int index = 0; index < expressionSyntaxs.Count; index++)
{
ExpressionSyntax ma = expressionSyntaxs[index];
typeSymbols.Add(this.compilation
.GetSemanticModel(ma.SyntaxTree)
.GetTypeInfo(ma)
.Type);
}
var expressionTypes = typeSymbols
.OfType<INamedTypeSymbol>()
.ToArray();
// add the found types to the list
this.AddRange(expressionTypes);
}
动机:
我正在制作一个分析项目的工具,并告诉哪些 .Net 框架版本支持给定项目(例如便携式 .Net 框架)。
我希望在编译之前将一组使用的类型与一组可用的类型从框架中匹配起来会更快。
对于小文件,这段代码足够快,并且总时间少于编译所有可能的框架的时间......但是对于大文件,这是不可接受的。
有没有办法以可接受的方式获取类型列表?
【问题讨论】:
-
CPU 时间花在哪里?
-
编译前需要这样做吗?也许查看编译后的 IL 并找到 methodref 和 typedef 标记会更容易。
-
@usr 大多数CPU时间在
this.compilation.GetSemanticModel(x.SyntaxTree).GetSymbolInfo(x).Symbol -
@KevinPilch-Bisson 我已经有一个默认编译。加载项目后,我调用
this.compilation = await project.GetCompilationAsync()。从第一次编译开始,我检测使用的类型、匹配框架,然后对于每个匹配项,我使用从第一个版本更改为这个版本的引用进行构建。