Добрый день!
Я сейчас пробую написать преобразователь Java кода в Arduino код (практически C).
Я так понимаю, это похоже на то что Вы делали. Но Вы используете Groovy, а я на чистой Java решил попробовать. Для анализа кода решил использовать ASTParser от Eclipse. И сразу возникло несколько вопросов. Каким образом Вы с исходниками работали? С помощью средств Groovy или ASTParser (хотя он вроде только для Java кода)? И как генерировали результирующий код из Java кода? Я сначала думал что ASTParser позволит просто изменить исходный код — т.е. по ходу парсинга в ASTVisitor изменяем текущую сущность, если надо, и дальше получаем исходник. Но как я понял, для этого используется другая сущность — ASTWriter, которая работает только для редактирования. А это мне вроде как не подходит. Поэтому возник второй вариант — самому формировать исходный код — например, формировать StringBuilder который при парсинге в ASTVisitor будет дополняться кодом. Вообще, может у вас какие нибудь идеи есть по этому поводу?
Добрый день!
Спасибо за интересную статью!
Просветите, пожалуйста, по поводу следующих нубовских вопросов:
В шейдерах код же исполняется native? А как решается вопрос с GC, как очищаются объекты? Или их нельзя создать? И можно ли создать свои классы?
Можно ли подобным образом компилировать Java код в C++? Я как-то нашёл проект для компиляции Java в C++ для микроконтроллеров (например, Arduino) — называется HaikuVM. И насколько я понял, там используется похожий принцип по разбору AST, но генерируется C++ который больше похож на байт код — по сути каждая инструкция из байт кода — преобразуется в вызов C функции с таким же названием. А у Вас же, насколько я понял, генерируется исходный код, который практически соответствует исходному Java коду. Или не так?
Периодически наблюдаю за вашей TeaVM — с того момента, как Вы статью на хабре написали. Сам писал на GWT, т.ч. интерес был не праздный. Но статей уже давно небыло. Не планируете написать ещё стаью о текущем состоянии дел с TeaVM? На github находил статьи на английском, но может тут напишете?
А в чём фишка поля (field) tag? Я так по коду понял, что если это поле есть, то при выводе лога оно печатается. Так? Ну и не могли бы Вы use case показать применимости тега? А то я с таким первый раз встречаюсь.
4. А существует ли более быстрый способ узнать имя вызывающего класса?
К сожалению, я его не знаю. По моему, в runtime этого нельзя быстро сделать.
А кстати в android.util.Log уровни сделаны константами, а не энамом.
Интересно, не знал. Сейчас посмотрел — действительно, числовые константы. Вообще в JUL (java.util.logging) Level тоже не enum, но используется как enum — final static поля с экземплярами этого класса на которые потом ссылаются.
P.S. Я вообще не придираюсь — просто интересно сделать code review. :)
1. Рефлексия — это плата за удобство использования.
В целом согласен — использовать удобно. Но нельзя ли в Android использовать compile-time аспекты? Может что то вроде AspectJ CTW? Может с этим получится сделать быстрое получение имени метода и класса? Т.е. при компиляции аспектов получать имя метод и класса у вызывающего кода и дальше его использовать. Конечно, будет сложнее чем сейчас — нужно будет компиляцию настраивать в gradle, но зато perfomance будет лучше.
4. Получение имени вызываемого класса через создание исключение (new Throwable().getStackTrace();) медленно.
5. Конструктор должен быть приватным. (насколько я понял, экземпляр этого класса из вне нельзя создать).
6. Поля V, D, I, и т.д., наверное, стоит сделать в виде enum.
А Вы поддержке IDEA писали по этому поводу? Если есть баг у них на трекере, то напишите, я проголосую за него (как, наверное, и многие из этого типика). Они вроде открыты для изменений — нужно только написать.
А как из C# работали с docx? Какие-то готовые решения или сами парсили xml? И как себя проект на Mono ведёт? Были ли ошибки? Я сам не C# разработчик и поэтому здесь могу ошибаться, но я слышал, что на крупных проектах нельзя так просто взять и перейти на Mono.
На счёт Docker интересно придумано! Он у вас и в production используется? А то на сколько я знаю, это технология больше для разработки подходит (для разворачивания на dev/test машинах).
О, так вообще всё шикарно получается — всё в runtime работает и не требует предварительной компиляции! Но при таком раскладе возможно увеличение времени старта — на генерация byte code. Не замечали такого? Или оно совсем мало?
Статья интересная. Сам пробовал на JNA писать. Понравился своей простотой.
А в плане использования не могли бы вы объяснить, как это выглядит? Вот в JNA я описал интерфейс и вызываю метод, который загружает dll (возьмём Windows) и делает инстанс интерфейса для этой dll. И всё. Больше ничего не нужно прописывать, главное, чтобы JNA был в classpath и приложение могло найти dll. А здесь как? Вы говорили, что генерируется byte code. А на каком этапе это происходит? При сборке? Т.е. есть ли какой нибудь gradle задача (для примера), которая при сборке обрабатывает исходники и генерирует byte code? Например, как в AspectJ CTW. Я build.gradle вашего проекта посмотрел, но ничего такого не нашёл (возможно, плохо искал) и pdf презентации тоже посмотрел.
Вообще если это так же просто как JNA, но так же быстро как JNI, то потрясающе! :)
P.S. Странно, что reflection такой медленный, его же вроде от версии к версии ускоряют.
Читал о шаблонах в xsd в samolisov.blogspot.ru/2013/01/xml.html Там, кстати, «Райского сада» нет.
Соглашусь, тема вообще интересная — я когда xsd писал не подозревал о существовании шаблонов в такой, вроде бы простой, области. Сам использовал «Венецианское жалюзи» — удобно при описании больших типов со вставкой комментариев. Если «Матрёшку» использовать, то будет большой тип, в котором сложно ориентироваться, в моём случае.
Ходил на такие квесты — понравилось. Задавался вопросом, как такое может быть устроено, а тут как раз такая статья! Спасибо!
Несколько вопросов:
У вас в квестах только «электрическая» логика реализована? Я, например, сталкивался с заданием, где была проволока из материала с памятью — при нагреве она изменяла положение и становилась цифрой, которая нужна для кода.
Кто и как придумывает квесты и задания к ним?
В какой IDE пишете для Arduino?
Ссылок на фирму, для которой делаете квесты, не будет? :)
P.S. Порадовался за ссылку на chipster — сам им пользуюсь :)
Вот это пруфы так пруфы!
P.S. Полностью согласен — сам работал с проектом, где использовались коды вместо Exception. Очень не удобно обрабатывать, много лишних проверок.
Я сейчас пробую написать преобразователь Java кода в Arduino код (практически C).
Я так понимаю, это похоже на то что Вы делали. Но Вы используете Groovy, а я на чистой Java решил попробовать. Для анализа кода решил использовать ASTParser от Eclipse. И сразу возникло несколько вопросов. Каким образом Вы с исходниками работали? С помощью средств Groovy или ASTParser (хотя он вроде только для Java кода)? И как генерировали результирующий код из Java кода? Я сначала думал что ASTParser позволит просто изменить исходный код — т.е. по ходу парсинга в ASTVisitor изменяем текущую сущность, если надо, и дальше получаем исходник. Но как я понял, для этого используется другая сущность — ASTWriter, которая работает только для редактирования. А это мне вроде как не подходит. Поэтому возник второй вариант — самому формировать исходный код — например, формировать StringBuilder который при парсинге в ASTVisitor будет дополняться кодом. Вообще, может у вас какие нибудь идеи есть по этому поводу?
Спасибо за интересную статью!
Просветите, пожалуйста, по поводу следующих нубовских вопросов:
В шейдерах код же исполняется native? А как решается вопрос с GC, как очищаются объекты? Или их нельзя создать? И можно ли создать свои классы?
Можно ли подобным образом компилировать Java код в C++? Я как-то нашёл проект для компиляции Java в C++ для микроконтроллеров (например, Arduino) — называется HaikuVM. И насколько я понял, там используется похожий принцип по разбору AST, но генерируется C++ который больше похож на байт код — по сути каждая инструкция из байт кода — преобразуется в вызов C функции с таким же названием. А у Вас же, насколько я понял, генерируется исходный код, который практически соответствует исходному Java коду. Или не так?
К сожалению, я его не знаю. По моему, в runtime этого нельзя быстро сделать.
Интересно, не знал. Сейчас посмотрел — действительно, числовые константы. Вообще в JUL (java.util.logging) Level тоже не enum, но используется как enum — final static поля с экземплярами этого класса на которые потом ссылаются.
P.S. Я вообще не придираюсь — просто интересно сделать code review. :)
5. Конструктор должен быть приватным. (насколько я понял, экземпляр этого класса из вне нельзя создать).
6. Поля V, D, I, и т.д., наверное, стоит сделать в виде enum.
P.S. Игра — найди 10 ошибок?
На счёт Docker интересно придумано! Он у вас и в production используется? А то на сколько я знаю, это технология больше для разработки подходит (для разворачивания на dev/test машинах).
А в плане использования не могли бы вы объяснить, как это выглядит? Вот в JNA я описал интерфейс и вызываю метод, который загружает dll (возьмём Windows) и делает инстанс интерфейса для этой dll. И всё. Больше ничего не нужно прописывать, главное, чтобы JNA был в classpath и приложение могло найти dll. А здесь как? Вы говорили, что генерируется byte code. А на каком этапе это происходит? При сборке? Т.е. есть ли какой нибудь gradle задача (для примера), которая при сборке обрабатывает исходники и генерирует byte code? Например, как в AspectJ CTW. Я build.gradle вашего проекта посмотрел, но ничего такого не нашёл (возможно, плохо искал) и pdf презентации тоже посмотрел.
Вообще если это так же просто как JNA, но так же быстро как JNI, то потрясающе! :)
P.S. Странно, что reflection такой медленный, его же вроде от версии к версии ускоряют.
Соглашусь, тема вообще интересная — я когда xsd писал не подозревал о существовании шаблонов в такой, вроде бы простой, области. Сам использовал «Венецианское жалюзи» — удобно при описании больших типов со вставкой комментариев. Если «Матрёшку» использовать, то будет большой тип, в котором сложно ориентироваться, в моём случае.
Несколько вопросов:
У вас в квестах только «электрическая» логика реализована? Я, например, сталкивался с заданием, где была проволока из материала с памятью — при нагреве она изменяла положение и становилась цифрой, которая нужна для кода.
Кто и как придумывает квесты и задания к ним?
В какой IDE пишете для Arduino?
Ссылок на фирму, для которой делаете квесты, не будет? :)
P.S. Порадовался за ссылку на chipster — сам им пользуюсь :)
P.S. Полностью согласен — сам работал с проектом, где использовались коды вместо Exception. Очень не удобно обрабатывать, много лишних проверок.