Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Хватит это терпеть - запили плагин для IDE

Хватит это терпеть - запили плагин для IDE

День ото дня разработчики сталкиваются с мелкими раздражающими недостатками IDE. То инспекции не хватит, то навигация не работает, как того хотелось бы. Можно, конечно, сетовать на разработчиков IDE, но #тыжпрограммист, можешь запилить всё сам! В этой презентации мы покажем, как упростить себе жизнь, написав плагин для IntelliJ.

Yuriy Artamonov

February 16, 2019
Tweet

More Decks by Yuriy Artamonov

Other Decks in Programming

Transcript

  1. ▪ Мотивация ▪ Как начать ▪ Немного про архитектуру ▪

    Примеры возможностей ▪ Основные сложности ▪ Ссылки План 3
  2. Зачем enterprise-разработчику писать IDE плагины? ▪ У всех есть свои

    наработки: in-house фреймворки, библиотеки, конфиги, процессы и соглашения ▪ Рутинная работа, связанная с исходным кодом, проектом, тестами, развёртыванием 5
  3. ▪ Языки и форматы файлов ▪ Статический анализ кода на

    лету ▪ Навигация между связанными элементами кода ▪ Генерация шаблонного кода ▪ Миграция старого кода на новый API ▪ Взаимодействие с локальными инструментами ▪ Взаимодействие с внешними сервисами через HTTP ▪ Улучшения редактора кода А что бы вы реализовали для себя? Возможности плагинов 7
  4. Базовые технологии IntelliJ Platform ▪ Java + Kotlin ▪ Custom

    JRE (JDK 8 с патчами, ждём JDK 11) ▪ UI на Swing ▪ Custom Look & Feel ▪ Архитектура на базе вложенных IoC-контейнеров (PicoContainer) ▪ Уровни: Application - Project - Module 9
  5. Запасаемся: ▪ Локальная инсталляция IDEA ▪ Плагины: Plugin DevKit, UI

    Designer ▪ Исходный код IDEA CE нужной ветки > git clone https://github.com/JetBrains/intellij-community.git --branch 183.5912 --single-branch Старт разработки 10
  6. Как начать Реалии: ▪ Gradle build ▪ Plugin.xml ▪ …

    ▪ Profit !!!1111 Осталось закодить. НЕЛЬЗЯ ПРОСТО ТАК ВЗЯТЬ И НАЧАТЬ ПИСАТЬ ПЛАГИН 11
  7. Модульность Intellij Ядро IDE - базовая функциональность: ◦ UI-библиотека, ◦

    VFS, PSI, Индексы, ◦ Движок кодовых инспекций и т.д. 12 IntelliJ Platform IDEA CE (Java, Groovy, Kotlin) PHP Support Ruby Support IDEA Ultimate PHP Storm RubyMine
  8. IntelliJ - Точки расширения ▪ Точки расширения для реализации конкретных

    IDE. action, inspection, intention action, ui settings group, language parser, language formatter и т.д. ▪ Точки расширения регистрируются в xml-файле – дескрипторе плагина plugin.xml. ▪ Полный список: LangExtensionPoints.xml, PlatformExtensionPoints.xml, VcsExtensionPoints.xml, etc. Пример: поддержка Groovy – отдельный плагин. Дескриптор > 1700 строк. 13
  9. Пример: уведомление на старте IDE ▪ Файл idea64.vmoptions можно и

    рекомендуется менять для ускорения работы IDE. ▪ Идея: после обновления напоминать разработчику, что он забыл подправить настройки ▪ Точка расширения - <startupActivity> 14
  10. IntelliJ – PSI дерево ▪ PSI = Program Structure Interface

    ▪ Представляют структуру программы для прикладной логики IDE ▪ Как дерево файловой системы, так и внутренние элементы файлов представляются PSI-элементами. ▪ PsiDirectory, PsiPackage, XmlFile, PropertiesFile ▪ Java: PsiJavaFile, PsiField, PsiLocalVariable, PsiTryStatement 15
  11. IntelliJ – PSI элементы ▪ PSI свои у каждого языка

    ◦ PsiForStatement (Java) ◦ GrForStatement (Groovy) ▪ Изменяемые ◦ Изменение PSI сразу отражается в документе ◦ Изменение файла документа → перестройка PSI ▪ Предоставляют API для обхода кода программы и изменения кода 16
  12. IntelliJ – Обход PSI Проверить, что первый аргумент вызова метода

    является исключением. Например: logger.error(e); PsiMethodCallExpression call = …; PsiExpression arg1 = call.getArgumentList().getExpressions()[0]; PsiType argumentType = arg1.getType(); if (JavaExpressionUtil.isInstanceof(argumentType, Throwable.class.getName())) { // then 1st argument of method call is an expression } 17
  13. IntelliJ – UAST Universal Abstract Syntax Tree ▪ Описывает JVM

    languages superset: Java и Kotlin ▪ Позволяет писать универсальный код инспекций ▪ Обёртка над PSI ▪ Элементы ◦ UElement, UFile, UClass, UMember, UField, UMethod, ... ▪ Конструкции ◦ UComment, UDeclaration, UExpression, UBlockExpression, UCallExpression, USwitchExpression, … ▪ Если не хватает возможностей - спускаемся на уровень UAST (resolve) ▪ Не поддерживается кодогенерация (используем PSI) См. org.jetbrains.uast 18
  14. IntelliJ - References ▪ Reference– это ссылка из места использования

    элемента кода к месту его объявления ▪ References могут быть добавлены плагином: <referenceContributor> 19
  15. IntelliJ - References Через references реализуются: ▪ Навигация (go to

    declaration) ▪ Инспекции, такие как Method does not exist ▪ Действие Find Usages ▪ Рефакторинги Rename, Move ▪ Автодополнение (code completion) Пример: переход к объявлению JPA свойств из XML в CUBA Plugin 20
  16. IntelliJ – Code Inspections ▪ Code Inspection – это средство

    статического анализа, фоновая проверка кода ▪ Анализируют PSI дерево: ◦ в открытом редакторе ◦ по всему проекту (Analyze -> Inspect Code) ▪ Могут быть настроены в окне Settings ▪ Quick Fix - трансформируют PSI-дерево, чтобы сразу исправить ошибку 21
  17. Пример: инспекция для JUnit assertEquals Проверка очередности параметров вызова JUnit

    Assert.assertEquals(expected, actual). Идея: actual не может быть константным выражением. Если actual – константа, а expected – нет, то параметры явно перепутаны. 22
  18. IntelliJ – File Based Indexes ▪ Обеспечивают быстрый поиск по

    проекту ▪ Строят отображение ключ -> значение по содержимому файлов ▪ Ключи и значения могут быть произвольного вида, хранятся в бинарном формате ▪ Содержимое индекса зависит только от содержимого конкретного файла, не зависит от других файлов проекта ▪ Обновляются на лету при изменении файла 23
  19. IntelliJ – Базовые индексы ▪ Индекс слов ◦ Ключ –

    хешкод слова ◦ Значение – битовая маска места вхождения (в коде, в комментарии, в строке) ◦ Используется в Find in Path, Find Usages ▪ Индекс имён файлов ▪ Индекс имён java-классов Пример: индекс JPA сущностей в CUBA Plugin 24
  20. Пример: навигация для событий в Spring Spring 4 Events ▪

    События - это сложно ▪ Разработчики воют ▪ IDE не хочет нам помогать Идея: плагин, отображающий навигацию на gutter To Receviers / To Senders 25
  21. Offtopic: External Tools ▪ Частичная альтернатива плагинам ▪ External tool

    – action, выполняющий shell-команду ▪ Возможность передать ▪ контекст (файл, открытый в редакторе, выделенный текст и т. п.) ▪ Можно вызывать по hotkey Пример: tomcat undeploy 26
  22. Ссылки ▪ IDEA Community Edition source code: https://github.com/JetBrains/intellij-community ▪ Plugin

    Development Documentation: http://www.jetbrains.org/intellij/sdk/docs/basics.html ▪ Plugin Development Forum: https://intellij-support.jetbrains.com/hc/en-us/community/topics/20036697 9-IntelliJ-IDEA-Open-API-and-Plugin-Development ▪ Customized IDEA Settings: http://tomaszdziurko.com/2015/11/1-and-the-only-one-to-customize-intellij -idea-memory-settings/ ▪ Более подробно о внутренностях IDEA. Николай Чашников — "IntelliJ IDEA изнутри": https://www.youtube.com/watch?v=NU3DDcsU_Co 28