Skip to content

Commit

Permalink
lvelements.compiler: Improved error reporting. Added error import tra…
Browse files Browse the repository at this point in the history
…cing.
  • Loading branch information
dinusv committed Oct 26, 2023
1 parent 96dbc08 commit 979c402
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 46 deletions.
53 changes: 36 additions & 17 deletions lib/lvbase/src/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,26 +86,31 @@ Module::Ptr Module::createFromPath(const std::string &path){
THROW_EXCEPTION(lv::Exception, Utf8("Cannot open file: %").format(path), 1);
}

instream.seekg(0, std::ios::end);
size_t size = static_cast<size_t>(instream.tellg());
std::string buffer(size, ' ');
instream.seekg(0);
instream.read(&buffer[0], static_cast<std::streamsize>(size));

MLNode m;
ml::fromJson(buffer, m);

return createFromNode(moduleDirPath, modulePath, m);
try{
instream.seekg(0, std::ios::end);
size_t size = static_cast<size_t>(instream.tellg());
std::string buffer(size, ' ');
instream.seekg(0);
instream.read(&buffer[0], static_cast<std::streamsize>(size));

MLNode m;
ml::fromJson(buffer, m);

return createFromNode(moduleDirPath, modulePath, m);
} catch ( lv::Exception& e ){
THROW_EXCEPTION(lv::Exception, Utf8("Error when parsing file %: %").format(modulePath, e.message()), lv::Exception::toCode("parse"));
} catch ( std::exception& e ){
THROW_EXCEPTION(lv::Exception, Utf8("Error when parsing file %: %").format(modulePath, e.what()), lv::Exception::toCode("parse"));
}
return nullptr;
}

