@pqgg7nwkd4

Как определить тип выражения, написанного на java?

Добрый день.

Пишу шаблонизатор, который транслирует код шаблона в код java, а затем компилирует с помощью javax.tools. Прошу оставить вопрос целесообразности.

Хочется в шаблонизатор добавить автоматический вывод типа выражения.
Например, есть команда шаблонизатора (команды заключаются в обратные кавычки):
`for x: dataSource.getUsers(true)`
...
`/for`
// В данном коде dataSource.getUsers(true) - это некий метод, который возвращает Iterable<User>


Транслироваться в Java это должно так:
for(User x: dataSource.getUsers(true)) {
  out("\n...\n");
}


Вариации выражения могут быть какими угодно:
`for x: dataSource.getUsers(true)`
`for x: ("1,2" + ",3").split(",")`


Вопрос: как мне при трансляции понять, какой тип элемента вернет выражение в for?
  • Вопрос задан
  • 164 просмотра
Пригласить эксперта
Ответы на вопрос 1
@fantomasdnb
Java разработчик, BPM
Поставьте себя на место транслятора.
Вы читая строку `for x: dataSource.getUsers(true)` должны знать, что такое dataSource - какого он типа, что возвращает getUser и вообще есть ли он.
Откуда это можно узнать? - Из текста программы. Замечу, что значения в Wildcard <> в рантайме уже неизвестно.
Для примера с dataSource это должно быть описано где-то в коде: определение поля класса или локальной переменной. Если этой информации нет, то значит, что вы сами этого не знаете и компилятор научить не сможете.
Согласитесь, если я напишу for x: foo.getBar('1'). вы не будете понимать что это и спросите: "а где объявлена foo и что возвращает метод". Для этого нужны исходники (возможно вы и так это понимаете) .

Для примера с "1,2" + ",3" тип понятен из контекста.

Что делать дальше: вам нужен практически парсер/компилятор java. Я бы для этого посмотрел в сторону AST (Abstract Syntax Tree) из эклипса. Не самое удобное API и можно легко написать плохой код, но оно 100% решит задачу.)

С помощью него можно распарсить текст до шаблона, узнать тип переменной и тип возвращаемого значения и получить тип в <>.
Со строками будет аналогично, только тип можно получить сразу, без парсинга остального кода, так как известно что литерал типа String и все методы этого типа известны всем.

Надеюсь хоть что-то понятно.

К слову то, что вы пытаетесь сделать уже реализовано в похожем виде в приблуде под названием Xtend.
https://eclipse.org/xtend/documentation/203_xtend_...
Возможно вам это поможет, правда документация у них покоробилась...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы