Slide 1

Slide 1 text

Хватит это терпеть - Запили плагин для IDE! Юрий Артамонов

Slide 2

Slide 2 text

22k downloads Куча закачек 2013 год Первая версия 300k LOC Гора кода CUBA IntelliJ Plugin 2

Slide 3

Slide 3 text

■ Мотивация ■ Как начать ■ Немного про архитектуру ■ Примеры возможностей ■ Основные сложности ■ Ссылки План 3

Slide 4

Slide 4 text

А почему вообще IntelliJ IDEA? А какой IDE пользуетесь вы? 4

Slide 5

Slide 5 text

Зачем enterprise-разработчику писать IDE плагины? ■ У всех есть свои наработки: in-house фреймворки, библиотеки, конфиги, процессы и соглашения ■ Рутинная работа, связанная с исходным кодом, проектом, тестами, развёртыванием 5

Slide 6

Slide 6 text

Это можно изменить ! 6

Slide 7

Slide 7 text

■ Языки и форматы файлов ■ Статический анализ кода на лету ■ Навигация между связанными элементами кода ■ Генерация шаблонного кода ■ Миграция старого кода на новый API ■ Взаимодействие с локальными инструментами ■ Взаимодействие с внешними сервисами через HTTP ■ Улучшения редактора кода А что бы вы реализовали для себя? Возможности плагинов 7

Slide 8

Slide 8 text

IDE глазами разработчика Адронный коллайдер 8

Slide 9

Slide 9 text

Базовые технологии IntelliJ Platform ■ Java + Kotlin ■ Custom JRE (JDK 8 с патчами, ждём JDK 11) ■ UI на Swing ■ Custom Look & Feel ■ Архитектура на базе вложенных IoC-контейнеров (PicoContainer) ■ Уровни: Application - Project - Module 9

Slide 10

Slide 10 text

Запасаемся: ■ Локальная инсталляция IDEA ■ Плагины: Plugin DevKit, UI Designer ■ Исходный код IDEA CE нужной ветки > git clone https://github.com/JetBrains/intellij-community.git --branch 183.5912 --single-branch Старт разработки 10

Slide 11

Slide 11 text

Как начать Реалии: ■ Gradle build ■ Plugin.xml ■ … ■ Profit !!!1111 Осталось закодить. НЕЛЬЗЯ ПРОСТО ТАК ВЗЯТЬ И НАЧАТЬ ПИСАТЬ ПЛАГИН 11

Slide 12

Slide 12 text

Модульность Intellij Ядро IDE - базовая функциональность: ◦ UI-библиотека, ◦ VFS, PSI, Индексы, ◦ Движок кодовых инспекций и т.д. 12 IntelliJ Platform IDEA CE (Java, Groovy, Kotlin) PHP Support Ruby Support IDEA Ultimate PHP Storm RubyMine

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Пример: уведомление на старте IDE ■ Файл idea64.vmoptions можно и рекомендуется менять для ускорения работы IDE. ■ Идея: после обновления напоминать разработчику, что он забыл подправить настройки ■ Точка расширения - 14

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

IntelliJ – PSI элементы ■ PSI свои у каждого языка ○ PsiForStatement (Java) ○ GrForStatement (Groovy) ■ Изменяемые ○ Изменение PSI сразу отражается в документе ○ Изменение файла документа → перестройка PSI ■ Предоставляют API для обхода кода программы и изменения кода 16

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

IntelliJ - References ■ Reference– это ссылка из места использования элемента кода к месту его объявления ■ References могут быть добавлены плагином: 19

Slide 20

Slide 20 text

IntelliJ - References Через references реализуются: ■ Навигация (go to declaration) ■ Инспекции, такие как Method does not exist ■ Действие Find Usages ■ Рефакторинги Rename, Move ■ Автодополнение (code completion) Пример: переход к объявлению JPA свойств из XML в CUBA Plugin 20

Slide 21

Slide 21 text

IntelliJ – Code Inspections ■ Code Inspection – это средство статического анализа, фоновая проверка кода ■ Анализируют PSI дерево: ○ в открытом редакторе ○ по всему проекту (Analyze -> Inspect Code) ■ Могут быть настроены в окне Settings ■ Quick Fix - трансформируют PSI-дерево, чтобы сразу исправить ошибку 21

Slide 22

Slide 22 text

Пример: инспекция для JUnit assertEquals Проверка очередности параметров вызова JUnit Assert.assertEquals(expected, actual). Идея: actual не может быть константным выражением. Если actual – константа, а expected – нет, то параметры явно перепутаны. 22

Slide 23

Slide 23 text

IntelliJ – File Based Indexes ■ Обеспечивают быстрый поиск по проекту ■ Строят отображение ключ -> значение по содержимому файлов ■ Ключи и значения могут быть произвольного вида, хранятся в бинарном формате ■ Содержимое индекса зависит только от содержимого конкретного файла, не зависит от других файлов проекта ■ Обновляются на лету при изменении файла 23

Slide 24

Slide 24 text

IntelliJ – Базовые индексы ■ Индекс слов ○ Ключ – хешкод слова ○ Значение – битовая маска места вхождения (в коде, в комментарии, в строке) ○ Используется в Find in Path, Find Usages ■ Индекс имён файлов ■ Индекс имён java-классов Пример: индекс JPA сущностей в CUBA Plugin 24

Slide 25

Slide 25 text

Пример: навигация для событий в Spring Spring 4 Events ■ События - это сложно ■ Разработчики воют ■ IDE не хочет нам помогать Идея: плагин, отображающий навигацию на gutter To Receviers / To Senders 25

Slide 26

Slide 26 text

Offtopic: External Tools ■ Частичная альтернатива плагинам ■ External tool – action, выполняющий shell-команду ■ Возможность передать ■ контекст (файл, открытый в редакторе, выделенный текст и т. п.) ■ Можно вызывать по hotkey Пример: tomcat undeploy 26

Slide 27

Slide 27 text

Написать плагин для IntelliJ в 2019 - Как в булочную сходить ! 27

Slide 28

Slide 28 text

Ссылки ■ 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

Slide 29

Slide 29 text

Спасибо! Вопросы? Twitter: @YuriyArtamonov 29