2017-10-10 3 views
0

특정 인터페이스를 구현하는 개체의 개체 이니셜 라이저 안의 setter 속성에 대한 모든 호출을 분석기에서 감지하도록하고 싶습니다. 나는 그것을 감지하는 방법에 대한 약간의 손실이 있으며, 문서는 약간 얇다. 호출 식을 얻을 수 있지만 개체 이니셜 라이저 내부에 있는지 확인하는 방법은 무엇입니까?Roslyn Analyzer Object initializer

아이디어가 있으십니까?

+1

구문 비주얼라이저를 사용하여 구문 트리의 모양을 확인하십시오. – SLaks

답변

1

특정 코드가 객체 이니셜 라이저 안에 있는지 알아 보려면 InitializerExpressionSyntax 유형의 모든 노드에 대한 조상을 찾아 볼 수 있습니다.

var initializer = node.Ancestors().OfType<InitializerExpressionSyntax>.FirstOrDefault(); 

특정 코드가 속성 설정자에게 할당되었는지 확인하려면 더 많은 작업을 수행해야합니다. 너 SemanticModelAssignmentExpressionSyntax에 할당 된 기호가 있는지 물어볼 필요가 있습니다. 분석기는 해당 인수/컨텍스트에서 올바른 SemanticModelSyntaxTree에 액세스해야합니다.

SemanticModel model = ...; 
AssignmentExpressionSyntax assignment = ...; // find the assignment 
var symbol = model.GetSymbolInfo(assignment).Symbol as IMethodSymbol; 
if (symbol?.MethodKind == MethodKind.PropertySet) { ... } 

개체가 특정 인터페이스를 구현하는지 확인하려면 개체 기호를 찾아야합니다. 속성 설정 기호의 포함 기호 체인을 검색하여 찾을 수 있습니다. 이미 가지고있는 InitializerExpressionSyntax의 부모 또는 조상이되어야하는 ObjectCreationExpressionSyntax을 찾아 개체의 상징을 찾을 수도 있습니다.

일단 생성 노드가 있으면 SemanticModel에게 다시 요청할 수 있습니다. GetTypeInfo 메서드를 사용하여 생성자의 심볼이 아닌 표현식의 유형 (생성되는 유형/심볼)을 가져옵니다.

var creation = initializer.Ancestors().OfType<ObjectCreationSyntax>().FirstOrDefault(); 
var createdType = model.GetTypeInfo(creation).Type as INamedTypeSymbol; 

이제 유형이 인터페이스를 구현하는지 알아야합니다.

먼저 인터페이스 유형에 대한 기호가 필요합니다. 이를 얻는 한 가지 빠른 방법은 CLR 메타 데이터 이름을 사용하여 검색하는 것입니다.

var interfaceType = model.Compilation.GetTypeByMetadataName("MyNamspace.MyInterfaceType"); 

이 부분

은 일반적으로 분석기의 초기화에 한 번 이루어집니다, 그래서 당신은 계속해서 또 다시, 그것을 계속 찾고 필요가 없습니다.

이제 건설중인 유형이 인터페이스를 구현하는 경우 발견해야 할 모든 것이 있습니다.

if (createdType.AllInterfaces.Contains(interfaceType)) { ... }