/** Creates plugin from a given MLNode*/
Module::Ptr Module::createFromNode(const std::string &path, const std::string &filePath, const MLNode &m){

if ( !m.hasKey("name") || !m.hasKey("package") ){
THROW_EXCEPTION(lv::Exception, "Failed to read plugin file at: " + path + ". Plugin requries 'name' and 'package' info.", Exception::toCode("~Keys"));
}

std::string package = m["package"].asString();
std::string name = m.hasKey("name") ? m["name"].asString() : Path::name(path);
std::string package = m.hasKey("package") ? m["package"].asString() : Module::findPackageFrom(path);
if ( package.empty() || !Path::exists(package))
THROW_EXCEPTION(lv::Exception, Utf8("Package not found for module: \'%\'.").format(filePath), Exception::toCode("~Keys"));

if ( Path::isRelative(package) ){
package = Path::resolve(Path::join(path, package));
Expand All @@ -115,7 +120,7 @@ Module::Ptr Module::createFromNode(const std::string &path, const std::string &f
package = Path::join(package, Package::fileName);
}

Module::Ptr pt(new Module(path, filePath, m["name"].asString(), package));
Module::Ptr pt(new Module(path, filePath, name, package));

if ( m.hasKey("palettes") ){
MLNode::ObjectType pal = m["palettes"].asObject();
Expand Down Expand Up @@ -257,6 +262,20 @@ Module::Module(const std::string &path, const std::string &filePath, const std::
m_d->context = nullptr;
}

std::string Module::findPackageFrom(const std::string& path){
auto current = path;
while ( Path::exists(current) ){
if ( Package::existsIn(current) ){
return current;
}
if ( Path::rootPath(current) == current ){
return "";
}
current = Path::parent(current);
}
return "";
}

void Module::addPalette(const std::string &type, const std::string &path){
if ( context() ){
Utf8 extension = Path::suffix(path);
Expand Down
1 change: 1 addition & 0 deletions lib/lvbase/src/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class LV_BASE_EXPORT Module{
private:
Module(const std::string& path, const std::string& filePath, const std::string& name, const std::string& package);

static std::string findPackageFrom(const std::string& path);
void addPalette(const std::string& type, const std::string& path);

ModulePrivate* m_d;
Expand Down
26 changes: 17 additions & 9 deletions lib/lvbase/src/package.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,24 @@ Package::Ptr Package::createFromPath(const std::string &path){
THROW_EXCEPTION(lv::Exception, Utf8("Cannot open package file: %. The file might not exist or the path might be wrong.").format(path), 1);
}

instream.seekg(0, std::ios::end);
size_t size = static_cast<size_t>(instream.tellg());
std::string buffer(size, ' ');
instream.seekg(0);
instream.read(&buffer[0], size);

MLNode m;
ml::fromJson(buffer, m);
try{
instream.seekg(0, std::ios::end);
size_t size = static_cast<size_t>(instream.tellg());
std::string buffer(size, ' ');
instream.seekg(0);
instream.read(&buffer[0], size);

MLNode m;
ml::fromJson(buffer, m);
return createFromNode(packageDirPath, packagePath, m);

} catch ( lv::Exception& e ){
THROW_EXCEPTION(lv::Exception, Utf8("Error when parsing file %: %").format(packagePath, e.message()), lv::Exception::toCode("parse"));
} catch ( std::exception& e ){
THROW_EXCEPTION(lv::Exception, Utf8("Error when parsing file %: %").format(packagePath, e.what()), lv::Exception::toCode("parse"));
}

return createFromNode(packageDirPath, packagePath, m);
return nullptr;
}

/** This function actually creates the path pointer that is returned to the above function */
Expand Down
2 changes: 1 addition & 1 deletion lib/lvbase/src/packagegraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ Module::Ptr PackageGraph::loadModule(const std::vector<std::string> &importSegme
}

if ( !Module::existsIn(modulePath) )
THROW_EXCEPTION(lv::Exception, Utf8("\'live.module.json\' file has not been found in \'%\'").format(modulePath), 7);
THROW_EXCEPTION(lv::Exception, Utf8("\'live.module.json\' file has not been found in \'%\'").format(modulePath), Exception::toCode("~module"));

Module::Ptr module = Module::createFromPath(modulePath);
module->assignContext(this);
Expand Down
16 changes: 10 additions & 6 deletions lib/lvelements/compiler/src/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,12 +356,16 @@ std::vector<std::shared_ptr<ElementsModule> > Compiler::compilePackage(Compiler:
std::shared_ptr<ElementsModule> Compiler::compileImportedModule(Compiler::Ptr compiler, const std::string &importKey, const Module::Ptr& requestingModule, Engine *engine){
auto foundEp = compiler->m_d->loadedModules.find(importKey);
if ( foundEp == compiler->m_d->loadedModules.end() ){
Module::Ptr module = compiler->m_d->packageGraph->loadModule(importKey, requestingModule);
if ( module ){
auto ep = engine ? ElementsModule::create(module , compiler, engine) : ElementsModule::create(module , compiler);
compiler->m_d->loadedModules[importKey] = ep;
compiler->m_d->loadedModulesByPath[ep->module()->path()] = ep;
return ep;
try{
Module::Ptr module = compiler->m_d->packageGraph->loadModule(importKey, requestingModule);
if ( module ){
auto ep = engine ? ElementsModule::create(module , compiler, engine) : ElementsModule::create(module , compiler);
compiler->m_d->loadedModules[importKey] = ep;
compiler->m_d->loadedModulesByPath[ep->module()->path()] = ep;
return ep;
}
} catch ( lv::Exception& e ){
THROW_EXCEPTION(lv::Exception, e.message(), lv::Exception::toCode("Import"));
}
} else {
return foundEp->second;
Expand Down
41 changes: 29 additions & 12 deletions lib/lvelements/compiler/src/elementsmodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,33 +136,50 @@ ModuleFile *ElementsModule::addModuleFile(ElementsModule::Ptr &epl, const std::s
epl->m_d->exports.insert(std::make_pair(exp.name, exp));
}

std::string currentUriName = epl->module()->context()->importId.data() + "." + name;

auto mfImports = mf->imports();
for ( auto it = mfImports.begin(); it != mfImports.end(); ++it ){

ModuleFile::Import& imp = *it;

if ( imp.isRelative ){
if ( epl->module()->context()->package == nullptr ){
THROW_EXCEPTION(lv::Exception, "Cannot import relative path withouth package: " + imp.uri, Exception::toCode("~Import"));
THROW_EXCEPTION(lv::Exception, Utf8("Cannot import relative path withouth package: \'%\' in \'%\'").format(imp.uri, currentUriName), Exception::toCode("~Import"));
}
if ( epl->module()->context()->package->name() == "." ){
THROW_EXCEPTION(lv::Exception, "Cannot import relative path withouth package: " + imp.uri, Exception::toCode("~Import"));
THROW_EXCEPTION(lv::Exception, Utf8("Cannot import relative path withouth package: \'%\' in \'%\'").format(imp.uri, currentUriName), Exception::toCode("~Import"));
}

std::string importUri = epl->module()->context()->package->name() + (imp.uri == "." ? "" : imp.uri);

ElementsModule::Ptr ep = Compiler::compileImportedModule(epl->m_d->compiler, importUri, epl->module(), epl->engine());
if ( !ep ){
THROW_EXCEPTION(lv::Exception, "Failed to find module: " + imp.uri, Exception::toCode("~Import"));
try{
ElementsModule::Ptr ep = Compiler::compileImportedModule(epl->m_d->compiler, importUri, epl->module(), epl->engine());
if ( !ep ){
THROW_EXCEPTION(lv::Exception, Utf8("Failed to find module \'%\' imported in \'%\'").format(imp.uri, currentUriName), Exception::toCode("~Import"));
}
mf->resolveImport(imp.uri, ep);

} catch ( lv::Exception& e ){
if ( e.code() == lv::Exception::toCode("import") )
THROW_EXCEPTION(lv::Exception, Utf8("%\n - Imported \'%\' from \'%\'").format(e.message(), importUri, currentUriName), e.code());
else
throw e;
}

mf->resolveImport(imp.uri, ep);

} else {
ElementsModule::Ptr ep = Compiler::compileImportedModule(epl->m_d->compiler, it->uri, epl->module(), epl->engine());
if ( !ep ){
THROW_EXCEPTION(lv::Exception, "Failed to find module: " + imp.uri, Exception::toCode("~Import"));
try{
ElementsModule::Ptr ep = Compiler::compileImportedModule(epl->m_d->compiler, it->uri, epl->module(), epl->engine());
if ( !ep ){
THROW_EXCEPTION(lv::Exception, Utf8("Failed to find module \'%\' imported in \'%\'").format(imp.uri, currentUriName), Exception::toCode("~Import"));
}
mf->resolveImport(imp.uri, ep);
} catch ( lv::Exception& e ){
if ( e.code() == lv::Exception::toCode("import") )
THROW_EXCEPTION(lv::Exception, Utf8("%\n - Imported \'%\' from \'%\'").format(e.message(), imp.uri, currentUriName), e.code());
else
throw e;
}
mf->resolveImport(imp.uri, ep);
}
}
return mf;
Expand Down Expand Up @@ -208,7 +225,7 @@ void ElementsModule::compile(){
auto mfImports = mf->imports();
for ( auto mit = mfImports.begin(); mit != mfImports.end(); ++mit ){
if ( mit->module == nullptr ){
THROW_EXCEPTION(lv::Exception, "Import not resolved: " + mit->uri, lv::Exception::toCode("~Import"));
THROW_EXCEPTION(lv::Exception, Utf8("Import not resolved \'%\' when compiling \'%\'").format(mit->uri, mf->filePath()), lv::Exception::toCode("~Import"));
}
mit->module->compile();
}
Expand Down
1 change: 0 additions & 1 deletion lib/lvelements/compiler/src/elementsmodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ class LV_ELEMENTS_COMPILER_EXPORT ElementsModule{
ElementsModule(Module::Ptr module, Compiler::Ptr compiler, Engine* engine);

ElementsModulePrivate* m_d;

};

}} // namespace lv, el
Expand Down

0 comments on commit 979c402

Please sign in to comment.