2017-05-24 18 views
1

저는 분석기 작성을 시도하고 있습니다. Roslyn을 사용하여 필드에 할당 된 모든 것을 찾아야합니다.Roslyn 필드에 대한 모든 과제 찾기

private async static Task<bool> VariableDoesNotMutate(SyntaxNodeAnalysisContext context, VariableDeclaratorSyntax firstVariable) 
{ 
    var variableSymbol = context.SemanticModel.GetDeclaredSymbol(firstVariable); 
    var references = await SymbolFinder.FindReferencesAsync(variableSymbol, context.GetSolution()); 

    foreach (var reference in references) 
    { 
     //How do I check for assignment? 
    } 

    //need to filter by assignments 
    return references.Count() > 1; 
} 

기호 찾기를 사용하여 들었습니다. 정확하지만 어떻게해야할지 모르겠습니다.
심볼 찾기에는 해킹을 통해 접근 할 수있는 솔루션이 필요하므로이 작업을 수행 할 수있는 다른 방법이 있다고 가정합니다.

문제 :

  1. 난 단지 선언은 내가 어떻게이 문제를 해결할 수있는 다른 참조를 찾을 수없는 반환되는 변수에 대한 모든 참조를 찾아보십시오

    ?

  2. 한 번 참조가있는 경우 어떻게하면 할당인지를 결정할 수 있습니까?

+1

을 당신은 아마 잘못된'Solution' 인스턴스를 검색하는 :이

static async Task<ISymbol> GetEquivalentSymbol(SyntaxNodeAnalysisContext context, FieldDeclarationSyntax field, CancellationToken cancellationToken) { var solution = context.GetSolution(); var classDeclaration = field.Ancestors().OfType<ClassDeclarationSyntax>().FirstOrDefault(); var namespaceDeclaration = field.Ancestors().OfType<NamespaceDeclarationSyntax>().FirstOrDefault(); var className = classDeclaration?.Identifier.ValueText; var initialVariable = field.Declaration.Variables.FirstOrDefault(); foreach (var project in solution.Projects) { foreach (var document in project.Documents) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken); var root = await document.GetSyntaxRootAsync(cancellationToken); if (null != namespaceDeclaration) { var namespaceNode = root.DescendantNodes().OfType<NamespaceDeclarationSyntax>() .FirstOrDefault(node => node.Name.ToString() == namespaceDeclaration.Name.ToString()); if (null == namespaceNode) { continue; } } var classNode = root.DescendantNodes() .OfType<ClassDeclarationSyntax>() .FirstOrDefault(node => node.Identifier.ValueText == className); var desiredField = classNode?.DescendantNodes().OfType<FieldDeclarationSyntax>() .FirstOrDefault(x => x.Declaration.Variables.First().Identifier.ValueText == initialVariable.Identifier.ValueText); if (desiredField == null) { continue; } var symbol = semanticModel.GetDeclaredSymbol(desiredField.Declaration.Variables.FirstOrDefault()); return symbol; } } return null; } 

는 그런 다음과 같이 참조를 얻을 수있는 잠재적 위험합니다. – SLaks

+0

@SLaks 어떻게 심볼에 대한 모든 할당 찾기를 사용할 수 있습니까? 분석기에 공개 된 방법으로 솔루션을 찾을 수없는 경우에는? –

+0

성능상의 이유로 인해서는 안됩니다. – SLaks

답변

0

내 문서가 올바른 해결 방법이 아니기 때문에 원래 참조를 찾을 수 없습니다. 분석기는 솔루션에 도달 할 수있는 방법을 제공하지 않으며 @SLaks가 다음과 같이 말하면 안됩니다.

솔루션을 얻으려면 AnalyzerOptions에 반영해야합니다. do here

그러나 필요한 경우 솔루션에서 동등한 기호 가져 오기를 수행하고 그 작업을 수행 할 수 있습니다.

var equivalentSymbol = await GetEquivalentSymbol(context, field, cancellationToken); 

var references = await SymbolFinder.FindReferencesAsync(equivalentSymbol, context.GetSolution(), cancellationToken);