|
14 | 14 | ****************************************************************************/ |
15 | 15 |
|
16 | 16 | #include "compilerwrap.h" |
| 17 | +#include "compilerhandle.h" |
17 | 18 | #include "live/visuallog.h" |
18 | 19 | #include "live/utf8.h" |
19 | 20 | #include "live/path.h" |
@@ -292,9 +293,177 @@ void compileModuleWrap(const Napi::CallbackInfo &info){ |
292 | 293 | } |
293 | 294 | } |
294 | 295 |
|
| 296 | +Napi::Value createCompilerWrap(const Napi::CallbackInfo &info){ |
| 297 | + Napi::Env env = info.Env(); |
| 298 | + if( info.Length() < 1 || !info[0].IsObject() ){ |
| 299 | + Napi::TypeError::New(env, "Expected options argument: createCompiler(options:Object)").ThrowAsJavaScriptException(); |
| 300 | + return env.Null();; |
| 301 | + } |
| 302 | + |
| 303 | + Napi::Object optionsArg = info[0].As<Napi::Object>(); |
| 304 | + |
| 305 | + Napi::Value err = env.Undefined(); |
| 306 | + Napi::Value res = env.Undefined(); |
| 307 | + |
| 308 | + try{ |
| 309 | + MLNode compilerOptions; |
| 310 | + |
| 311 | + if ( optionsArg.Has("log") ){ |
| 312 | + Napi::Object logOptionsArg = optionsArg.Get("log").As<Napi::Object>(); |
| 313 | + MLNode logOptions; |
| 314 | + convertToMLNode(logOptionsArg, logOptions); |
| 315 | + |
| 316 | + VisualLog().configure("global", logOptions); |
| 317 | + optionsArg.Delete("log"); |
| 318 | + } |
| 319 | + |
| 320 | + convertToMLNode(optionsArg, compilerOptions); |
| 321 | + |
| 322 | + lv::el::Compiler::Config config; |
| 323 | + config.initialize(compilerOptions); |
| 324 | + lv::el::Compiler::Ptr compiler = lv::el::Compiler::create(config); |
| 325 | + |
| 326 | + |
| 327 | + auto externalCompilerPtr = Napi::External<lv::el::Compiler::Ptr>::New( |
| 328 | + env, |
| 329 | + new lv::el::Compiler::Ptr(compiler), |
| 330 | + [](Napi::Env env, lv::el::Compiler::Ptr* data){ |
| 331 | + delete data; // Clean up when the external is garbage collected |
| 332 | + } |
| 333 | + ); |
| 334 | + |
| 335 | + |
| 336 | + Napi::Object obj = CompilerHandle::constructor.New({ externalCompilerPtr }); |
| 337 | + Napi::Object result = Napi::Object::New(env); |
| 338 | + result.Set("value", obj); |
| 339 | + return result; |
| 340 | + |
| 341 | + } catch ( lv::el::SyntaxException& e ){ |
| 342 | + Napi::Object ob = Napi::Object::New(env); |
| 343 | + populateSyntaxError(env, ob, &e); |
| 344 | + err = ob; |
| 345 | + } catch ( lv::el::TracePointException& e ){ |
| 346 | + Napi::Object ob = Napi::Object::New(env); |
| 347 | + populateError(env, ob, &e); |
| 348 | + err = ob; |
| 349 | + } catch ( lv::Exception& e ){ |
| 350 | + Napi::Object ob = Napi::Object::New(env); |
| 351 | + populateError(env, ob, &e); |
| 352 | + err = ob; |
| 353 | + } catch ( std::exception& e ){ |
| 354 | + Napi::Object ob = Napi::Object::New(env); |
| 355 | + populateErrorMessage(env, ob, &e); |
| 356 | + err = ob; |
| 357 | + } catch ( ... ){ |
| 358 | + Napi::Object ob = Napi::Object::New(env); |
| 359 | + populateErrorMessage(env, ob, nullptr); |
| 360 | + err = ob; |
| 361 | + } |
| 362 | + |
| 363 | + Napi::Object result = Napi::Object::New(env); |
| 364 | + result.Set("error", err); |
| 365 | + return result; |
| 366 | +} |
| 367 | + |
| 368 | +void runCompilerWrap(const Napi::CallbackInfo &info){ |
| 369 | + Napi::Env env = info.Env(); |
| 370 | + if( info.Length() < 2 || !info[0].IsObject() || !info[1].IsString()){ |
| 371 | + Napi::TypeError::New(env, "Expected arguments of type: runCompiler(compiler:CompilerHandle, path:String)").ThrowAsJavaScriptException(); |
| 372 | + return; |
| 373 | + } |
| 374 | + |
| 375 | + Napi::Object obj = info[0].As<Napi::Object>(); |
| 376 | + CompilerHandle* handle = Napi::ObjectWrap<CompilerHandle>::Unwrap(obj); |
| 377 | + |
| 378 | + lv::el::Compiler::Ptr compiler = handle->getInternalInstance(); |
| 379 | + |
| 380 | + Napi::String fileArg = info[1].As<Napi::String>(); |
| 381 | + |
| 382 | + Napi::Value err = env.Undefined(); |
| 383 | + Napi::Value res = env.Undefined(); |
| 384 | + |
| 385 | + try{ |
| 386 | + std::string file = fileArg.Utf8Value(); |
| 387 | + std::string scriptFile = Path::resolve(file); |
| 388 | + std::string pluginPath = Path::parent(scriptFile); |
| 389 | + |
| 390 | + if ( Module::existsIn(pluginPath) ){ |
| 391 | + Package::Ptr package(nullptr); |
| 392 | + if ( Module::fileExistsIn(pluginPath) ){ |
| 393 | + Module::Ptr module = Module::createFromPath(pluginPath); |
| 394 | + package = Package::createFromPath(module->package()); |
| 395 | + } else { |
| 396 | + std::string packagePath = Module::findPackageFrom(pluginPath); |
| 397 | + if ( !packagePath.empty() ){ |
| 398 | + Module::Ptr module = Module::createFromPath(pluginPath); |
| 399 | + package = Package::createFromPath(module->package()); |
| 400 | + } |
| 401 | + } |
| 402 | + |
| 403 | + if ( package ){ |
| 404 | + std::string current = package->path(); |
| 405 | + std::vector<std::string> importPaths; |
| 406 | + while ( Path::exists(current) ){ |
| 407 | + auto importPath = Path::join(current, compiler->importLocalPath() ); |
| 408 | + if ( Package::existsIn(current) && Path::exists( importPath ) ){ |
| 409 | + importPaths.push_back(importPath); |
| 410 | + } |
| 411 | + if ( Path::rootPath(current) == current ){ |
| 412 | + break; |
| 413 | + } |
| 414 | + current = Path::parent(current); |
| 415 | + } |
| 416 | + compiler->setPackageImportPaths(importPaths); |
| 417 | + } |
| 418 | + } |
| 419 | + |
| 420 | + lv::el::ElementsModule::Ptr elemMod = lv::el::Compiler::compile(compiler, scriptFile); |
| 421 | + lv::el::ModuleFile* mf = elemMod->moduleFileBypath(scriptFile); |
| 422 | + |
| 423 | + |
| 424 | + if ( mf ){ |
| 425 | + Napi::Object result = Napi::Object::New(env); |
| 426 | + Napi::Value file = Napi::String::New(env, Path::toUnixSeparator(mf->jsFilePath())); |
| 427 | + result.Set("file", file); |
| 428 | + res = result; |
| 429 | + } |
| 430 | + |
| 431 | + } catch ( lv::el::SyntaxException& e ){ |
| 432 | + Napi::Object ob = Napi::Object::New(env); |
| 433 | + populateSyntaxError(env, ob, &e); |
| 434 | + err = ob; |
| 435 | + } catch ( lv::el::TracePointException& e ){ |
| 436 | + Napi::Object ob = Napi::Object::New(env); |
| 437 | + populateError(env, ob, &e); |
| 438 | + err = ob; |
| 439 | + } catch ( lv::Exception& e ){ |
| 440 | + Napi::Object ob = Napi::Object::New(env); |
| 441 | + populateError(env, ob, &e); |
| 442 | + err = ob; |
| 443 | + } catch ( std::exception& e ){ |
| 444 | + Napi::Object ob = Napi::Object::New(env); |
| 445 | + populateErrorMessage(env, ob, &e); |
| 446 | + err = ob; |
| 447 | + } catch ( ... ){ |
| 448 | + Napi::Object ob = Napi::Object::New(env); |
| 449 | + populateErrorMessage(env, ob, nullptr); |
| 450 | + err = ob; |
| 451 | + } |
| 452 | + |
| 453 | + if ( info.Length() > 2 ){ |
| 454 | + Napi::Function cb = info[2].As<Napi::Function>(); |
| 455 | + cb.Call(env.Global(), {res, err}); |
| 456 | + } |
| 457 | + |
| 458 | +} |
| 459 | + |
295 | 460 | Napi::Object Init(Napi::Env env, Napi::Object exports) { |
| 461 | + CompilerHandle::Init(env, exports); |
| 462 | + |
296 | 463 | exports.Set("compile", Napi::Function::New(env, lv::compileWrap)); |
297 | 464 | exports.Set("compileModule", Napi::Function::New(env, lv::compileModuleWrap)); |
| 465 | + exports.Set("createCompiler", Napi::Function::New(env, lv::createCompilerWrap)); |
| 466 | + exports.Set("runCompiler", Napi::Function::New(env, lv::runCompilerWrap)); |
298 | 467 | return exports; |
299 | 468 | } |
300 | 469 |
|
|
0 commit comments