Visual Studio SDK получает информацию о модификаторе типа - тип абстрактный или внутренний? - PullRequest
0 голосов
/ 18 марта 2020

Я использую метод IVsObjectList2.GetCategoryField2 для извлечения различной информации типа.

Теперь мне интересно, как я могу получить C# конкретную c информацию, такую ​​как abstract или internal модификатор типа? Браузер объектов может отображать эту информацию.

enter image description here

Обновление 1:

Я предпринял еще одну попытку получить эту информацию. Через DynamicTypeService и IVsHierarchy (проекта) я могу получить TypeResolutionService. Это может затем вернуть Type, который я ищу, и сформировать Тип, который я получаю (внутренний, абстрактный и т. Д. c.)

К сожалению, это работает только с. NET Рамочные проекты. . NET Основные проекты не работают. Предполагается, что. NET основные проекты вызывают проблемы при разрешении, потому что надстройка VS (или Visual Studio SDK) работает под. NET Framework.

var dte = Package.GetGlobalService(typeof(DTE)) as DTE2;
var serviceProvider = new ServiceProvider((Microsoft.VisualStudio.OLE.Interop.IServiceProvider)dte);

IVsSimpleObjectList2 objectList;
....
objectList.CountSourceItems(index, out var vsHierarchy, out var itemid, out var pcItems);

DynamicTypeService dynamicTypeService = (DynamicTypeService)serviceProvider.GetService(typeof(DynamicTypeService));
var typeResolutionService = dynamicTypeService.GetTypeResolutionService(hier);
var type = typeResolutionService.GetType("ObjectBuilder.ObjectBrowserTestTypes.AbstractTestClass");

Больше информации здесь : Visual Studio Extension получает все классы и интерфейсы метаданных

Я все еще ищу решение. У кого-нибудь есть другая идея?

1 Ответ

0 голосов
/ 26 марта 2020

В конце я решил не получать информацию о типах через Object-Browser или IVsObjectManager2. Причина в том, что я не получил всю необходимую информацию.

Для типов в загруженных в данный момент проектах Visual Studio я использую класс ElementClass или CodeClass.

var service = Package.GetGlobalService(typeof(DTE)) as DTE2;
Project project = service?.Solution?.Projects.Item(0);
CodeType codeType = project.CodeModel.CodeTypeFromFullName("Full name of Type");

if (codeType.Kind == vsCMElement.vsCMElementClass && codeType is CodeClass2 codeClass)
{
    // get all the information form the code class
    var typeDescription = new TypeDescription();
    typeDescription.FullName = codeClass.FullName;
    typeDescription.ContainsGenericParameters = codeClass.IsGeneric;
    typeDescription.IsAbstract = codeClass.IsAbstract;
}

Для типов, которые находятся в ссылочной сборке, я использую Mono.Cecil. Преимущество Mono.Cecil заключается в том, что он работает с. NET Framework DLL и. NET Core DLL. Путь к указанной сборке можно получить через VS-SDK.

var vsProject = project.Object as VSLangProj.VSProject;
var assemblyPath = vsProject.References.Item(0).Path;

ModuleDefinition module = Mono.Cecil.ModuleDefinition.ReadModule(assemblyPath);
foreach (TypeDefinition type in module.Types)
{
    var isAbstract = type.IsAbstract;
}
...