Всем привет!


Неделю назад мы выпустили AppCode 2019.1 — поговорим об изменениях в нем. Под катом куча нового, полезного, исправленного и дополненного.


Splash



Swift


Swift 5


Все новые возможности Swift 5 корректно работают в AppCode 2019.1:


  • SE-0200 Raw text literals
  • SE-0213 Literal initialization via coercion
  • SE-0216 Dynamic callables
  • SE-0224 Support 'less than' operator in compilation conditions
  • SE-0227 Identity key path
  • SE-0228 Fix ExpressibleByStringInterpolation
  • SE-0230 Flatten nested optionals resulting from try?

Переименование


Была проблема с переименованием перегруженных методов и методов класса-родителя — а теперь ее нет.


Навигация к определению


Казалось бы, что может быть проще и элементарнее перехода к определению метода или класса? Стандартное, привычное действие.


И все действительно так в Objective-C: название типа при инициализации объекта стоит отдельно, сам метод-инициализатор — отдельно. Соответственно, если курсор стоит на названии типа, мы переходим к определению типа, если на инициализаторе — к определению инициализатора. А вот в Swift все становится сложнее. Инициализатор слился с названием типа воедино, и, если воспроизводить поведение Xcode, теряем возможность перехода именно к инициализатору. Если же оставлять поведение AppCode 2018.3.x, ломаем привычку пользователя (“как в Xcode”, то есть переход не к определению инициализатора, а к определению типа). Это по понятным причинам не нравится пользователям.


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


Go to Declaration


Оба сценария использования сохранены, все счастливы.


Перемещение выражений


Пока пользователи Xcode выделяют мышкой и копипастят, пользователи AppCode ставят курсор на выражение и двигают его целиком легким нажатием ??^/v:


Move Statement


Работает для циклов, функций, методов, классов, условий, в общем, почти для всего.


Многострочные литералы


Как превратить однострочный литерал в многострочный? В AppCode теперь достаточно нажать ?:


Multiline strings


Подсветка, автодополнение, анализ кода и все-все-все


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


  • Мы стали строить символы библиотек и для симуляторов, и для устройств. Раньше строили только для симулятора.
  • Сделав это, стали корректно определять текущую платформу (симулятор/устройство) и правильно передавать ее clang-annotator в Objective-C и SourceKit в Swift. Почему это важно? Например, SourceKit не будет отображать ошибки и предупреждения, если ему некорректно передать в аргументах папку с продуктами сборки. Эта проблема должна исчезнуть.
  • Стали правильно обрабатывать DerivedSources и все исходники, сгенерированные в этой папке (Core Data, Intents).

Objective-C/C/C++


Коллеги из CLion добавили стили именования кодовых конструкций для C/C++, а мы их получили еще и для Objective-C (Preferences | Editor | Code Style | C/C++/Objective-C | Naming Convention):


Naming convention


Запуск и отладка


AppCode теперь умеет присоединяться к процессам, запущенным не только на симуляторе, но и на устройстве (??A > Attach to process):


Attach to process


В настройки конфигураций запуска добавлена возможность выбора языка и региона приложения:


Application language and region


Run to Cursor можно вызывать не только через ?F9, но и нажатием на номер строки в редакторе:


Mute variables


Пересчет переменных при отладке теперь можно запретить с помощью действия Mute Variables в контекстном меню:


Mute variables


Темы для IDE


Внимательный читатель уже заметил, что все скриншоты в посте сделаны с использованием новой темы оформления Dark Purple:


Dark Purple theme


Темы IDE теперь можно делать самостоятельно, поэтому в репозитории плагинов кроме нескольких тем, сделанных нами, уже можно найти несколько пользовательских вариантов оформления. А до 3-го мая можно не только сделать свою тему, но и поучаствовать в конкурсе, недавно анонсированном нами.


Список недавно просмотренных / измененных участков кода


Есть несколько полезных действий для навигации к недавно открытым или измененным местам в коде:


  • Recent Files (?E)
  • Switcher (??)
  • Jump to Last Edit Location (???)

Перемещение к последнему отредактированному участку кода вообще сложно переоценить, особенно когда редактируешь файл большого размера.


Теперь появился еще и список недавно просмотренных / измененных мест Recent Locations (??E):


Recent Locations


Вот такой получился релиз. Все вопросы, пожелания и даже баг-репорты пишите прямо тут в комментариях — будем рады ответить!


