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

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

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

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

Avatar for Yuriy Artamonov

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