2014-11-07 3 views
2
나는 ReSharper에서의 탐색 플러그인을 쓰고 있어요, 내 상황은 내가

어떻게이있는 IClrDeclaredElement에서 IDeclaredType를 얻을 않는 ReSharper에서 SDK

var declaredElements = context.GetData(DataConstants.DECLARED_ELEMENTS) 

이 일에서 얻은 IDeclaredElement의 목록을 가지고있다

요소는 사용자가 마우스 커서를 놓은 요소입니다.

내가 원하는 것은 모든 유형 매개 변수를 포함하여 선언 된 요소의 IDeclaredType을 얻는 것입니다.이 경우 일반 유형입니다.

The resharper SDK documentation is quite light when it comes to the type system 실제로 다양한 유형 간의 관계를 설명하지는 않습니다.

저는 다른 플러그인을 찾아서이 예제를 찾아 보았지만 비어 있습니다. 나는 Util과 Extension의 모든 클래스를 체크해 봤지만, 원하는 곳에서 메소드를 찾을 수 있는지는 알 수 있습니다.하지만 아무 것도 없습니다. 내가 찾은 유일한 약

이었다이 :

현재 유형을 제외한 유형 계층을 반환
declaredElements.First().GetSuperTypes() 

. 유용하지만, 내가 찾고있는 것이 아닙니다.

누구나이 API에 대한 경험이 있거나 어떻게 작동하는지 알고 있습니까? 나는 타입들 사이의 관계를 좀 더 자세히 설명하는 대답을 좋아할 것입니다. 간단한에서 그것의

나의 이해 : 이름 (IDeclaredElement, IDeclaredType)에을 선언

  • 유형은 실제 코드 요소를 참조 나타납니다.
  • ITYPE는
  • 내가 이름 (ITypeElement, IDeclaredElement)의 요소와 유형의 의미에 대한 불분명 해요 아마도 그것이 AST 요소를 참조의 실제 코드 요소에 해당하지 않는 모든 유형에 대한 최상위 인터페이스로 나타납니다.

나는 을 좋아한다. 이것에 대한 약간의 설명은이다. 이 코드 밖으로

+0

문제를 조금 명확하게 설명해 주시겠습니까? 구현하려는 최종 사용자 기능의 관점에서. 나는 일반적으로 문제가있는 단일 API가 없기 때문에 문제를 공식화하여 조언을 해줄 수 있기 때문에 묻습니다. 감사. –

답변

9

이 문서에 업데이트하세요 : https://github.com/JetBrains/resharper-devguide/issues/4

내가 시도하고 여기에 화분 설명을 제공합니다.

ITreeNode 유형 계층 구조는 코드의 추상 구문 트리를 정의합니다. 이것은 많은 정보를 제공하지만 매우 낮은 수준입니다. 코드의 원시 텍스트에 직접 매핑됩니다. 또한 더 높은 수준의 정보도 누락됩니다. 예를 들어 클래스 선언을 위해 모든 유형 멤버를 가져 오려면 클래스에 대한 AST를 처리하고 모든 적절한 트리 노드를 수집 할 수 있지만 부분 클래스를 처리해야하며 AST는 정보를 제공하지 않습니다 클래스의 다른 부분을 찾는 데 사용됩니다. 마찬가지로 클래스 선언 public class Foo : Bar이 표시되면 Bar 기본 유형의 수동 해결을 수행해야합니다.

IDeclaredElement 유형 계층 구조는 본질적으로 구문 트리의 의미 론적 관점입니다. 가장 단순한 수준에서 선언 된 요소는 "선언이있는 무언가"입니다. 이것은 클래스 선언, 메소드 선언 또는 HTML 요소, CSS 클래스, 심지어 색상 및 파일 시스템 경로와 같은 코드와 관련이없는 것일 수 있습니다 (이 때문에 "요소"라고 부름). 다른 많은 것 ).

예를 들어 CLR 유형은 ITypeElement 인터페이스로 표시되며 IDeclaredElement에서 파생됩니다. 대상 유형의 메서드, 속성, 생성자 등에 대해 선언 된 요소를 가져 오는 메서드 및 속성을 제공합니다. 따라서 선언 된 요소에 대해서만 CLR 원본 프로젝트의 의미 론적 뷰를 제공 할 수 있습니다. 거의, 그러나 아주.

선언 된 요소에는 선언 된 요소에 대한 선언 인 IDeclaration 구문 트리 노드를 제공하는 GetDeclarations 메서드가 있습니다. 마찬가지로 IDeclaration 노드는 노드에서 선언 된 요소를 가져올 수있는 DeclaredElement 속성을 제공합니다.

또한 ReSharper는 트리 노드가 선언 된 요소로 해석 할 발신 참조를 허용하는 참조라는 매우 강력한 메커니즘을 가지고 있습니다 (해결하지 못할 수도 있습니다. 아직 작성되지 않았거나 과부하를 규정하지 않고 메소드를 사용하는 것과 같이 하나 이상의 요소로 해석 될 수 있습니다. 이러한 참조는 변수 선언을 다시 참조하는 변수 이름 또는 및 소스 코드 Bar을 가져올 수있는 BarBar (Bar)의 선언 된 요소에 대한 참조를 갖는 의 모든 노드에 적용 할 수 있습니다.).

