2015-03-20 2 views
4

Я хочу, чтобы получить список всех используемых типов в проекте, например:Получить список ссылочных типов в рамках проекта с Рослинами

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

Я надеялся, что перед компиляцией будет быстрее соответствовать набору используемых типов с набором доступных типов из фреймворка.

С небольшими файлами этот код достаточно быстр, а общая сумма времени меньше, чем общая для компиляции с любой возможной структурой ... но с большими файлами это неприемлемо.

Есть ли способ получить список типов таким образом, который является приемлемым?

+0

Где больше всего процессорного времени потратили? – usr

+0

Вам нужно сделать это перед компиляцией? Возможно, было бы проще посмотреть на скомпилированный IL и найти маркеры methodref и typedef. –

+0

@usr. Самое время процессора находится в 'this.compilation.GetSemanticTodel (x.SyntaxTree) .GetSymbolInfo (x) .Symbol' –

ответ

5

Итак, я узнал урок: никогда не предполагают, что неизменяемая структура будет кэшировать любые его вычисления только потому, что два вызова возвратят тот же результат.

Это правда, что, когда метод является чистым, возврат всегда один и тот же структурно, но он не должен быть одним и тем же экземпляром.

Мое предположение привело меня к ошибке: считая, что this.compilation.GetSemanticModel(id.SyntaxTree) всегда будет возвращать один и тот же экземпляр семантической модели для заданного SyntaxTree ... это неправда.

Я изменил код к следующему, и теперь он молниеносно:

var root = await syntaxTree.GetRootAsync(); 
var nodes = root.DescendantNodes(n => true); 

var st = root.SyntaxTree; 
var sm = this.compilation.GetSemanticModel(st); 

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 => sm.GetSymbolInfo(id).Symbol) 
     .OfType<INamedTypeSymbol>() 
     .ToArray(); 

    this.Add(namedTypes); 

    // ExpressionSyntax: 
    // - method calls 
    // - property uses 
    // - field uses 
    // - all kinds of composite expressions 
    var expressionTypes = syntaxNodes 
     .OfType<ExpressionSyntax>() 
     .Select(ma => sm.GetTypeInfo(ma).Type) 
     .OfType<INamedTypeSymbol>() 
     .ToArray(); 

    this.Add(expressionTypes); 
} 
+1

Вы, вероятно, вычислили всю семантическую модель для каждого посещенного вами узла. – usr

Смежные вопросы