Привет, Хабр!
Недавно вышел AppCode 2016.2, новый релиз нашей IDE для разработки под iOS/OSX. Под катом много гифок и размышлений об автоматизированных рефакторингах в Objective-C и Swift.

Introduce Variable (он же Extract Variable) — это локальный рефакторинг, который позволяет автоматически извлечь часть сложного выражения в локальную переменную. Конечно, это можно сделать и вручную. Напечатать название переменной, проставить ее тип, присвоить ей нужное выражение, вручную поправить все в коде, проконтролировать, что не забыл исправить каждое вхождение… Хорошая привычка, и по собственному опыту помню, при разработке под iOS она вырабатывается довольно быстро.
Правда в том, что эта работа рутинна, а рутинные задачи всегда лучше автоматизировать. Для Objective-C этот рефакторинг был реализован в AppCode достаточно давно. Кстати, интересным эффектом его частого использования становится нежелание самому писать названия переменных и вообще начинать строку кода с привычного “тип переменной — название переменной”.
Ведь можно сначала написать выражение — а потом автоматически выделить его в переменную, выбрав подсказку для ее названия или напечатав свое:

Для реализации Introduce Variable для Swift пришлось научиться обрабатывать огромное количество конструкций языка — ведь для извлечения переменной нам необходимо знать ее тип, и это всего лишь одно из условий.
По умолчанию всегда извлекается константа, а изменить let на var можно во всплывающем окне:

Ну и чтобы стало еще проще — опционально можно автоматически подставить тип переменной:

К слову, и руками заменять все вхождения в коде не нужно — AppCode это сделает сам:

Когда пишешь код, все ошибки и предупреждения хочется видеть сразу же. И в любом случае не после компиляции. В этой версии мы решили интегрировать SourceKit для отображения ошибок и предупреждений в редакторе:

А также дать возможность нашим пользователям использовать те же самые быстрые исправления, которые выдает Xcode:

Фактически, в AppCode SourceKit используется как внешний линтер для кода, а мы тем временем продолжаем работать над новыми возможностями кодогенерации, использующими платформу IntelliJ.
Казалось бы, опечатки в исходном коде или комментариях не так важны — ведь на работоспособность библиотеки или приложения они не оказывают абсолютно никакого влияния. Но что если проект становится публичным и все эти опечатки попадают в автоматически сгенерированную на основе исходного кода документацию? В этом случае возникает необходимость избегать их, а проверять вручную большой объем кода — неблагодарное занятие.
Теперь AppCode ищет опечатки как в комментариях к коду на Swift, так и в самом исходном коде — названиях переменных, классов и даже их частях, помогая быстро внести исправления:

В Objective-C, как и в C++, такая возможность тоже есть. Более того — это один из механизмов платформы IntelliJ, адаптированный под конкретный язык программирования. Подробнее про то, как в AppCode устроена работа с инспекциями кода, можно прочитать здесь.
Live Templates — это наши шаблоны исходного кода. Суть — дать возможность быстро вставить фрагмент исходного кода по аббревиатуре, аналог сниппетов в XCode. В чем различие? Например, с помощью Live Templates можно сделать вот так:

Кстати, для Objective-C аналогом является встроенный шаблон с аббревиатурой each:

В чем магия? В том, что поля ввода значений в AppCode можно сприптовать. Например, скопировать значение вводимого значения из одного поля в другое. Или — как в шаблоне for — сделать так, чтобы поле ввода искало в своей окрестности массивы, по которым можно проитерировать. Возможности не безграничны, но они есть — а подробнее про них можно прочитать вот тут.
Второе базовое отличие — возможность обернуть выделенный фрагмент исходного кода в какое-либо выражение (Surround With templates):

В AppCode 2016.2 мы добавили поддержку всех этих механизмов для Swift и сделали базовый набор шаблонов, аналогичный сниппетам в Xcode.
В коде на Objective-C и Swift есть названия параметров — такова специфика языка. Вручную их вставлять неудобно, поэтому еще одна базовая возможность, добавленная в этот релиз, — это автоматическая вставка названий параметров и полей для ввода значений при автодополнении функций и методов в Swift:
В числе типов автодополнения кода в продуктах JetBrains есть возможность быстро завершить конкретную конструкцию в коде: вставить точку с запятой (даже если курсор стоит отнюдь не в конце выражения), круглые или фигурные скобки и сразу же перейти к набору следующего выражения. В этой версии мы основательно доработали этот тип автодополнения, и теперь он работает вот так:

Нас очень давно просили сделать генерацию документационных комментариев для методов и функций в Objective-C, и большинство запросов ограничивалось просьбой дать функциональность, аналогичную VVDocumenter. И если бы в нашем понимании “правильно сделанная поддержка документации для Objective-C в AppCode” ограничивалась бы действием “вставить шаблон комментария с предзаполненным параметрами”, то мы бы давно это сделали — вот так:

