2017-11-03 5 views
1

와 속성에서 종류 : 내가하고 싶은 무엇나는 이런 식으로 뭔가 보이는 몇 가지 코드를 해석하기 위해 노력하고있어 로슬린 사용 로슬린

public class Foo 
{ 
    public override Type BarType 
    { 
     get { return typeof(MyBar); } 
    } 
} 

는 상징으로 그 유형을 얻을 다음 MyBar을 얻고입니다, 하지만 이것이 가능하거나 실용적인 것이라 할지라도 나는 확신하지 못합니다. 나는이 클래스 클래스에서 파생되는 클래스를 몇 개 가지게 될 것입니다.

감안할 때 ClassDeclarationSyntaxFoo, 나는이 수행 할 수

var prop = syntax.DescendantNodes().OfType<PropertyDeclarationSyntax>() 
       .FirstOrDefault(p => p.Identifier.ToString() == "BarType"); 

또는 제공을 INamedTypeSymbolFoo, 나는이 수행 할 수

var member = symbol.GetMembers("BarType").FirstOrDefault(); 

을하지만, 어디로 가야 정보를 얻을수 있는지 모른다 거기에서.

궁극적으로 나는 추가 분석을 위해 MyBar에 대한 심볼을 얻을 수 있기를 원하므로 어쨌든 문자열 "MyBar"을 얻는 것은 정규화되지 않았기 때문에 도움을주지 않을 것입니다.

제안 사항?

편집 :

가이 같은 프로젝트 및 편집을 받고 있어요 :

var workspace = MSBuildWorkspace.Create(); 
var project = workspace.OpenProjectAsync(projectPath).Result; 
var compilation = project.GetCompilationAsync().Result; 

compilation 여기 CSharpCompilation이다. 나는이 GetTypeSymbol 방법을 갖고있는 것 같다하지 않는 SyntaxTreeSemanticModel로 끝날 model 얻을

foreach (var doc in project.Documents) 
{ 
    Console.WriteLine($"Analyzing {doc.Name}"); 

    //var model = doc.GetSemanticModelAsync().Result; 
    var tree = doc.GetSyntaxTreeAsync().Result; 
    var root = tree.GetRoot(); 
    var model = compilation.GetSemanticModel(tree); 
    var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>(); 

    foreach (var syntax in classes) 
    { 
     var symbol = model.GetDeclaredSymbol(syntax); 
     //... need to analyze properties in the class here... 
    } 
} 

어느 방법 : 거기에서 나는 이런 일을한다.

답변

2

Compilation (& 구성 참조)에서 오는 시맨틱 모델이 필요합니다.

그러면 해당 노드에서 GetTypeSymbol()을 호출하여 INamedTypeSymbol으로 전송할 수 있습니다.

+0

당신이 조금하시기 바랍니다 정교한 수

var classDeclarationSyntaxs = root.DescendantNodes().OfType<ClassDeclarationSyntax>(); foreach (var classDeclarationSyntax in classDeclarationSyntaxs) { var propertyDeclarationSyntaxs = classDeclarationSyntax.Members.OfType<PropertyDeclarationSyntax>(); var barTypePropertyDeclarationSyntax = propertyDeclarationSyntaxs.FirstOrDefault(p => p.Identifier.Text == "BarType"); if (barTypePropertyDeclarationSyntax != null) { var returnStatementSyntax = barTypePropertyDeclarationSyntax.DescendantNodes().OfType<ReturnStatementSyntax>().FirstOrDefault(); if (returnStatementSyntax != null) { var typeOfExpressionSyntax = returnStatementSyntax.ChildNodes().OfType<TypeOfExpressionSyntax>().FirstOrDefault(); if (typeOfExpressionSyntax != null) { var symbolInfo = semanticModel.GetSymbolInfo(typeOfExpressionSyntax.Type); var symbolInfoSymbol = symbolInfo.Symbol; } } } } 

또한 이것에 대한 SyntaxWalker을 사용할 수 있습니다 다음 SemanticModel하면이 같은 SymbolInfo을받을 수 있나요? 'member'에'GetTypeSymbol'을 찾을 수 없습니다. –

+0

@MattBurland : 그 방법은'SemanticModel'에 있습니다. 이것은'Compilation' 또는'Project'에서옵니다. – SLaks

+0

도움을 주셔서 감사합니다.하지만 아직 보지 못했습니다. 나는 내가하려고하는 것을 더 포함시키기 위해 약간의 질문을 편집했다. 나는'project.GetCompilationAsync(). Result'로부터 컴파일을 얻었고 컴파일로부터'SemanticModel'을 얻을 수 있습니다.GetSemanticModel (tree)', 그러나 결과 모델은 여전히'GetTypeSymbol()'메소드를 가지고 있지 않다. –

1

ReturnStatementSyntaxTypeOfExpressionSyntax을 찾아야합니다. 여기에는 MyBar 유형이 포함됩니다.

public class TypeOfSyntaxWalker : CSharpSyntaxWalker 
{ 
    private readonly SemanticModel _semanticModel; 

    public ISymbol SymbolInfoSymbol { get; private set; } 

    public TypeOfSyntaxWalker(SemanticModel semanticModel) 
    { 
     _semanticModel = semanticModel; 
    } 

    public override void VisitTypeOfExpression(TypeOfExpressionSyntax typeOfExpressionSyntax) 
    { 
     var parent = typeOfExpressionSyntax.Parent; 
     if (parent.Kind() == SyntaxKind.ReturnStatement) 
     { 
      var propertyDeclarationSyntax = parent.FirstAncestorOrSelf<PropertyDeclarationSyntax>(); 
      if (propertyDeclarationSyntax != null && 
        propertyDeclarationSyntax.Identifier.ValueText == "BarType") 
      { 
       var symbolInfo = _semanticModel.GetSymbolInfo(typeOfExpressionSyntax.Type); 
       SymbolInfoSymbol = symbolInfo.Symbol; 
      } 
     } 
     base.VisitTypeOfExpression(typeOfExpressionSyntax); 
    } 
} 

가 사용 :

var classDeclarationSyntaxs = root.DescendantNodes().OfType<ClassDeclarationSyntax>(); 
foreach (var classDeclarationSyntax in classDeclarationSyntaxs) 
{ 
    var typeOfSyntaxWalker = new TypeOfSyntaxWalker(semanticModel); 
    typeOfSyntaxWalker.VisitClassDeclaration(classDeclarationSyntax); 
    var symbolInfoSymbol = typeOfSyntaxWalker.SymbolInfoSymbol; 
}