Команда AppCode

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


  1. dachuiko
    17.04.2019 18:10

    Зачем все эти фичи, если среда зависает намертво и ресурсы жрет хуже хрома!
    Серьёзно… Просто попытался воспроизвести первую гифку — и аппкод зависает намертво.

    а так задумка, конечно же, хорошая…


    1. yeswolf Автор
      17.04.2019 18:20

      Серьёзно… Просто попытался воспроизвести первую гифку — и аппкод зависает намертво.

      Давайте понимать, почему так случилось. Виснет — значит «фриз» или прогресс какой-нибудь крутится долго? Подсветка файла прошла? Сколько памяти у IDE, не забита ли (Preferences | Appearance & Behavior | Appearance | внизу в Window Options — Show Memory Indicator > OK)? Если там все 2GB забиты, надо дать больше через правку Xmx в Help | Edit Custom VM Options.


      1. dachuiko
        17.04.2019 18:49

        Вот, к сожалению, жаль, что у такого хорошего инструмента нет автоматического отслеживания подобных вещей. Всё работает, подсветка есть, индекс собран, по файлам прыгает. Но в какой-то момент при попытке перейти на определение по cmd+b — фриз полностью главного потока. И висит оно так минут 10.

        Спасибо за пути возможного решения.


        1. yeswolf Автор
          18.04.2019 14:01

          Инструмент-то есть, просто всегда хочется попробовать более простой вариант перед сбором всех логов. В общем, нужно содержимое директории, открывающейся по Help | Show Log in Finder целиком — включая все поддиректории. Там должны быть дампы после фризов, попробуем разобраться. Лучше всего их — сразу в трекер.


      1. dachuiko
        17.04.2019 18:53

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


    1. NishchebrodKolya2
      18.04.2019 13:58
      -1

      Хорошую программу на джаве не напишут.


  1. yeswolf Автор
    17.04.2019 18:20

    del


  1. house2008
    17.04.2019 23:18

    Спасибо, пользуюсь 2019.1, но мне кажется 2018 версия была шустрее. После следующих изменений стало, вроде, лучше:
    1. Добавил некоторые JVM флаги ( stackoverflow.com/questions/5651538/speedup-intellij-idea). После настроек сделал max 2Gb и min 1Gb и это оказалось лучше чем я когда выставлял max 7Gb, все равно AppCode всегда показывает использование памяти ок 800Мб.
    2. Комплишен оооочень медленный, в итоге убрал галочки на smart и base completion, мне важно чтобы комплит появлялся, то что он мне помогал бы не совсем важно, иначе с этими галочками приходится по 5 — 10 секунд ждать первые подсказки, а без них всего пару секунд. Еще есть хак, если нужно вызвать метод или переменную из локального скоупа (class/struct/etc) то нужно всегда писать self. тогда видимо отсекаются глобальные области поиска и комплит почти сразу работает. Для глобальных функций/переменных как долго работал так и работает, проще дописать руками или открыть Xcode и там написать и потом обратно переключиться.

    Буквально на днях заметил странную штуку, сборка в AppCode намного дольше чем на Xcode. Тесты проводились следующим образом.
    Xcode:
    1. Закрыл Xcode
    2. Почистил DerivedData (Library/.../Xcode/DerivedData)
    3. Открыл Xcode и сразу нажал запустить проект на симуляторе (то есть полная сборка + запуск)
    Время на всё ушло 3:50-4:00 минуты в Xcode

    AppCode, тоже самое, только чистил его DerivedData (../Caches/../AppCode 2019/../DerivedData/) и AppCode мне выдавал больше 5 минут (нажимал на жука чтобы включить отладку я так понимаю).

    Еще мне очень сильно не нравится в 2019 после 2018 версии, что довольно часто после изменения кода (например изменить имя приватной функции, добавить дополнительный параметр в функцию) всё перестает работать секунд на 10-20, то есть IDE UI не блокирован, но если попробовать посмотреть описание любой переменной или функции в классе (да хочь чего) через cmd+touchpad то ничего не показывает, если нажать на любой (тут я подчеркиваю, что работа с другой нетронутой функцией, а не которая была переименована) вызов функции то не переходит в ее дефенишен и более того эта функция даже не подсвечивается (что по ней можно перейти).

    Еще замечаю (любая версия IDE), что бывают выражения, которые программа с другом вывозит. Вот например внутри функции был код

    let obj1 // CoreData объект из другого модуля
    let obj2 // еще CoreData объект из другого модуля
    let ratio = 100 * obj1.price1 / obj2.price2
    

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

    Очень плохо резолвится chaining, прям проблема
    guard let obj = object?.array.first?.innerObject?.someFireld else { return }
    

    Тут всегда даже подсветка не работает, я уже не говорю, что не может вывести тип. Такое часто когда тип объекта object из другого модуля.

    2019 версия стала подсвечивать больше кода, конечно есть участки где IDE не может понять, но их стало меньше — за это спасибо.

    Уже не помню, но вроде компишен дженериков тоже очень плохо работает
    class A {
        private let relay = RxSwift.BehaviorRelay</* с этого места комплит не работает */User?>(value: nil)
    }
    

    Вот всегда при объявлении подобных переменных тип приходится писать руками, автокомплит молчит.


    1. yeswolf Автор
      18.04.2019 15:00

      в итоге убрал галочки на smart и base completion

      Галочки там стоят на «Automatically insert single suggestion», так что оно влиять на скорость никак не может. Даже если показалось, что что-то изменилось — это не так. По быстродействию автодополнения — проблема известная, будем отсматривать.
      Буквально на днях заметил странную штуку, сборка в AppCode намного дольше чем на Xcode.
      то есть полная сборка + запуск

      Так все таки только сборка, или сборка плюс запуск занимают больше времени? Это два разных процесса, причины замедления там тоже принципиально разные. Чтобы нормально понять — нужны измерения после ?F9 в AppCode (Build) и ?B в Xcode, с предварительно очищенной DerivedData.
      довольно часто после изменения кода (например изменить имя приватной функции, добавить дополнительный параметр в функцию) всё перестает работать секунд на 10-20

      У вас в этот момент код подсвечивается, в правом верхнем углу отображается серый «глаз»? Если код не подсветился и глаз отображается — значит, идет перепарсинг и перерезолв, пока не окрасится код — остальное тоже не отработает. Тут бы снэпшот надо.
      Еще замечаю (любая версия IDE), что бывают выражения, которые программа с другом вывозит.

      И тут тоже бы надо снэпшот.
      Тут всегда даже подсветка не работает, я уже не говорю, что не может вывести тип. Такое часто когда тип объекта object из другого модуля.

      А вот тут бы тестовый проект, потому что крайне трудно воспроизвести то, о чем вы говорите. Если брать минимальный пример типа:

      class MyObject {
          var innerObject: String?
      }
      
      class Test {
          var array: Array<MyObject>?
          func test() {
              var t = Test()
              guard let obj = t.array?.first?.innerObject?.count else {
                 
              }
          }
      }
      


      то здесь все подсвечивается. Поэтому проблема не в chaining, как таковом, а, скорее всего, в сочетании generics в ваших объектах. Понять точно было бы полезно.
      Уже не помню, но вроде компишен дженериков тоже очень плохо работает

      По дженерикам, к сожалению, еще надо пройтись по площадям. Пока не прошлись.


  1. sacred
    18.04.2019 12:29

    Это все конечно круто и классно, но у меня аппкод уже в районе года неюзабелен
    (например вот youtrack.jetbrains.com/issue/OC-18316) и все еще продолжает таким и оставаться.
    После каждой такой новости или твита от вас качаю апдейт, запускаю и вижу что воз и ныне там.

    А помню когда при переходе на подписочную модель обещали что ух сейчас как закроем все баги и займемся перфом. А в реальности для свифта и среднего проекта (унас почти нет реактивщины и прочеей сложной магии) использовать иде физически больно: компиляция на лету с теми же ошибками типа нереализованного протолока занимает много времени, автокомплит почти всегда тупит. Зато темы есть)


    1. yeswolf Автор
      18.04.2019 14:34

      OC-18316 пока не исправили, но в 2019.2 будем работать над скоростью автодополнения целенаправленно. Про компиляцию бы подробнее посмотреть. У нас с Xcode разные DerivedData, если переключаетесь и билдите то там, то там, то вполне может быть.


      1. sacred
        18.04.2019 14:38

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


  1. dachuiko
    18.04.2019 12:50

    и компиляция с необновленными подами заканчивается не очень информативно

    Error:Build failed with 0 errors


    1. yeswolf Автор
      18.04.2019 14:09

      Лог сборки можете переслать в личку? В окне Messages слева есть кнопка «Show build log».


  1. mkovalevskyi
    18.04.2019 19:46

    А можно, в двух словах для начинающих, чем это от XCode отличается?..
    Ибо на офф сайте я такой информации не вижу (


  1. spiceginger
    18.04.2019 19:49

    Спасибо большое. Последний релиз отличный.