in-memory компиляция шаблона с зависимостями
RohovDmytro opened this issue · comments
— Понадобилось скомпилировать шаблон, который использует импорты.
— Соответственно, понадобились .obj файлы этих зависимостей из рантайма, но без возможности записать и считать их с диска.
Возможно добавить в АПИ модуля in-memory генерацию obj файла?
Все возможно. Вопрос только в трудозатратах.
Прямо сейчас у меня, если честно, нет на это времени. Там нужно довольно существенно переделывать схему компиляции.
Пусть issue висит, как будет время, попробую сделать.
Локально я реализовал у себя это сверх простым способом.
Добавил в параметр options
поле ´saveObj::bool´. И в месте, где происходит сохранение на диск учитываю это значение. Очень просто. Дефолтное значение можно сделать ´true´.
Примете пулл реквест?
Ну давайте pr, погляжу.
А что если для in-memory компиляции пойти таким путём: передавать в options
, который идёт в compile()
какой-нибудь provide(pathname)
, возвращающий по пути модуль? Если немного поправить w_deimport
и w_deinclude
, то должно работать.
Ну и для compile()
и parse()
добавить новую сигнатуру: compile(options)
, где в самом options
можно передать input
или pathname
.
@rogovdm Насколько я понял, ты возвращаешь obj из compile
, а сохраняешь только при saveObj
?
@pasaran примешь PR?
Добавлю тестов и документацию и уже тогда PR.
Интерфейс ломать не стал, только расширил.
Со стороны пользователя in-memory выглядит довольно просто:
var main = fs.readFileSync('main.yate', 'utf8');
var hello = fs.readFileSync('hello.yate', 'utf8');
// Компилируем модуль.
// Можно добавить filename для лучшего вывода ошибок, иначе <anonymous>
var mod = yate.compile({input: hello});
// Компилируем main.
var res = yate.compile({input: main, modules: {hello: mod.obj}});
Можно так же передать resolve
, чтобы инклюды обрабатывать и provide
вместо modules
, если нужна ещё большая гибкость.
Но есть сколький момент: не стал связывать при импорте AST с файлом. Я не понимаю, когда может понадобиться выводить ошибку с указанием именно на место объявления, а не на место использования, но если такой кейс действительно есть, можно сделать InputStream
ленивым.