Реализация собственного мастера для Visual Studio для пользовательских классов C ++ - PullRequest
7 голосов
/ 27 февраля 2011

Для того, чтобы новые классы C ++ соответствовали некоторым довольно требовательным соглашениям о кодировании (заранее: я не в состоянии обсуждать это ...), я думал о способе создания заглушек для новых классов C ++.В настоящее время все делают копирование-вставку, регулярно упуская некоторые детали.Используемая среда IDE - MS Visual Studio 2005, но я думаю, что в 2008 и 2010 годах изменений в этих темах не было.

Моей первой идеей было реализовать сценарий командной строки, чтобы сделать это, что было бы довольно просто сделать.В качестве альтернативы я подумал об использовании механизма расширения VS по умолчанию для лучшей интеграции IDE.Таким образом, при выборе Add-> New Item ... на фильтре (Solution Explorer) это может быть связано с некоторыми пользовательскими вещами.

После некоторых исследований я обнаружил, чтопростой в использовании механизм шаблонов, который, к сожалению, не работает для C ++ (http://msdn.microsoft.com/en-us/library/6db0hwky%28v=vs.80%29.aspx). для C ++, кажется, что вместо этого вам нужно реализовать собственный мастер, включающий html для компоновки и javascript для логики.

Что касается пользовательского подхода мастера, я пришел к выводу, что это потребует некоторых усилий (по крайней мере, для меня), чтобы сделать это. MSDN не очень подробно по этой теме. Я нашел некоторые пошаговые руководства ввеб, который имеет дело с пользовательскими мастерами только для проектов ( Add-> New Project ... вместо Add-> New Item ... ).

Итак, вот вопрос qn: Кто-нибудь делал это или что-то подобное? Стоит ли это (лучшая интеграция в IDE) (справиться с деталями реализации пользовательского мастера), или вы бы предложили команду go?инструмент линии вместо?Полагаю, что в текущем проекте более двух дней работы не окупятся.

Если вы считаете, что пользовательские мастера хороши, возможно, вы можете дать несколько советов для начала.Кроме того, возможно, есть альтернативы, которые я не придумал.Надстройки VS, по-видимому, были слишком хороши для этого, и адаптация, например, VC \ vcprojectitems \ newc ++ file.cpp не сработает.

Заранее спасибо и наилучшими пожеланиями... Jerb

1 Ответ

13 голосов
/ 27 октября 2011

Я сделал нечто подобное, используя собственный мастер.

Для своих целей я просто хотел внедрить несколько простых макросов в каждый класс, чтобы вставить его в статический объект фабрики.

Я не сделалне нужно модифицировать настоящего мастера, просто скопируйте мастер по умолчанию для универсального класса и измените JavaScript для генерации кода.

Документация по теме - мусор, но здесь есть хорошее место для начала работы с javascript (которыйэто то место, где вы собираетесь получить максимальную мощность):

http://msdn.microsoft.com/en-us/library/t41260xs(v=VS.71).aspx

Здесь находится мастер классов по умолчанию:

C: \ Program Files\ Microsoft Visual Studio 10.0 \ VC \ VCWizards \ CodeWiz \ Generic \ Class \ Scripts \ 1033 \ default.js


Дублирование проекта

Дублировать это сложнее, чем ядумал, что вам нужно скопировать и вставить папку

Microsoft Visual Studio 10.0 \ VC \ VCWizards \ CodeWiz \ Generic \

, а затем перейти к:

C: \ Program Files \ Microsoft Visual Studio 10.0 \ VC \ VCAddClass \ Generic

Создайте дубликат этой папки и измените Generic.vsdir внутри нее, чтобы он указывал на дублирование .. \ Simple.vsz (файл в папке VCAddClass).

Файл Simple.vsz указывает на местоположение папки «Generic» в VCWizards, которые вы вначале дублировали, поэтому укажите свой новый simple.vsz.


Генерация кода

Что касается фактической генерации кода, ее не так сложно подобрать.Чтобы все началось быстрее, вот общий способ работы default.js:

Когда мастер завершит работу, метод code gen запускается из:

function OnFinish(selProj, selObj)

selProj is (asнасколько я могу судить) экземпляр EnvDTE.Project

http://msdn.microsoft.com/en-us/library/envdte.project.aspx

Получение информации от мастера, кажется, основано на:

wizard.FindSymbol("CLASS_NAME")

Настоящая магия начинает происходить с объектом selProj.CodeModel

oCM.AddClass(strClassName, strHeader, vsCMAddPositionEnd, "", "", vsCMAccessDefault);

Похоже, что для этих методов добавление чего-либо в файл просто изменяет файл как одно действие, так как требует путь к файлу какего параметр.

Возвращает экземпляр CodeClass и может быть добавлен с помощью его методов, таких как:

AddAttribute
AddFunction
...

Это довольно ограниченно, если вы ищете очень строгое форматирование кода (или в моемслучай вставки макросов, которые не соответствуют нормальному синтаксису кода.

Простой способ обойти это - просто создать собственную строку для частей, которые вам необходимо полностью контролировать с помощью интерфейса EditPoint.

EditPoint - это место внутри файла кода, в которое можно вызывать методы, такие как:

EditPoint.Insert(string)
Editpoint.InsertFromFile(path)

Чтобы получить EditPoint в месте, где вы хотите вставить код, просто используйтерасположение одного из существующих элементов в файле кода поколения (например, класса или конструктора) и получение TextPoint с использованием .StartPointOf или .EndPointOf и манипулирование параметрами.

Получив TextPoint, вы можете создать EditPoint, напримерИтак:

newclass.EndPointOf(vsCMPartBody).CreateEditPoint().Insert("\nprivate:\n  REGISTER_TYPE_MEMBER("+strClassName+");\n");

Чтобы вместо этого получить TextPoint внутри файла .cpp:

oConstructor.StartPointOf(vsCMPartWhole,vsCMWhereDefinition).CreateEditPoint().Insert("REGISTER_TYPE_BODY_ID("+strClassName+",REPLACE_ID);\n\n\n");

Это дает вам возможность делать все, что вы хотите, с помощью JScript-манипуляции со строками так долго, как вы можетенайдите нужные входные данные с помощью мастера (в который я еще не углубился)

...