2014-04-21 1 views
4

코드 수정 프로젝트 진단의 현재 작업 공간 (예 : 프로젝트 경로, 솔루션 경로)에 대한 정보를 얻으려면 어떻게해야합니까?Roslyn : 코드 수정 프로젝트로 진단의 현재 작업 공간

나는

내가하지만 그렇게, 나는 솔루션 인스턴스를

편집이 필요 SymbolFinder.FindImplementationsAsync에 접근 할 필요가 ISyntaxNodeAnalyzer

유형의 진단을 구현하고있다 : 나는 다음과 같은 코드가 있습니다

var syntax = (LocalDeclarationStatementSyntax) node; 
var type = syntax.Declaration.Type; 
var typeSymbol = semanticModel.GetTypeInfo(type).ConvertedType; 

typeSymbol의 모든 사용법/참조를 찾고 싶습니다. TypeSymbol은 소스 코드에있는 Class를 나타냅니다.

이렇게하려면 SymbolFinder를 사용하고 싶었지만 SymbolFinder의 메서드에는 Solution 인스턴스가 필요합니다. Roslyn의 이전 버전에서는 문서가 진단의 메서드 매개 변수로 제공되었으므로 프로젝트 및 솔루션을 얻을 수있었습니다.

답변

6

진단 분석기를 구현할 때 작업 영역에 있거나 다중 프로젝트 분석을 수행하는 현재 방법은 명령 줄 컴파일러 만 사용하여 단일 컴파일에 대해 실행할 수 있어야하므로 현재로서는 없습니다. 그러나 진단이 결정되면 코드 수정 공급자에서이 작업을 수행 할 수 있습니다.

한 번 클래스가 다른 클래스를 구현하는 모든 장소를 찾고 싶다면 광범위한 진단 분석기를 만들고 진단을 결정하기 전에 모든 선언을 검토 할 수 있습니다. ICompilationStartedAnalyzer와 ICompilationEndedAnalyzer를 모두 구현하여이 작업을 수행 할 수 있습니다.

+0

은 어떻게 든 실제 진단에서 솔루션 인스턴스를받을 수 있습니까? 또는 문서 인스턴스? Roslyn의 이전 버전에는 메소드 매개 변수로 Document가 있습니다. –

+0

또는 현재 진단중인 솔루션 경로를 가져올 수 있습니까? –

+0

당신은 그것들에 도달 할 수 없습니다 - 컴파일러 수준에서 그러한 것들이 존재한다는 보장은 없습니다. 진단 내용을 설명하기 위해 질문을 업데이트하면 더 나은 지침을 제공 할 수 있습니다. –

2

정말로 이것을 할 필요가 있지만, 반사를 통해 모든 환경에서 작동 할 수는 없습니다 ... 저는 Windows 환경에서만 이것을 테스트했습니다.

public static class RoslynExtensions 
{ 
    public static Solution GetSolution(this SyntaxNodeAnalysisContext context) 
    { 
     var workspace = context.Options.GetPrivatePropertyValue<object>("Workspace"); 
     return workspace.GetPrivatePropertyValue<Solution>("CurrentSolution"); 
    } 

    public static T GetPrivatePropertyValue<T>(this object obj, string propName) 
    { 
     if (obj == null) 
     { 
      throw new ArgumentNullException(nameof(obj)); 
     } 

     var pi = obj.GetType().GetRuntimeProperty(propName); 

     if (pi == null) 
     { 
      throw new ArgumentOutOfRangeException(nameof(propName), $"Property {propName} was not found in Type {obj.GetType().FullName}"); 
     } 

     return (T)pi.GetValue(obj, null); 
    } 
} 

은과 같이 분석기에서 호출 :

public override void Initialize(AnalysisContext context) 
{ 
    context.RegisterSyntaxNodeAction(AnalyzeConstDeclaration, SyntaxKind.FieldDeclaration); 
} 

public static void AnalyzeConstDeclaration(SyntaxNodeAnalysisContext context) 
{ 
    var solution = context.GetSolution(); 
}