Блог пользователя Egor

Автор Egor, 14 лет назад, По-русски
Пожалуй, я уже готов выложить плагин для Intellij Idea для общего доступа (исходный код будет открыт завтра после окончания CodeChef Long Contest)

Что делает данный плагин:
  • Инлайнит классы из вашей библиотеки в один файл
  • Убирает неиспользуемый код
  • Позволяет вбить один раз тесты и запускать на всех тестах одной кнопкой

Что он не делает:
  • Не решает за вас задачи

Плагин находится в стадии альфа-тестирования. Известны следующие баги:
  • Иногда при нажатии на Delete task не удаляется файл самой таски. Можно удалить руками
  • Не удаляет циклические вызовы методов, а так же циклическое использование классов в конструкторе
  • Не удаляет методы, которые исполняют какой-либо интерфейс/являются переопределением методов наследуемых классов. Естественно, если наследуемый класс удален сам или данный класс нигде не используется метод будет удален вместе с классом. Пример - если вы используете класс из библиотеки с определенным методом toString то он не будет удален даже если не используется в коде
  • Не удаляет метод с именем main независимо от сигнатуры
  • Не поддерживаются static imports
Конечно, используете вы плагин на свой страх и риск
Плагин поставляется вместе с проектом, подготовленным для совместного использования. Плагин рассчитывает, что вы будете пользоваться именно этим проектом. В проекте есть 3 таски в качестве примера использования - 2 обычных и 1 для TopCoder.
Инструкция:
  1. Добавить на toolbar кнопки плагина (Customize Menus and Toolbars -> Main Toolbar -> Add after... -> Plug-ins -> Contest helper)
  2. Нажать кнопку New Task. Ввести имя таски, выбрать тип тестов (Single - один тест на файл, Multi Number - первым токеном дано число тестов, Multi EOF - ввод до конца файла либо до теста с нулевыми значениями), тип ввода/вывода (StdIn - стандартный поток, File Task Id - id таски в нижнем регистре + .in/.out, File Custom - какие либо другие названия файлов)
  3. Будет создан и открыт файл, в котором надо непосредственно писать решение. Функции в качестве параметров передадут номер теста в файле (начиная с 1), входной поток (InputReader, о нем ниже) и выходной поток (PrintWriter). Так же будет создан файл чекера, по умолчанию он просто сравнивает токены
  4. Кнопка Edit Tests позволяет вбить тесты. Ваш КО
  5. Когда вы дописали код и вбили тесты - нажимаете кнопку Run Task. Она потупит некоторое время и создаст все необходимые файлы. После этого можно запускать конфигурацию Tester Debug для работы непосредственно в модуле main/lib или Tester Run если вы хотите посмотреть, как будет вести себя непосредственно то, что вы пошлете на сервер
  6. Не забывайте нажимать на кнопку Run Task каждый раз, как вы сделали изменения в вашем коде/добавили тесты. Не стоит менять что-то в классе Main который лежит в модуле test - при следующем запуске Run Task эти изменения потеряются
  7. На сервер надо отсылать файл Main из модуля test
Для топкодера все чуть проще - вам достаточно настроить moj (или любой другой плагин, который генерит сурцы) на корневую папку модуля topcoder. Файл в модуле main будет автоматически сгенерирован, затем нужно будет только нажать Run Task и можно будет нажимать Compile в арене.
Кнопка Delete Task просто удалит таску, а Archive - скопирует все файлы таски в package unsorted модуля archive.
Ваши библиотечные классы должны лежать в модуле lib не в default package и не в package с именем, совпадающем с каким-либо из дефолтных package java (например - java.util)

Ссылки для скачивания:

Update: Про InputReader. В модуле utils в package net.egork.io лежит обрезанная версия моего класса для ввода достаточная для работы плагина. Сделано это чтобы вас не обвинили в использовании чужого кода. Можете дописывать туда все, что вам нужно - этот ввод очень быстро работает

Update 2: Еще замечание - если пишете COCI - не называйте таску так же, как она называется у них. Связано с особенностью их тестера

Update 3: Исходный код тут. Писалось по ночам, не судите строго
И да, хоть кто-нибудь поставил? Если да, то как впечатления? Чего не хватает?

Update 4: Вышла новая версия. Для скачивания доступен плагин и проект. В проекте изменились фалы main/Tester.java, test/Tester.java и utils/main/net/egork/utils/checker/Checker.java, если вы уже скачивали проект вам надо обновить только их
Изменения:
Добавлена кнопка Restore Task которая восстанавливает таски из package unsorted (выдается список, где можно выбрать конкретную таску)
Файл таски синхронизируется перед Run Task
Можно добавить тесты из кода - для этого надо изменить метод generateTests чекера
Есть возможность запустить только на определенных тестах из набора - для этого тестеру в качестве аргументов командной строки надо передать номера тестов. Номера идут с нуля, сначала тесты введенные из GUI, потом тесты из генератора

