Motto

В тихом саду здравомыслия
Пусть на вас постоянно падают
кокосовые орехи пробужденности.
Чогьям Трунгпа РИНПОЧЕ


Версия для мобильного


понедельник, 27 июня 2011 г.

Описание ModelMaker Code eXplorer

Обещанный обзор ModelMaker Code eXplorer.

Сегодня я расскажу об одном эксперте для Delphi, способным фантастически упростить рефакторинг. Разработан этот эксперт компанией ModelMakerTools.  У ModelMakerTools есть 2 продукта, которые часто путают:

  1. ModelMaker - инструмент для работы с UML в Delphi.
  2. ModelMaker Code eXplorer (MMX) - набор инструментов для рефакторинга. Существуют версии для Delphi и для Visual Studio. В этом посте я расскажу о версии для Delphi.

MMX интегрируется в Delphi 5 - 7, Delphi 2005 - 2010 и Delphi XE. Т.е. вы получаете удобный инструмент для рефакторинга практически в любых версиях Delphi. И этот инструмент удобнее стандартных мастеров для рефакторинга, встроенных в Delphi.

Почти все функции которые я здесь описываю, доступны в MMX начиная с версии 5.1. Текущая версия – 9.0. Для снимков экрана я использовал версию 8.

Скажу сразу, ModelMaker Code eXplorer – платный продукт. Новая лицензия стоит 99 евро. И купить его можно только через ShareIt.

Но на сайте доступна trial версия, которая работает в течение 30 дней без каких-либо ограничений. Более того каждое обновление продлевает срок trial-а. (раньше было так, как сейчас не знаю).

Ложка дёгтя: после окончания 30-дней триала, MMX может вызывать Access Violation-ы при работе с IDE. Например при нажатии Ctrl+Shift+вверх или вниз. Или в других случаях. В общем, если ваша IDE внезапно начала сыпать ошибками, проверьте, не закончился ли испытательный период у MMX. Чтобы убедится, Для этого достаточно открыть окно Code Explorer. Если trial окончен, там будет показано соответствующее сообщение. Такие AV в IDE, это побочный эффект от защиты от взломов trial-а и способный серьёзно потрепать нервы. Поэтому предупреждаю о нём сразу. В остальном, это прекрасный и удобный инструмент для Delphi программиста.

Скриншоты MMX на официальном сайте. История изменений. На сайте продукта доступны видеоролики, демонстрирующих функционал MMX. Это что касается официальной документации. А тех, кому интересны личные впечатления, прошу пожаловать под кат.

Что мне особенно нравится в MMX - так это то, что каждая функция там работает именно так как заявлено, и часто учитывает мельчайшие нюансы, такие как, например, местонахождение курсора. Так, например при вставке кода из буфера обмена, в зависимости от того, где находился курсор в момент вызова функции, код будет превращён либо в процедуру, либо в метод класса.

Это наверное самый большой пост у меня в блоге. Более 2000 слов, 13 тысяч знаков без пробелов. И картинки. Надеюсь, что для вас он окажется полезным.

О терминах.

Чтобы избежать тавтологий в этом описании, я иногда буду называть функции MMX, мастерами, иногда инструментами. Что касается исходного кода, под процедурами подразумеваются как процедуры, так и функции, глобальные и локальные, а также иногда и методы классов (включая классовые методы). В случаях, когда подразумевается именно метод класса, я так и буду писать, метод. Классы, свойства, методы, процедуры, интерфейсы, поля и события я буду называть элементами кода.

Описание

Я не буду описывать все функции - их слишком много. Расскажу только о тех, которые мне нравятся больше всего, и в конце дам список ссылок на статьи с официального сайта, рассказывающие об остальных.

1. Синхронизация объявления/реализации.

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

В Delphi каждая процедуры и функции объявляется дважды. В секции объявления и секции реализации. Получается, если необходимо добавить новый параметр, сигнатуру метода придется править дважды. Если необходимо изменить тип возвращающего значения функции, его также приходится менять дважды. Если необходимо переименовать процедуру/функцию, переименовывать приходится в двух местах. Все наверняка уже привыкли так делать.

Мастер синхронизации здорово упрощает жизнь в таких случаях. При вызове (горячая клавиша по умолчанию: Ctrl+Alt+Y), мастер синхронизирует объявления в месте объявления функции и в месте реализации. Предположим, вы пишете код процедуры, и понимаете, что вам необходимо добавить новый входной параметр. Вы поднимаетесь выше добавляете его в сигнатуру функции прямо над кодом. Далее достаточно нажать Ctrl+Alt+Y, и этот параметр тут же добавится в сигнатуру функции в той части, где функция была объявлена. Если процедуру необходимо превратить в функцию, то всё так же просто. Заменяете procedure на function, указываете тип возвращаемого значения, нажимаете Ctrl+Alt+Y и вот уже ваша процедура везде объявлена как функция.