코드 파일의 구문보기, 코드 선언의 의미 론적보기 및 모든 항목을 함께 조인하는 참조 기능이 인상적인 세트를 제공하지만 모든 것을 포함하지는 않습니다. 선언 된 요소는 선언 된 의 의미 론적 관점을 제공하지만 모든 사용 시나리오를 나타내지는 않습니다.

구체적으로 (CLR 유형을 살펴보면) 형식의 사용을 배열, 포인터 또는 닫힌 제네릭 형식으로 나타낼 수 없습니다. ITypeElementFoo 또는 Bar<T> 클래스의 의미 론적 뷰를 제공 할 수 있지만 Foo[] 또는 Bar<Quux>을 나타낼 수 없습니다.

선언 된 요소는 이러한 사용 시나리오를 기본 클래스, 메서드 서명 등으로 모델링 할 수 있어야합니다. 이렇게하려면 유도 된 선언 요소 (예 : ITypeElement)가이 "유형 시스템을 나타내는 추가 인터페이스 계층을 사용합니다 "정보. 이 계층 구조는 분석되는 언어에 따라 다릅니다. CLR 유형의 경우 IType 계층 구조이며 JavaScript의 경우 IJavaScriptType입니다.

IType은 선언 된 요소의 의미 론적보기를 대체하는 것이 아니라 추가 정보입니다. IType은 모든 유형 멤버의 심볼 테이블을 반환 할 수 있지만 ITypeElement과 동일한 방식으로 접근자를 제공하지는 않습니다. 대신 IType은 선언 된 요소와 ISubstitution의 인스턴스에 대한 래퍼이며 generic 형식 매개 변수에 대한 대체를 제공합니다 (배열은 System.Array 형식으로 표시되며 기본 요소 형식을 사용합니다. 닫힌 제네릭이거나 다른 배열 일 수 있으므로 자체는 IType입니다. 대체는 아무것도 대체하지 않는 빈 대체가 될 수 있으며 열린 제네릭으로 표시된 유형 또는 전혀 제네릭이 아닌 유형을 허용합니다.IDeclaredType 인터페이스는 선언 된 요소를 나타내는 IType입니다.

기타 : 참조를 해석하면 실제로 제네릭을 모델링하기 위해 선언 된 요소와 ISubstitution으로 해석됩니다. 메소드 선언 시그너처에 대한 참조를 해석 할 때, 그 메소드가 IList<T>이고 어떤 것이 T인지 알아야합니다. IType 인스턴스를 얻기 위하여

, 당신 중 하나는 기존의 선언 요소 (메소드 서명, 기본 클래스 등)에서 하나를 얻기 위해 필요하거나 TypeFactory.CreateType 함께 만들어. 일반 유형 인 경우 대부분 ISubstitution을 지정해야합니다. 당신은 ITypeElement 당신은 또한 전달에 유형 매개 변수의 역할을하도록 TypeFactory.CreateType 방법 중 하나에 전달하는 이러한 유형을 사용할 수 있습니다

var type = psiModule.GetPredefinedType(context).String; 

: 당신은 또한을 통해 공통의 "미리 정의 된"유형의 무리를 얻을 수 있습니다.

결과적으로 우리는 소스 코드를 선언합니다. 이는 ITreeNode, IDeclarationITypeDeclaration입니다. IDeclaration을 사용하거나 참조를 해결하여이 선언의 의미 론적 뷰를 얻으십시오. IDeclaredElement, ITypeElement은 클래스를 나타내는 파생 인터페이스입니다. CLR 기반 선언 요소는 닫힌 제네릭 일 필요가있는 기본 클래스 또는 열린 제네릭 또는 배열 일 수있는 메서드 매개 변수와 같은 형식 사용을 나타 내기 위해 IType을 사용합니다. IDeclaredType은 우리를 선언 된 요소로 되돌릴 수있는 유형 용도입니다. 유형은 종종 내부적으로 선언 된 요소와 ISubstitution으로 표시됩니다.이 매개 변수는 제네릭 매개 변수가없는 경우에 대해 제네릭 매개 변수를 채울 수도 있고 ID 대체가 될 수도 있습니다. 그리고 마지막으로 ITypeTypeFactory.CreateType을 사용하거나 PredefinedType의 속성을 사용하여 얻을 수 있습니다.

+1

문서를 pase로 복사하십시오 : D 항상 그렇듯이, 아주 좋은 설명입니다! – Matthias

+2

정확하게 붙여 넣기는 아니지만 지금은 문서에 있습니다. [소개] (http://jetbrains.github.io/resharper-devguide/Architecture/PSI.html), [구문 트리] (http://jetbrains.github.io/resharper-devguide/PSI/SyntaxTrees.html) , [선언 된 요소들] (http://jetbrains.github.io/resharper-devguide/PSI/DeclaredElements.html), [참고 문헌] (http://jetbrains.github.io/resharper-devguide/PSI/References.html)) 및 [유형 시스템] (http://jetbrains.github.io/resharper-devguide/PSI/TypeSystems2.html) – citizenmatt

2

확인 : 나는 문제를 추가했습니다

void Do(IDataContext dataContext) 
{ 
    foreach (var reference in dataContext.GetData(DataConstants.REFERENCES)) 
    { 
    var resolveResultWithInfo = reference.Resolve().Result; 
    var typeElement = resolveResultWithInfo.DeclaredElement as ITypeElement; 
    if (typeElement != null) 
    { 
     var substitution = resolveResultWithInfo.Substitution; 
     var declaredType = TypeFactory.CreateType(typeElement, substitution); 
    } 
    } 
}