Update 5: Вышел маленький некритичный фикс. Обновление только для плагина, заново скачивать проект не надо
  • Проголосовать: нравится
  • +23
  • Проголосовать: не нравится

14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
TopСoder плагины нуждаются в одобрении от организаторов TopCoder? Легально ли использование неофициальных плагинов?
  • 14 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится
    Это не плагин для арены, так что я не думаю, что возникнут какие-то проблемы. Ваня Метельский в курсе, если что
14 лет назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится
Ой-ёй-ёй... Ну, я уже говорил, что, по-моему, тем, кто в ACM своё ещё не отыграл, использование такого плагина навряд ли пойдёт на пользу. Так что - Егор развращаэ =)
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Да, jar не надо распаковывать. Просто кидаете его в %user dir%\.IntelliJIdea10\config\plugins и перезапускаете идею
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    А под Eclipse это можно приспособить?
    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Я думаю можно переписать если Eclipse предоставляет плагинам похожий API
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

> Не забывайте нажимать на кнопку Run Task каждый раз, как вы сделали изменения в вашем коде/добавили тесты.

Может её лучше обозвать Generate Main или как-то так? И ещё добавить сохранение изменений в редактируемых файлах, как делает это обычный Run.

> Если да, то как впечатления?

Вообще я немного не понял, как сделать типа unarchive? Непосредственно переместить 3 файла в main? Как изменить текущий task на другой? Что должно происходить по кнопочке с биноклем и именем текущего task? Показываться окно настройки текущего task? К чему тогда бинокль? Список task-ов? К чему тогда имя текущего task? У меня, короче, ничего не показывается... и в логах никаких exception-ов.

Окна New Task/Edit Tests (хотя title у них отсутствует) показываются постоянно в левом верхнем углу (хотя диалоговые окошки самой IDEA обычно показываются в центре экрана).

Для topcoder можно как-то задать тесты? Или только в коде метода main? Вам не кажется, что если бы для codeforces было бы точно также, то это было бы логичней и даже иногда удобнее?

В общем идея прикольная... но только вот много слишком на форматировании кода завязано. Ну т.е. если например, у меня будет моя библиотека подрубаться вот такой строчкой: " import my.fuck.*;", т.е. с безобидным пробелом в начале строки (ну или как многие любят "import java.util.*; import my.fuck.*;" одной строчкой) - то плагин уже не поймёт это, и сгенерит мне некомпилируемый код. Я понимаю что по-хорошему надо придерживаться coding standards и всё такое, но...

> Чего не хватает?