Кстати, автодополнение названий параметров и документационных тэгов тоже работает:

Но этого мало. Документацию необходимо обновлять, и каждый, кто хоть однажды документировал свой проект целиком, знает, что заставить себя обновить однажды написанный комментарий значительно сложнее, чем написать его в первый раз. Поэтому мы реализовали обработку комментариев в коде так, чтобы Rename для названий параметров (как нам кажется, наиболее частый случай изменений) работал корректно:

Дополнительный бонус — сильно улучшилось отображение таких комментариев в окне Quick Documentation.
Swift — новый, активно развивающийся язык. Но еще долгое время он будет существовать бок о бок с Objective-C, и разработчики будут использовать их вместе. Поэтому мы говорим “рефакторинги в Swift”, а в реальности в большинстве случаев имеем в виду “рефаторинги в смешанном коде”. В AppCode уже достаточно давно есть Rename и для Swift, и для сущностей Objective-C, используемых из Swift. В этой версии мы работали над Rename для методов классов Swift, используемых из Objective-C.
Когда метод класса в Swift не содержит никаких дополнительных аттрибутов, переименовать его просто, т. к. название в Objective-C совпадает с названием метода в Swift:

Все становится намного интереснее, если у метода есть псевдоним, сделанный с помощью аннотации @objc. В этом случае при вызове Rename из Objective-C AppCode определит имя функции в Swift и менять будет именно его:

Другой интересный случай — наличие внешнего названия у параметра функции в Swift. Например, для функции

Пока эти возможности реализованы только для методов и классов, в будущем планируем сделать то же самое для полей классов.
Про настройки форматирования кода в AppCode можно написать отдельную статью, но мы просто кратко отметим, что для Objective-C/C/C++ добавлены два новых предопределенных стиля форматирования — LLVM и LLDB.
Небольшое демо (на английском) с демонстрацией новых возможностей:
Все платформенные изменения отлично описаны в посте anastasiak2512, в нем же можно прочитать про новые возможности генерации кода для C++ (Generate operators и Generate definitions). Традиционно все они доступны в AppCode.
На этом все. Читайте о других возможностях продукта у нас на сайте, следите за обновлениями в нашем англоязычном блоге, и задавайте любые возникшие вопросы в комментариях к этому посту.
Недавно вышел AppCode 2016.2, новый релиз нашей IDE для разработки под iOS/OSX. Под катом много гифок и размышлений об автоматизированных рефакторингах в Objective-C и Swift.

Swift
Introduce Variable
Introduce Variable (он же Extract Variable) — это локальный рефакторинг, который позволяет автоматически извлечь часть сложного выражения в локальную переменную. Конечно, это можно сделать и вручную. Напечатать название переменной, проставить ее тип, присвоить ей нужное выражение, вручную поправить все в коде, проконтролировать, что не забыл исправить каждое вхождение… Хорошая привычка, и по собственному опыту помню, при разработке под iOS она вырабатывается довольно быстро.
Правда в том, что эта работа рутинна, а рутинные задачи всегда лучше автоматизировать. Для Objective-C этот рефакторинг был реализован в AppCode достаточно давно. Кстати, интересным эффектом его частого использования становится нежелание самому писать названия переменных и вообще начинать строку кода с привычного “тип переменной — название переменной”.
Ведь можно сначала написать выражение — а потом автоматически выделить его в переменную, выбрав подсказку для ее названия или напечатав свое:

Для реализации Introduce Variable для Swift пришлось научиться обрабатывать огромное количество конструкций языка — ведь для извлечения переменной нам необходимо знать ее тип, и это всего лишь одно из условий.
По умолчанию всегда извлекается константа, а изменить let на var можно во всплывающем окне:

Ну и чтобы стало еще проще — опционально можно автоматически подставить тип переменной:

К слову, и руками заменять все вхождения в коде не нужно — AppCode это сделает сам:

Ошибки и предупреждения в окне редактора кода
Когда пишешь код, все ошибки и предупреждения хочется видеть сразу же. И в любом случае не после компиляции. В этой версии мы решили интегрировать SourceKit для отображения ошибок и предупреждений в редакторе:

А также дать возможность нашим пользователям использовать те же самые быстрые исправления, которые выдает Xcode:

Фактически, в AppCode SourceKit используется как внешний линтер для кода, а мы тем временем продолжаем работать над новыми возможностями кодогенерации, использующими платформу IntelliJ.
Проверка правописания
Казалось бы, опечатки в исходном коде или комментариях не так важны — ведь на работоспособность библиотеки или приложения они не оказывают абсолютно никакого влияния. Но что если проект становится публичным и все эти опечатки попадают в автоматически сгенерированную на основе исходного кода документацию? В этом случае возникает необходимость избегать их, а проверять вручную большой объем кода — неблагодарное занятие.
Теперь AppCode ищет опечатки как в комментариях к коду на Swift, так и в самом исходном коде — названиях переменных, классов и даже их частях, помогая быстро внести исправления:

