Решение для языка Groovy 6 Использование в языке Java 7 Структура реализации плагина для Intellij idea 9



Скачать 82.92 Kb.
Дата31.07.2016
Размер82.92 Kb.
ТипРешение
Санкт-Петербургский Государственный Университет

Математико-механический факультет

Кафедра системного программирования


Улучшение автодополнения для языка Groovy в

IDE IntelliJ IDEA

Курсовая работа студента 445 группы

Абишева Тимура Маратовича
Научные руководители: Мухин М. А.

Программист ООО «ИнтеллиДжей Лабс»

Орехов Р. С.

Инженер-программист ЗАО «Ланит-Терком»


Санкт-Петербург

2011

Оглавление


Оглавление 2

Введение 2

Постановка задачи 4

Решение 5

Основная идея решения 5

Решение для языка Groovy 6

Использование в языке Java 7

Структура реализации плагина для IntelliJ IDEA 9

Дальнейшее развитие 9

Результаты 10

Список литературы 11





Введение


Groovy – объектно-ориентированный, динамически типизированный язык, с широкой поддержкой метапрограммирования. Для него автодополнение в средах разработки, таких как IntelliJ IDEA, Eclipse или Netbeans, работает плохо:



Рис.

Более полная работа автодополнения в средах разработки облегчает разработку приложений.

Отметим основные источники плохого автодополнения:


  • невозможность вывода типа переменной



Рис.

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



  • использование возможностей метапрограммирования

Этот случай неправильного срабатывания автодополнения можно видеть на Рис. 1. В данном примере средствами метапрограммирования у класса создавалось 3 новых метода: changeRoleToUser(), changeRoleToModerator() и changeRoleToAdmin(). Так как все современные среды разработки для языка Groovy для обеспечения автодополнения используют лишь статический анализ кода, мы не наблюдаем вышеописанных методов в автодополнении.

Пример добавления методов к классу Object можно найти в исходниках Grails [1].



  • использование метода method_missing

В языке Groovy существует возможность отлавливать вызов несуществующего метода у класса и обрабатывать данный случай. В случае отсутствия у класса вызываемого метода, но наличия метода с названием method_missing, последний вызывается с аргументами в виде имени вызываемого метода и его фактических параметров.

К примеру, в объектно-реляционном отображении под названием GORM, используемом в Grails, данная возможность ранее использовалась следующим образом [2]: если в коде был вызов Person.findByName(name), то, так как у класса Person не было метода findByName, осуществлялся вызов Person. method_missing(“findByName”, name). method_missing, в случае GORM, разбирал название отсутствующего метода (“findByName”) и извлекал из него имя поля и необходимые действия с ним (соответственно name и find).

Если класс использует метод method_missing, очень сложно предугадать все возможные допустимые имена методов. Иногда среды разработки подстраиваются под библиотеки, что в свою очередь выливается в необходимость разработчиков IDE поддерживать постоянно изменяющиеся возможности библиотеки/каркаса приложений. IntelliJ IDEA именно таким образом поддерживает GORM.

Gradle также использует method_missing [3].



Постановка задачи


Улучшить автодополнение в языке Groovy для случая использования метапрограммирования в контексте класса, а также предложить методы улучшения автодополнения в случаях использования method_missing.

Решение

Основная идея решения


Основной идеей решения является использование динамического взаимодействия с классами вместо статического анализа кода для получения списка автодополнения. Во время вызова автодополнения в среде разработки с помощью механизма Java Reflection динамически создается объект класса переменной, для которой вызвано автодополнение. Далее у объекта вызывается метод getCompletionList(), который должен возвращать список строк (в терминологии языка java – List). Все строчки, полученные в результате данного вызова, будут добавлены в список автодополнения среды разработки.

Соответственно, решение задачи состоит из двух частей: разработки плагина для среды разработки, осуществляющего создание экземпляра класса и вызов метода у него, и второе, разработка метода getCompletionList() у классов языка Groovy, обеспечивающего максимально корректный и полный список методов для автодополнения.

Ограничениями данного подхода являются:


  • файл с классом, для которого надо улучшить автодополнение, должен быть откомпилирован на момент запуска автодополнения;

  • этот класс должен иметь конструктор по умолчанию.



Решение для языка Groovy


Алгоритм для получения элементов автодополнения состоит из нескольких частей:

  • получения всех возможных имен методов класса с помощью вызова методов getMetaMethods и getMethods у метакласса объекта;

  • удаление среди них всех методов, полученных вызовом getMethod у стандартного класса объекта (так как они определяются средой разработки);

  • удаление стандартных методов, присущих всем классам языка Groovy;

  • удаление всех методов, содержащих в названии знак “$” либо “__”, как нужных лишь для внутренних нужд языка Groovy.

Реализация данного алгоритма приводится ниже:



Рис.

Также для случаев реализации классом метода method_missing предоставляется возможность реализации корректного getCompletionList() со стороны разработчиков библиотек. В таком случае задача поддержки корректного автодополнения ложится на разработчиков библиотеки.

