Я хочу, чтобы получить список всех используемых типов в проекте, например:Получить список ссылочных типов в рамках проекта с Рослинами
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 Framework поддерживают данный проект (например, Portable .Net Frameworks).
Я надеялся, что перед компиляцией будет быстрее соответствовать набору используемых типов с набором доступных типов из фреймворка.
С небольшими файлами этот код достаточно быстр, а общая сумма времени меньше, чем общая для компиляции с любой возможной структурой ... но с большими файлами это неприемлемо.
Есть ли способ получить список типов таким образом, который является приемлемым?
Где больше всего процессорного времени потратили? – usr
Вам нужно сделать это перед компиляцией? Возможно, было бы проще посмотреть на скомпилированный IL и найти маркеры methodref и typedef. –
@usr. Самое время процессора находится в 'this.compilation.GetSemanticTodel (x.SyntaxTree) .GetSymbolInfo (x) .Symbol' –