Сначала мне потребовалось время чтобы привыкнуть к этой фиче. Помню, поначалу после изменения типа по привычке нажимал Ctrl+Shift+вверх (перейти в interface часть), и добавлял нужные параметры. А когда привык использовать MMX, оказалось сложно отвыкнуть работать без него.

2. Рефакторинг через Clipboard.

Вторая фишка с которой очень удобно делать рефакторинг - это возможность вызвать Cut, Copy и Paste to/from Clipboard для элементов кода (процедур, методов, классов, свойств).

По умолчанию этим командам назначены следующие горячие клавиши:

  • Ctrl+Alt+X – Cut entity
  • Ctrl+Alt+C – Copy entity
  • Ctrl+Alt+V – Paste entity
Как это работает:

Если курсор находится в коде процедуры или метода и вы нажимаете Ctrl+Alt+X, то весь метод (и interface и implementation части) будет удалён из текущего модуля/класса и скопирован в буфер обмена. Вы можете перейти в другой модуль, или другой класс, нажать там Ctrl+Alt+V и метод будет вставлен.

Причём, если в момент вставки курсор будет находится в теле класса, то скопированный код будет добавлен в качестве метода объекта. Если же курсор будет находится вне класса, то код вставлен в виде процедуры или функции.

Если перед вызовом Cut или Copy, курсор находился на объявлении класса, то в буфер обмена будет скопирован весь класс, включая весь код, содержащийся в его методах.

Если же курсор находился на свойстве класса, то в буфер обмена будет скопировано объявление свойства, и Get/Set методы, и/или поле используемое для хранения значения свойства.

90% работы по переносу классов из одного юнита в другой, или для перемещения методов из одного класса в другой, выполняю через Clipboard. Действительно удобно.

3. Редактирование сущностей

MMX содержит в себе чудесную функцию Edit Entity, позволяющую редактировать сущность находящуюся под курсором. Редактировать можно: процедуры, функции, классы, интерфейсы, свойства, поля. При вызове этой функции, будет открыта модальная форма, позволяющая изменить отредактировать параметры объекта. Для разных сущностей используются разные формы. Как выглядят эти формы, вы сможете увидеть на скриншотах ниже.

Для процедур редактируемыми параметрами являются (см. скриншот ниже):

  • Имя процедуры
  • возвращаемый тип
  • Видимость (для методов класса)
  • параметры, их имена, типы, значения по умолчанию
  • Тип методы
  • Опции и директивы.

Этот же диалог открывается при вызове MMX-функций Add procedure и выполнении рефакторинга Extract Method. Для остальных типов объектов смотрите ниже снимки экрана.

На первый взгляд, эта форма выглядит не особо полезной – ведь опытному программисту проще написать объявление самому. Изюминка здесь в том, что этот редактор позволяет переименовать любой метод/класс/интерфейс. При этом старое имя будет заменено на новое во всём модуле. После переименования метода, MMX предлагает заменить все обращения к старому имени этого метода на новое (см. снимок экрана ниже).

MMX: переименование метода

В диалоге редактирования любого объекта есть вкладка Documentation, содержащая редактор для написания XmlDoc документации по редактируемому объекту. По сути это обычное memo, но большую ценность представляет панель инструментов с кнопками для быстрой генерации каркаса документации, вставка списка параметров и вставка XmlDoc тэгов из контекстного меню (Shift+Ctrl+A в любом редакторе документации). Я часто использую это меню для вставки ссылок на документацию к другим элементам (тэги <see cref> и <seealso cref>), тем более что при вставке этого тэга MMX открывает диалог поиска сущности на которую будет указывать ссылка. Точнее, часто использовал этому меню поначалу, пока не выучил нужные тэги наизусть.

Горячая клавиша по умолчанию для Edit Entity – Ctrl+E. Я для себя обычно заменяю на Ctrl+Alt+E (или Ctrl+Alt+Shift+E), так как часто пользуюсь быстрым поиском Delphi (Ctrl+E и начать набирать текст). Правда, Ctrl+Alt+E в MMX по умолчанию назначена для функции добавления/редактирования событий, но ей я не пользуюсь, поэтому просто отключаю. Хотя вот, недавно, узнал что в CnWizards есть возможность быстро найти выделенный текст, просто нажав F3.

Функция редактирования документации доступно и на других формах, например в окне Live Documentation и в главном окне MMX - Code Explorer (о нём чуть ниже).