Не хватает парсера заданий с codeforces с автоматической генерацией классов и файлов с тестовыми входными данными из примеров. :)

  • 14 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится
    1. Сохранение перед генерацией уже добавлено в TODO, на выходных добавлю. Сам ухитрился ни разу не напороться так как у меня Ctrl+s наживается автоматом на уровне подсознания

    2. Unarchive - да, пока никак. Добавлю в TODO возможность вернуть таску из папки Unsorted

    3. Бинокль - да, список тасков должен появляться. А какая версия идеи? А то у меня все диалоги непосредственно под кнопкой появляются. Надо будет скриншотов наделать чтобы все видели, как оно должно быть и жаловались, если не так

    4. Для топкодера только в коде. Потому и кнопка задисейблена. Добавить поддержку тестов с топкодера - очень далекий TODO. Для Codeforces будет добавлена возможность возвращать коллекцию тестов из чекера, но текуший вариант лично мне кажется удобнее (в старом тимплейте у меня так и было)

    5. А что, кто-то, кто пишет в идее ручками форматирует список импортов? о_О. Не, ну trim я добавлю, а вот с импортами в одну строчку вряд ли что-то буду делать

    6. С удовольствием приму в дар код такого парсера и подключу к плагину
    И да, большое спасибо за фидбек
    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      1. IDEA сама чёрти с какой версии сохраняет любые изменения в файле (не дожидаясь Ctrl+S). Так что у меня эта привычка уже давно атрофировалось.

      3. Последняя стабильная - 10.0.3. Дело может быть в том, что запущена она под JDK 1.7.

      4. Добавлять тесты через окошко, ИМХО, неудобно... да и для codeforces часто надо генерить максимальные тесты программно. Ну и запускать одним хоткеем (типа Ctrl+Shift+F10) удобнее, чем двумя (Run Task, Shift+F10, ещё и возможно придётся выбрать соответствующую конфигурацию).

      5. Нет, но просто чтоб пользоваться этим плагином надо очень хорошо понимать как он работает... т.к. многие тонкости не учтены, то можно наткнуться на очень с первого взгляда странные грабли. Например напишу я у себя внутри метода:
      /*
      import my.fuck.Fuck;
      */
      и оно будет попытаться добавить этот класс. :)

      6. Я задумываюсь над таким, но боюсь он будет в непригодном виде для простого подключения (т.к. будет не на Java).

      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        3. В общем, очень странное поведение. Но я вроде только Public API использую, никаких там SwingUtilities2. Если не сложно, то можно выкачать код плагина и посмотреть под дебагером
        4. Мне удобнее, чем в код - особенно редактировать. Но да, уже сказал, что добавлю возможность выдавать добавлять коллекцию тестов из чекера (что и для генератора будет самое оно)
        5. Как подключит, так и похерит в общем то
        • 14 лет назад, # ^ |
          Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

          3. После перезапуска IDEA кнопочка с именем Task-а работает - показывает список, только почему-то развернутым на весь экран (ну т.е. окно типа normal, а не dialog). После хотя бы одного запуска action-а "New Task" кнопочка работать перестает (до перезапуска IDEA). Возможно это глюки несовместимости моего WM и явы, которых у вас нету - лучше создавать диалоговые окошки также как это делают в самой IDEA.

          5. Спорный вопрос...

          import java.util.*;
          ...
          /*
          import my.fuck.Arrays;
          */
          Arrays.sort(new int[]{...});

          В таком случае оставит, причем в нерабочем виде (если в my.fuck.Arrays не определен метод sort)... ;)

          Но это всё тонкости, на которые можно забить.
          • 14 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится
            3. Могу только предложить подебагать. У меня такого не было никогда

            • 14 лет назад, # ^ |
                Проголосовать: нравится 0 Проголосовать: не нравится
              Вот это помогает:
              % hg diff plugin/main/net/egork/plugin/SelectTaskDialog.java
              diff -r 92c6cc71a045 plugin/main/net/egork/plugin/SelectTaskDialog.java
              --- a/plugin/main/net/egork/plugin/SelectTaskDialog.java	Fri Apr 15 15:08:56 2011 +0400
              +++ b/plugin/main/net/egork/plugin/SelectTaskDialog.java	Sat Apr 16 00:53:50 2011 +0300
              @@ -13,7 +13,7 @@
               	private TaskConfiguration selectedTask;
               
               	private SelectTaskDialog() {
              -		super(null, ModalityType.DOCUMENT_MODAL);
              +		super((Frame)null, true);
               		selectedTask = ConfigurationHolder.getInstance().getCurrentTask();
               		final TaskConfiguration[] tasks = ConfigurationHolder.getInstance().getTasks();
               		final JBList taskList = new JBList(tasks);
              
              • 14 лет назад, # ^ |
                  Проголосовать: нравится 0 Проголосовать: не нравится
                Это ломает то, что можно закрыть список кликнув в любом другом месте. Надо будет мне поставить 7й сдк и посмотреть - если повторится, то зафайлить багу в оракл
                • 14 лет назад, # ^ |
                  Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

                  Поверьте опыту - постить баги в Оракл/Сан - практически бесполезное занятие... скорее всего этот баг уже есть у них в багтрекере и этак лет десять уже там.

                  Ну и учтите что этот баг, скорее всего, специфичен для X11 (т.е. только для JDK под Linux/Solaris, да и то не во всех WM может проявляться).

                  P.S. Кстати, посмотрите как сделано окно About у самой IDEA - оно работает нормально и закрывается как вы хотите.

14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
...  I see "Eliminates unused code" is very useful...
but I do not know how to use it .... does it can use as a normal TopCoder Plug-in?.
... or a Tools ..in other way..
and does it has a cpp version ..?
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    It is plug-in for Intellij Idea, IDE for Java. In order to interact with TopCoder Arena it requires some existing TC plug-in, I recommend moj. Just set source folder in FileEdit to topcoder module of your project.
    No C++ version as Idea do not support it. Also I think considering macroses it is not really possible
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Вообще не очень он дружественно работает.

SRM 506: в первой задаче комментарий о том, что настоящее решение внизу, неуместен, поскольку ничего из библиотеки не включается.

Во второй задаче написано опять же, что настоящий код внизу, а на самом деле решение почти ровно посередине.

Это так и задумано?
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    У меня в библиотеке новой не было минкоста. Потому я скопировал из старой библиотеки. Это легко заметить по тому, что оно все лежит в основном классе, в то время как то, что инлайнится лежит в классах верхнего уровня
    В первой противоречия не вижу - оно ведь и вправду самый нижний класс, просто он единственный
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Вопрос по Idea. Она легко выделяет неиспользуемые методы, но можно ли их удалить автоматически, не смог найти такой услуги в Idea?