Привет, Хабр!

Недавно вышел 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.

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

Комментарии (13)


  1. justhabrauser
    29.07.2016 19:29
    -1

    > «новые рефакторинги и инспекции»
    Ке'с ке се «инспекции»?
    Новый креатив маркетинг-менеджера согласно скедулингу?
    Или транслейтинг тимлидером эксептованных тасков?


    1. yeswolf
      29.07.2016 20:44

      Срезали вы меня. Продолжайте, добавьте еще немного Шукшина. Пятница все-таки.


  1. dion
    29.07.2016 20:25
    +1

    Огромное спасибо за AppCode!


  1. GRIM2D
    30.07.2016 22:16

    Исправьте пожалуйста один момент.
    При закрытии таба, AppCode должен открыть предедущий таб, а открывает последный.

    Скажем открыты 10 файлов. Открываю 8ой и начинаю работать. Перехожу на файл через declaration (CMD + click). Если закрыть файл, то AppCode открывает 10й таб, вместо 8


    1. abusalimov
      31.07.2016 01:23
      +1

      Попробуйте изменить настройку Editor > General > Editor Tabs > Tab Closing Policy на Activate most recently opened tab


  1. asvechkar
    01.08.2016 01:16
    +1

    Всё бы хорошо, но!
    Для редактирования Storyboard пока без Xcode никуда.
    И не все ошибки показывает, например, с теми же var/let и Optional variable.
    В целом IDE хороший, но желаю вам разработать полное замещение Xcode.
    Пока использую оба IDE в паре.


    1. yeswolf
      01.08.2016 13:42

      И не все ошибки показывает, например, с теми же var/let и Optional variable.

      Здесь было полезно уточнить версию и если возможно — дать пример проблемного кода (можно в личные сообщения). Идеальный вариант — тестовый проект.
      Для редактирования Storyboard пока без Xcode никуда.

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

      Про замену Xcode. Для нас идеальным вариантом была бы полная концентрация на работе с кодом и над возможностями, которые относятся именно к этой сфере, но пока так сделать нельзя. Отчасти поэтому AppCode существует именно в виде отдельной IDE, но при этом мы его позиционируем как дополнение к Xcode, т.к. некоторые части (тот же xcodebuild, не говоря уже о симуляторах) нам необходимо переиспользовать и мы не будем пытаться их переписать.


      1. GRIM2D
        01.08.2016 14:25

        Насчет InterfaceBuilder. Почему бы не написать собственный формат? Пусть генерирует код для постройки UI. Для начала AutoResize добавить, потом уже AoutLayout.


        1. yeswolf
          01.08.2016 14:48
          +1

          Такие вещи — если они действительно нужны сообществу разработчиков — обычно создаются сообществом разработчиков. Я помню одни и те же вопросы к построению интерфейсов в Xcode еще начиная с версии 2.x, но альтернативы, которая действительно широко используется при разработке нативных приложений так и не появилось. Думаю, никому это просто не нужно.


  1. s_suhanov
    01.08.2016 10:36

    Немного смутило


    let rect: CGRect = CGRect(x: 0, y: 0, width: 10, height: 10)

    "Эппл" настоятельно рекомендует в данном случае НЕ писать аннотацию типа. :)


    1. yeswolf
      01.08.2016 14:36

      Ошибся, спасибо за корректировку.


  1. iWord
    01.08.2016 12:48
    +1

    IDEA для JVM божественна! Но AppCode для iOS не хвата нормальной работы как в XCode


    1. yeswolf
      01.08.2016 13:10
      +1

      Если сможете описать, какие проблемы возникли, нам это было бы очень полезно (вдруг они уже давно исправлены).