수색…


MSBuild 프로젝트에서 작업 공간 생성

계속하기 전에 먼저 Microsoft.CodeAnalysis.CSharp.Workspaces Nuget을 가져옵니다.

var workspace = Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Create();
var project = await workspace.OpenProjectAsync(projectFilePath);
var compilation = await project.GetCompilationAsync();

foreach (var diagnostic in compilation.GetDiagnostics()
    .Where(d => d.Severity == Microsoft.CodeAnalysis.DiagnosticSeverity.Error))
{
    Console.WriteLine(diagnostic);
}

작업 영역에 기존 코드를로드하려면 오류를 컴파일하고보고하십시오. 그 후 코드가 메모리에 저장됩니다. 여기에서 통사론과 의미 론적 측면 모두를 사용할 수 있습니다.

구문 트리

구문 트리 (Syntax Tree) 는 프로그램을 이름, 명령 및 표시의 트리로 나타내는 불변의 데이터 구조입니다 (이전에 편집기에서 구성한대로).

예를 들어 compilation 이라는 Microsoft.CodeAnalysis.Compilation 인스턴스가 구성되어 있다고 가정합니다. 로드 된 코드에서 선언 된 모든 변수의 이름을 나열하는 여러 가지 방법이 있습니다. 이렇게 순진하게하기 위해서는 모든 문서 ( DescendantNodes 메소드)의 모든 구문을 가져 와서 Linq를 사용하여 변수 선언을 설명하는 노드를 선택하십시오.

foreach (var syntaxTree in compilation.SyntaxTrees)
{
    var root = await syntaxTree.GetRootAsync();
    var declaredIdentifiers = root.DescendantNodes()
        .Where(an => an is VariableDeclaratorSyntax)
        .Cast<VariableDeclaratorSyntax>()
        .Select(vd => vd.Identifier);

    foreach (var di in declaredIdentifiers)
    {
        Console.WriteLine(di);
    }
}

해당 유형을 가진 모든 유형의 C # 구문이 구문 트리에 존재합니다. 특정 유형을 빨리 찾으려면 Visual Studio의 Syntax Visualizer 창을 사용하십시오. 그러면 현재 열려있는 문서가 Roslyn 구문 트리로 해석됩니다.

시맨틱 모델

시맨틱 모델 (Semantic Model) 은 구문 트리와 비교하여 코드 해석 및 통찰력이 더 깊다. 구문 트리가 변수의 이름을 말할 수있는 곳에서 의미 론적 모델은 유형과 모든 참조를 제공합니다. 구문 트리는 메서드 호출을 인식하지만 의미 론적 모델은 메서드가 선언 된 정확한 위치에 대한 참조를 제공합니다 (오버로드 확인이 적용된 후).

var workspace = Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Create();
var sln = await workspace.OpenSolutionAsync(solutionFilePath);
var project = sln.Projects.First();
var compilation = await project.GetCompilationAsync();

foreach (var syntaxTree in compilation.SyntaxTrees)
{
    var root = await syntaxTree.GetRootAsync();

    var declaredIdentifiers = root.DescendantNodes()
        .Where(an => an is VariableDeclaratorSyntax)
        .Cast<VariableDeclaratorSyntax>();

    foreach (var di in declaredIdentifiers)
    {
        Console.WriteLine(di.Identifier);
        // => "root"

        var variableSymbol = compilation
            .GetSemanticModel(syntaxTree)
            .GetDeclaredSymbol(di) as ILocalSymbol;

        Console.WriteLine(variableSymbol.Type);
        // => "Microsoft.CodeAnalysis.SyntaxNode"

        var references = await SymbolFinder.FindReferencesAsync(variableSymbol, sln);
        foreach (var reference in references)
        {
            foreach (var loc in reference.Locations)
            {
                Console.WriteLine(loc.Location.SourceSpan);
                // => "[1375..1379)"
            }
        }
    }
}

구문 트리를 사용하여 로컬 변수 목록을 출력합니다. 그런 다음 의미 론적 모델을 참조하여 전체 유형 이름을 얻고 모든 변수의 모든 참조를 찾습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow