2015-01-30 3 views
3

와 다른 상속보다 모든 클래스 선언을 찾기 나는 SyntaxTree의 배열을 포함하는 CSharpCompilation 인스턴스를하고 난 클래스로슬린

예를 들어

// Not in syntax tree but referenced in project 
public class Base{} 

// In syntax tree, how to find all such classes? 
public class MyClass : Base {} 
에서 상속하는 모든 클래스 선언을 찾기 위해 노력하고있다

나는 몇 가지 시도를 해봤지만 모든 옵션과 약간 혼란스럽고 올바른 방법을 찾지 못하는 것 같습니다.

나는 기호를 얻기 위해 노력했지만이 상속 유형 로슬린에 아주 새로운

SyntaxTree[] trees = context.CSharpCompilation.SyntaxTrees; 
IEnumerable<ISymbol> symbols = context.CSharpCompilation.GetSymbolsWithName(x => x == typeof(Base).Name, SymbolFilter.Type); 

작동하지 않습니다와이를 달성하는 방법에 대한 제안이나 포인터에 가장 감사 할 것입니다.

답변

0

그래서 나는 재귀 적으로 모든 클래스 선언 구문 목록을 가정 상속 유형

public class BaseClassRewriter : CSharpSyntaxRewriter 
{ 
    private readonly SemanticModel _model; 

    public BaseClassRewriter(SemanticModel model) 
    { 
     _model = model; 
    } 

    public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node) 
    { 
     var symbol = _model.GetDeclaredSymbol(node); 
     if (InheritsFrom<BaseClass>(symbol)) 
     { 
      // hit! 
     } 
    } 

    private bool InheritsFrom<T>(INamedTypeSymbol symbol) 
    { 
     while (true) 
     { 
      if (symbol.ToString() == typeof(T).FullName) 
      { 
       return true; 
      } 
      if (symbol.BaseType != null) 
      { 
       symbol = symbol.BaseType; 
       continue; 
      } 
      break; 
     } 
     return false; 
    } 
} 
+0

제네릭을 처리하지 마십시오. http://source.roslyn.codeplex.com/#Microsoft.CodeAnalysis.Workspaces/Shared/Extensions/ITypeSymbolExtensions.cs,310 – SLaks

+0

ITypeSymbol 및 INamedTypeSymbol의 확장 기능은 유용하지만 현재는 내부 용입니다. 이 코드에 대한 유스 케이스를 확인 했으므로 다행스럽게도 제네릭에 대해 걱정할 필요가 없습니다. 적어도 기본 용도는 제네릭이 아닙니다. –

+0

당신이 할 수있는 일은 당신의 프로젝트에 그것들을 드러내 비공개로 만드는 것입니다. 올 겨울 내 옛 직업에 어떻게 돌아 왔는지 정확하게 말할 수는 없습니다. 우리는 분석을 위해이 클래스들을 사용합니다. –

5

먼저 Base에 대한 기호를 가져와야합니다. 이 유형이 사전에 알고있는 특정 유형 인 경우 Compilation.GetTypeByMetadataName을 사용할 수 있습니다. 이 링크는 사용중인 방법의 100 가지 이상의 예를 보여줍니다.

거기에서 당신이하려는 일에 달려 있습니다. 분석기 내부에서이 작업을 수행하는 경우 (코드에서 "context.CSharpCompilation"으로 의심되는)이 파생 형식의 일부 속성을 확인한 다음 확인하려고하면 SymbolKind에 RegisterSymbolAction을 사용할 수 있습니다. NamedType을 입력 한 다음 각 유형의 BaseType (가능하면 재귀 적으로 반복적으로)을 검사하여 위의 GetTypeByMetadataName에 의해 발견 된 유형을 찾았는지 확인하십시오.

분석가의 컨텍스트 외부에서 솔루션 전체 분석을 수행하는 경우 Roslyn 코드베이스에 helper for this이 있지만 내부적입니다. existing request은 ITypeSymbolExtensions를 공개하기 때문에이 요청에이 스레드를 언급했으며 INamedTypeSymbolExtensions를 포함하도록 확장 해 보겠습니다.

+0

이 유용한 정보를 제공해 주셔서 감사합니다. 사실 저는 SyntaxRewriter에서 이것을하고 있습니다. 몇 시간의 고통이 지나치게 순진한 방법으로 생각해 냈습니다. 정보가 나에게 훨씬 좋은 방법을 보여줄 것입니다. 의견이 아닌 다른 대답으로 코드를 포함하십시오 –

0
var classDecSynList = classDecSynList.Where(x=> 
     (((IdentifierNameSyntax(x.BaseList.Types.FirstOrDefault())) 
       .Identifier.ValueText=="Base")); 

모든 클래스를 확인합니다 다음 함께했다;

관련 문제