Для использования улучшенного автодополнения в своих проектах на языке Groovy необходимо сделать несколько шагов:


  • установить плагин для среды разработки;

  • подключить класс VeryGoodCompletion.groovy в свой проект;

  • аннотировать классы, для которых желательно улучшенное автодополнение, аннотацией @Mixin(VeryGoodCompletion).



Использование в языке Java


Использование концепции воздействия класса на автодополнение в среде разработки возможно и в языке Java. Так как язык Java является языком со статической типизацией, то для сред разработки не составляет труда с помощью статического анализа кода предлагать хорошее автодополнение. Однако в некоторых случаях возможно введение автодополнения, специализированного под конкретные случаи и не поддерживаемого в среде разработки. К примеру, пусть создается веб-фреймворк. Одной из его составляющих вещей обязательно будет маршрутизация. Допустим, маршрутизация в приложении, написанном на этом фреймворке, реализуется следующим образом:



Рис.

При реализации контроллера в приложении у нас может возникнуть потребность перенаправления на другую страницу (redirect). Это может быть реализовано, к примеру, вот так:





Рис.

Хотелось бы, чтобы на момент набора вызова метода redirectTo в списке автодополнения среды разработки в качестве вариантов были все доступные маршруты нашего приложения. Это возможно посредством реализации метода getCompletionList() для класса Response, например, таким образом:





Рис.

Структура реализации плагина для IntelliJ IDEA


  • RuntimeCompletion.java – основной класс, реализующий дополнительное автодополнение, имеет два основных отображения (Map):

    • TYPE_RESOLVERS – отображение из названия языка в TypeResolver;

    • COMPLETION_PROVIDERS – отображение из названия языка в ICompletionProvider.

  • TypeResolver.java – интерфейс, определяющий тип переменной в позиции указателя;

  • ICompletionProvider.java – интерфейс, определяющий метод получения списка автодополнения на основе текущего проекта, класса текущей переменной, а также классов параметров типа текущей переменной;

  • в пакетах java и groovy содержится реализация вышеназванных интерфейсов для языков Java и Groovy;

  • в пакете utils содержатся утилитарные классы;

  • в пакете jvm содержатся различные классы для работы с виртуальной машиной java.



Дальнейшее развитие


Существует множество путей дальнейшего развития данной курсовой работы. Хотелось бы отметить основные из них:

  • отделение кода для автодополнения от основного библиотечного кода, разработка некоторого плагинного формата подключения кода для автодополнения к основному коду;

  • добавление поддержки языков Scala и JRuby, как языков, также основанных на jvm;

  • добавление поддержки какого-либо языка не на платформе Java, к примеру, Ruby;

  • популяризация решения в среде разработчиков.



Результаты


В результате данной курсовой работы был разработан плагин для среды разработки IntelliJ IDEA, существенно улучшающий в определенных случаях качество автодополнения для языка Groovy, а также предлагающий методы улучшения автодополнения для определенных случаев в языке Java.

Код плагина можно скачать по адресу https://github.com/ttim/rcompletion, код различных примеров использования плагина по адресу https://github.com/ttim/rcompletion-example.

Ревизии на момент написания работы были:


  • rcompletion 9131747fda64e7f21c78165c61649e48c5bbf771;

  • rcompletion-example 4cc58667c4b4f93d326fd478b8d18ca6d14e949e.

Также плагин можно скачать из репозитория плагинов для среды разработки IntelliJ IDEA под названием Runtime Completion.

Список литературы


[1] GitHub // grails-plugin-codecs/src/main/groovy/org/codehaus/groovy/grails/plugins/CodecsGrailsPlugin.groovy at master from grails/grails-core – GitHub // URL: https://github.com/grails/grails-core/blob/master/grails-plugin-codecs/src/main/groovy/org/codehaus/groovy/grails/plugins/CodecsGrailsPlugin.groovy // проверено 08.06.2011

[2] GitHub // grails-hibernate/src/main/groovy/org/codehaus/groovy/grails/plugins/orm/hibernate/HibernatePluginSupport.groovy at fcae731cd31f2486ff3e28eb726b1c841dcd8e87 from grails/grails-core – GitHub // URL: https://github.com/grails/grails-core/blob/fcae731cd31f2486ff3e28eb726b1c841dcd8e87/grails-hibernate/src/main/groovy/org/codehaus/groovy/grails/plugins/orm/hibernate/HibernatePluginSupport.groovy // проверено 19.06.2011



[3] GitHub // subprojects/core-impl/src/main/groovy/org/gradle/api/internal/artifacts/publish/maven/deploy/groovy/DefaultGroovyMavenDeployer.groovy at master from gradle/gradle – GitHub // URL: https://github.com/gradle/gradle/blob/master/subprojects/core-impl/src/main/groovy/org/gradle/api/internal/artifacts/publish/maven/deploy/groovy/DefaultGroovyMavenDeployer.groovy // проверено 08.06.2011



Поделитесь с Вашими друзьями:


База данных защищена авторским правом ©uverenniy.ru 2019
обратиться к администрации

    Главная страница