В Objective-C, как и в C++, такая возможность тоже есть. Более того — это один из механизмов платформы IntelliJ, адаптированный под конкретный язык программирования. Подробнее про то, как в AppCode устроена работа с инспекциями кода, можно прочитать здесь.
Live Templates
Live Templates — это наши шаблоны исходного кода. Суть — дать возможность быстро вставить фрагмент исходного кода по аббревиатуре, аналог сниппетов в XCode. В чем различие? Например, с помощью Live Templates можно сделать вот так:

Кстати, для Objective-C аналогом является встроенный шаблон с аббревиатурой each:

В чем магия? В том, что поля ввода значений в AppCode можно сприптовать. Например, скопировать значение вводимого значения из одного поля в другое. Или — как в шаблоне for — сделать так, чтобы поле ввода искало в своей окрестности массивы, по которым можно проитерировать. Возможности не безграничны, но они есть — а подробнее про них можно прочитать вот тут.
Второе базовое отличие — возможность обернуть выделенный фрагмент исходного кода в какое-либо выражение (Surround With templates):

В AppCode 2016.2 мы добавили поддержку всех этих механизмов для Swift и сделали базовый набор шаблонов, аналогичный сниппетам в Xcode.
Поля ввода значений при автодополнении
В коде на Objective-C и Swift есть названия параметров — такова специфика языка. Вручную их вставлять неудобно, поэтому еще одна базовая возможность, добавленная в этот релиз, — это автоматическая вставка названий параметров и полей для ввода значений при автодополнении функций и методов в Swift:

Objective-C
Complete Statement
В числе типов автодополнения кода в продуктах JetBrains есть возможность быстро завершить конкретную конструкцию в коде: вставить точку с запятой (даже если курсор стоит отнюдь не в конце выражения), круглые или фигурные скобки и сразу же перейти к набору следующего выражения. В этой версии мы основательно доработали этот тип автодополнения, и теперь он работает вот так:

Документация
Нас очень давно просили сделать генерацию документационных комментариев для методов и функций в Objective-C, и большинство запросов ограничивалось просьбой дать функциональность, аналогичную VVDocumenter. И если бы в нашем понимании “правильно сделанная поддержка документации для Objective-C в AppCode” ограничивалась бы действием “вставить шаблон комментария с предзаполненным параметрами”, то мы бы давно это сделали — вот так:

Кстати, автодополнение названий параметров и документационных тэгов тоже работает:

Но этого мало. Документацию необходимо обновлять, и каждый, кто хоть однажды документировал свой проект целиком, знает, что заставить себя обновить однажды написанный комментарий значительно сложнее, чем написать его в первый раз. Поэтому мы реализовали обработку комментариев в коде так, чтобы Rename для названий параметров (как нам кажется, наиболее частый случай изменений) работал корректно:

Дополнительный бонус — сильно улучшилось отображение таких комментариев в окне Quick Documentation.
Рефакторинг Rename в смешанном коде
Swift — новый, активно развивающийся язык. Но еще долгое время он будет существовать бок о бок с Objective-C, и разработчики будут использовать их вместе. Поэтому мы говорим “рефакторинги в Swift”, а в реальности в большинстве случаев имеем в виду “рефаторинги в смешанном коде”. В AppCode уже достаточно давно есть Rename и для Swift, и для сущностей Objective-C, используемых из Swift. В этой версии мы работали над Rename для методов классов Swift, используемых из Objective-C.
Когда метод класса в Swift не содержит никаких дополнительных аттрибутов, переименовать его просто, т. к. название в Objective-C совпадает с названием метода в Swift:

Все становится намного интереснее, если у метода есть псевдоним, сделанный с помощью аннотации @objc. В этом случае при вызове Rename из Objective-C AppCode определит имя функции в Swift и менять будет именно его:

Другой интересный случай — наличие внешнего названия у параметра функции в Swift. Например, для функции
function(extParam param:String)
соответствующий метод в Objective-C будет называться functionWithExtParam
. И такой случай мы тоже обрабатываем корректно:
Пока эти возможности реализованы только для методов и классов, в будущем планируем сделать то же самое для полей классов.
Форматирование кода
Про настройки форматирования кода в AppCode можно написать отдельную статью, но мы просто кратко отметим, что для Objective-C/C/C++ добавлены два новых предопределенных стиля форматирования — LLVM и LLDB.
Демо
Небольшое демо (на английском) с демонстрацией новых возможностей:
Все платформенные изменения отлично описаны в посте anastasiak2512, в нем же можно прочитать про новые возможности генерации кода для C++ (Generate operators и Generate definitions). Традиционно все они доступны в AppCode.
На этом все. Читайте о других возможностях продукта у нас на сайте, следите за обновлениями в нашем англоязычном блоге, и задавайте любые возникшие вопросы в комментариях к этому посту.