Добавление/редактирование метода

MMX: Редактор метода

Вкладка Documentation диалога редактирования метода.

Редактирование документации

Диалог добавления/редактирования свойства.

MMX: Добавление/редакторование свойства

Диалог добавления/редактирования класса.

MMX: Добавление/редакторование класса

Диалог добавления/редактирования интерфейса.

MMX: Добавление/редакторование интерфейса

Помимо редактора процедуры, можно вызвать и отдельный редактор только для параметров. Но для этого используется уже другая функция.

Мастер параметров

MMX: Добавление/редакторование параметров

4. Рефакторинг: Извлечение метода

В Delphi начиная с 2005 версии есть встроенная функция рефакторинга, включая функцию Extact Method, но она работает хуже чем аналогичная функция из MMX. Стандартный Delphi Refactoring плохо работает с условными директивами компилятора (IFDEF). Точнее, он их игнорирует. Проверено в Delphi 2009, 2010, XE.

При попытке извлечь метод из этого кода:

{$IFDEF USE_GUI}
if not UseAutosave then
begin
  Konfigur.ReadOnly := True;
  LazyProfile.ReadOnly := True;
end;
{$ELSE}
  Konfigur.ReadOnly:=True;
  LazyProfile.ReadOnly:=True;
{$ENDIF}

В новый метод была перенесёна только эта часть кода:

{$IFDEF USE_GUI}
if not UseAutosave then
begin
  Konfigur.ReadOnly := True;
  LazyProfile.ReadOnly := True;
end;

А вот Modelmaker Code Explorer прекрасно справился с таким синтаксисом. С другой стороны, MMX тоже не идеален, и не всегда корректно подставляет параметры во вновь созданный метод. Возможно, я слишком многого хочу от простой программы. =)

Условные директивы - это именно то, обо что чаще всего спотыкаются парсеры кода. Да что там, парсеры, от некоторых конструкций, даже IDE выпадает в осадок, изрыгая warning-и и отключая автозавершение кода.

Пример работы MMX рефакторинга Extract Method:

Выделяем текст, и открываем контекстное меню MMX. Выбираем там пункт Extract Method.

Delphi: Extact method

Отображается форма редактирования метода. Здесь можно подкорректировать имя, параметры, возвращаемый тип, а также указать что делать с кодом в оригинальном методе. Варианты: оставить, убрать, закомментировать с пометкой TODO. По умолчанию, извлеченный код комментируется.

Диалог Extract method в Delphi MMX

Результат выполнения рефакторинга Extract Method (для извлеченного кода была включена опция “Закомментировать с пометкой TODO”).

Extract method. Результат

5. Подготовка программы к переводу

Я часто рекомендую установить ModelMaker Code eXplorer только ради этой функции. Речь идёт о конвертировании жёстко-закодированных строк в константы/resourcestring. Все инструменты для перевода Delphi-программ, включая стандартный Integrated Translation Editor, требуют чтобы все строки, которые необходимо переводить, были вынесены в ресурсы программы.

MMX предлагает для этого ряд функций. Расскажу о них по порядку.

Простейшие функции – Convert to const и Convert to resourcestring. Эти функции позволяет быстро преобразовать текст под курсором в константу или в ресурс. Причём можно указать, где будет размещён извлечённый текст: локально, в секции implementation, в секции interface или в отдельном файле.

Следующий уровень – это возможность вызвать мастера конвертирования для текущего юнита “Module String Wizard”. Весь юнит будет обработан и в отдельной форме будет выведен список найденных строк. В этой форме можно пометить, что делать с каждой строкой: превратить в resourcestring, в константу или пометить комментарием “//do not localize”. См. пример использования функции Convert Strings на официальном сайте.

И самый высший уровень – это мастер “Multi File String Wizard”. Этот мастер умеет искать такие строки сразу в нескольких файлах. Например во всех файлах активного проекта, или во всех файлах внутри определённой папки. Кстати, на сайте авторов доступна утилита командной строки выполняющая поиск таких строк в файлах с исходниками.

В общем, идеальный помощник для подготовки программы к локализации. Если вам необходимо подготовить свою программу или просто проверить, я рекомендую поставить MMX. Хотя бы и trial-версию. Она работает 30 дней без каких-либо ограничений, и этого времени обычно более чем достаточно для того, чтобы подготовить к переводу все проекты.

Всплывающее меню Conversion для строки под курсором.

MMX: Преобразовать строку в константу

Диалог “Module String Wizards”:

MMX: Мастер строк модуля

Диалог Multi-File String Converter. Здесь можно видеть сколько hard-coded строк было найдено в модуле, и сколько из них уникальные.

MMX: Мастер ковертации строк в файлах

6. Code Explorer

Окно ModelMaker Code ExplorerПо сути, это основная функция MMX-а. Но я пользуюсь ей редко, поэтому поместил её в конец. Я так понимаю, что это замена стандартному Delphi окну Structure, обладающая большим функционалом. Там куча настроек и куча кнопок, большую часть из которых я не использую.

А вот, что нравится мне:

  1. Во-первых, при перемещении курсора по редактору кода, текущий метод будет подсвечен в окне Explorer-а, и наоборот.
  2. Во-вторых, в окне Explorer-а можно открыть панель редактирования документации (такую же как я упомянутую выше в описании формы редактирования сущностей). См. снимок экрана ниже.
  3. В-третьих Живые метрики (Live Metrics). Живые метрики – это список предупреждений по плохому неидеальному коду. Быстрый способ взглянуть на потенциально проблемные места в коде. См. снимок экрана ниже.
Живые Метрики включают в себя:
  1. Магические строки (смешение текста и кода – использование в коде строк, не являющихся константами, ресурсами и не помеченные комментарием //do not localize).
  2. Слишком длинные линии (линии превышающие в длину n-символов)
  3. Слишком длинные методы (методы длиннее 50 строк)
  4. Магические числа (числа в коде, не являющиеся константами)
  5. TODO – количество TODO комментариев в коде
  6. Использование with в коде.
  7. Неиспользуемые обработчики событий.
  8. Использование анонимных методов.
  9. Процедуры со слишком большим числом параметров.
  10. Слишком большое число вложенных подпрограмм.
  11. ещё какие-то

Любую из метрик можно настроить под себя или отключить.

Лично я чаще всего использую Explorer именно для поиска магических строк в текущем модуле и пометки системных строк комментарием //do not localize. См. предыдущую главу о подготовке программы к переводу.

Редактирование документации в окне MMX Code Explorer:

Редактирование документации в окне Code Explorer

Живые метрики:

MMX: Живые метрики

7. Остальные функции

В этом разделе просто собраны все функции, описанные на сайте ModelMaker со ссылками на описания.

Try Finally Wizard. Добавляет finally .. end после ввода try. По ссылке подробный пример с картинками на официальном сайте.

Рефакторинги
Ссылки по теме

9 комментариев:

  1. Анонимный29 июня 2011 г., 20:29

    Полностью поддерживаю. Эта штука местами покруче решарпера будет.

    ОтветитьУдалить
  2. Анонимный30 июня 2011 г., 20:07

    Жаль платная )

    ОтветитьУдалить
  3. > Жаль платная )
    Ага. Была б бесплатная - цены бы ей не было.
    А с другой стороны, если б MMX был бесплатным, едва ли он работал бы так же хорошо и вообще как-то развивался.

    Вот если б его вместе с Delphi поставляли - тогда было бы супер.

    ОтветитьУдалить
  4. Анонимный4 июля 2011 г., 12:07

    >Вот если б его вместе с Delphi поставляли - тогда было бы супер.

    Ну насколько я помню такие продукты как ModelMaker и Bold/Eco поставлялись с D7 в Архитект версии. Ну дальнейшего развития это не нашло. Видать не всё так гладко...

    ОтветитьУдалить
  5. Aleksey Timohin: А почему же вы Code Explorer-ом не пользуетесь? Предпочитаете что то другое, тогда что?
    Лично я еще не привык пользоватся никакими из возможностей этого эксперта кроме Code Explorer. Зато без него чувствую себя как без рук. А на стандартный браузер всегда смотрю со слезами на глазах :)

    ОтветитьУдалить
  6. Купил и не жалею. Отличный софт!

    ОтветитьУдалить
  7. Alex Kononov, а мой обзор как-то поспособствовал покупке? =)

    ОтветитьУдалить
  8. 2 Torbins:
    > А почему же вы Code Explorer-ом не пользуетесь? Предпочитаете что то другое, тогда что?

    Извините, как-то не заметил этого комментария.
    Я использую Code Explorer - но в основном для написания документации к методу, и для просмотра Parser Warnings (hard-coded string, magic numbers). В качестве навигатора, так и привык к нему. Да и вообще для навигации, я в основом Grep Search использую из gExperts и Диалог со списком процедур (Ctrl+D) из CnWizards.

    ОтветитьУдалить
  9. Aleksey Timohin, о CodeExplorer я знал раньше =)
    Просто в Украине триаьный период нелинеен во времени. В США все проще: надо - купил =)

    ОтветитьУдалить

Постоянные читатели