Skip to content

Commit 26feb22

Browse files
committed
Added package scope.
[CL] Added support for package scope (@scope/package_name) [CL] Added missing Identifier error location. [CL] Fixed async event listeners. test: Updated catch libary.
1 parent 55168b8 commit 26feb22

23 files changed

+352443
-225897
lines changed

lib/lvbase/src/package.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class PackagePrivate{
4444

4545
public:
4646
std::string name;
47+
std::string scope;
4748
std::string path;
4849
std::string filePath;
4950
std::string documentation;
@@ -120,8 +121,12 @@ Package::Ptr Package::createFromNode(const std::string& path, const std::string
120121
if ( !m.hasKey("name") || !m.hasKey("version") )
121122
return Package::Ptr(nullptr);
122123

124+
std::string nameScope = m["name"].asString();
125+
size_t pos = nameScope.find_last_of('.');
126+
std::string name = pos != std::string::npos ? nameScope.substr(pos + 1) : nameScope;
127+
std::string scope = pos != std::string::npos ? nameScope.substr(0, pos) : "";
123128

124-
Package::Ptr pt(new Package(path, filePath, m["name"].asString(), Version(m["version"].asString())));
129+
Package::Ptr pt(new Package(path, filePath, scope, name, Version(m["version"].asString())));
125130

126131
if ( m.hasKey("dependencies") ){
127132
MLNode::ObjectType dep = m["dependencies"].asObject();
@@ -205,6 +210,25 @@ const std::string &Package::name() const{
205210
return m_d->name;
206211
}
207212

213+
/** \brief Returns the package scope */
214+
const std::string &Package::scope() const{
215+
return m_d->scope;
216+
}
217+
218+
/** \brief Returns the package name with its scope */
219+
std::string Package::nameScope() const{
220+
return hasScope() ? m_d->scope + "." + m_d->name : m_d->name;
221+
}
222+
223+
/** \brief Returns the package name with its scope as a path */
224+
std::string Package::nameScopeAsPath() const{
225+
return hasScope() ? m_d->scope + "/" + m_d->name : m_d->name;
226+
}
227+
228+
bool Package::hasScope() const{
229+
return !m_d->scope.empty();
230+
}
231+
208232
/** \brief Returns the package path */
209233
const std::string &Package::path() const{
210234
return m_d->path;
@@ -312,12 +336,13 @@ std::vector<std::string> Package::findModules(const std::string &path){
312336
return result;
313337
}
314338

315-
Package::Package(const std::string &path, const std::string& filePath, const std::string &name, const Version &version)
339+
Package::Package(const std::string &path, const std::string& filePath, const std::string& scope, const std::string &name, const Version &version)
316340
: m_d(new PackagePrivate)
317341
{
318342
m_d->path = path;
319343
m_d->filePath = filePath;
320344
m_d->name = name;
345+
m_d->scope = scope;
321346
m_d->version = version;
322347
m_d->context = nullptr;
323348
}

lib/lvbase/src/package.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ class LV_BASE_EXPORT Package{
139139

140140
const std::string& name() const;
141141
const std::string& path() const;
142+
const std::string& scope() const;
143+
std::string nameScope() const;
144+
std::string nameScopeAsPath() const;
145+
bool hasScope() const;
142146
const std::string& filePath() const;
143147
const std::string& documentation() const;
144148
const std::string& release() const;
@@ -160,7 +164,7 @@ class LV_BASE_EXPORT Package{
160164
private:
161165
static std::vector<std::string> findModules(const std::string& path);
162166

163-
Package(const std::string& path, const std::string& filePath, const std::string& name, const Version& version);
167+
Package(const std::string& path, const std::string& filePath, const std::string& scope, const std::string& name, const Version& version);
164168

165169
PackagePrivate* m_d;
166170

lib/lvbase/src/packagegraph.cpp

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ PackageGraph::~PackageGraph(){
8181

8282
/** Loads package in the graph and makes necessary checks */
8383
void PackageGraph::loadPackage(const Package::Ptr &p, bool addLibraries){
84-
auto it = m_d->packages.find(p->name());
84+
auto it = m_d->packages.find(p->nameScope());
8585
if ( it == m_d->packages.end() ){
8686
p->assignContext(this);
8787

@@ -92,9 +92,9 @@ void PackageGraph::loadPackage(const Package::Ptr &p, bool addLibraries){
9292
}
9393
}
9494

95-
m_d->packages[p->name()] = p;
95+
m_d->packages[p->nameScope()] = p;
9696

97-
vlog("lvbase-packagegraph").v() << "Loaded package \'" + p->name() << "\' [" + p->version().toString() + "]";
97+
vlog("lvbase-packagegraph").v() << "Loaded package \'" + p->nameScope() << "\' [" + p->version().toString() + "]";
9898

9999
} else {
100100
Package::Ptr existingPackage = it->second;
@@ -104,17 +104,17 @@ void PackageGraph::loadPackage(const Package::Ptr &p, bool addLibraries){
104104
if ( newVersion.majorNumber() != oldVersion.majorNumber() ){
105105
THROW_EXCEPTION(
106106
lv::Exception,
107-
"Incompatible package versions for package \'" + p->name() + "\': " +
107+
"Incompatible package versions for package \'" + p->nameScope() + "\': " +
108108
oldVersion.toString() + " vs " + newVersion.toString(), 1);
109109
}
110110

111111
if ( newVersion > oldVersion ){
112112
vlog("lvbase-packagegraph").v() <<
113-
"Replaced package \'" << p->name() << "\' from [" << existingPackage->version().toString() << "] to [" <<
113+
"Replaced package \'" << p->nameScope() << "\' from [" << existingPackage->version().toString() << "] to [" <<
114114
p->version().toString() << "]";
115115

116116
p->assignContext(this);
117-
m_d->packages[p->name()] = p;
117+
m_d->packages[p->nameScope()] = p;
118118

119119
if ( addLibraries ){
120120
for ( auto it = p->libraries().begin(); it != p->libraries().end(); ++it ){
@@ -145,19 +145,19 @@ void PackageGraph::loadPackageWithDependencies(
145145

146146
/** */
147147
void PackageGraph::addDependency(const Package::Ptr &package, const Package::Ptr &dependsOn){
148-
auto packageit = m_d->packages.find(package->name());
149-
if ( packageit == m_d->packages.end() && package->name() != "." )
150-
THROW_EXCEPTION(lv::Exception, "Failed to find package:" + package->name(), 3);
148+
auto packageit = m_d->packages.find(package->nameScope());
149+
if ( packageit == m_d->packages.end() && package->nameScope() != "." )
150+
THROW_EXCEPTION(lv::Exception, "Failed to find package:" + package->nameScope(), 3);
151151
if ( package->contextOwner() != this )
152-
THROW_EXCEPTION(lv::Exception, "Package \'" + package->name() +"\' is not part of the current package graph.", 3);
152+
THROW_EXCEPTION(lv::Exception, "Package \'" + package->nameScope() +"\' is not part of the current package graph.", 3);
153153
if ( dependsOn->contextOwner() != this )
154-
THROW_EXCEPTION(lv::Exception, "Package \'" + dependsOn->name() +"\' is not part of the current package graph.", 3);
154+
THROW_EXCEPTION(lv::Exception, "Package \'" + dependsOn->nameScope() +"\' is not part of the current package graph.", 3);
155155

156-
auto dependsOnit = m_d->packages.find(dependsOn->name());
156+
auto dependsOnit = m_d->packages.find(dependsOn->nameScope());
157157
if ( dependsOnit == m_d->packages.end() ){
158-
auto internalsIt = internals().find(dependsOn->name());
158+
auto internalsIt = internals().find(dependsOn->nameScope());
159159
if ( internalsIt == internals().end() ){
160-
THROW_EXCEPTION(lv::Exception, "Failed to find package: " + dependsOn->name(), 2);
160+
THROW_EXCEPTION(lv::Exception, "Failed to find package: " + dependsOn->nameScope(), 2);
161161
} else {
162162
if ( !hasDependency(package, dependsOn) )
163163
package->context()->dependencies.push_back(dependsOn);
@@ -179,7 +179,7 @@ void PackageGraph::addDependency(const Package::Ptr &package, const Package::Ptr
179179
ss << " -> ";
180180
}
181181

182-
ss << n->name() << "[" << n->version().toString() << "]";
182+
ss << n->nameScope() << "[" << n->version().toString() << "]";
183183
}
184184

185185
for ( auto it = package->context()->dependencies.begin(); it != package->context()->dependencies.end(); ++it ){
@@ -203,9 +203,9 @@ void PackageGraph::addDependency(const Package::Ptr &package, const Package::Ptr
203203

204204
/** Check if there are cycles between packages, starting from the given packages */
205205
PackageGraph::CyclesResult<Package::Ptr> PackageGraph::checkCycles(const Package::Ptr &p){
206-
auto it = m_d->packages.find(p->name());
207-
if ( it == m_d->packages.end() && p->name() != ".")
208-
THROW_EXCEPTION(lv::Exception, "Failed to find package for cycles: " + p->name(), 2);
206+
auto it = m_d->packages.find(p->nameScope());
207+
if ( it == m_d->packages.end() && p->nameScope() != ".")
208+
THROW_EXCEPTION(lv::Exception, "Failed to find package for cycles: " + p->nameScope(), 2);
209209

210210
std::list<Package::Ptr> path;
211211
path.push_back(p);
@@ -384,7 +384,7 @@ std::string PackageGraph::toString() const{
384384

385385
ss << "Internals:" << std::endl;
386386
for ( auto it = internals().begin(); it != internals().end(); ++it ){
387-
ss << " " << it->second->name() << "[" << it->second->version().toString() << "]";
387+
ss << " " << it->second->nameScope() << "[" << it->second->version().toString() << "]";
388388
}
389389
ss << std::endl;
390390

@@ -412,7 +412,7 @@ std::string PackageGraph::toString() const{
412412
Package::Ptr PackageGraph::findPackage(Package::Reference ref) const{
413413
std::vector<std::string> paths = packageImportPaths();
414414
for ( auto it = paths.begin(); it != paths.end(); ++it ){
415-
std::string path = *it + "/" + ref.name.data();
415+
std::string path = *it + "/" + ref.name.replaceAll(".", "/").data();
416416
if ( Package::existsIn(path) ){
417417
Package::Ptr p = Package::createFromPath(path);
418418
if ( p->version().majorNumber() == ref.version.majorNumber() && p->version() > ref.version ){
@@ -446,9 +446,12 @@ Package::Ptr PackageGraph::findPackage(Package::Reference ref) const{
446446
Package::Ptr PackageGraph::findPackage(const std::string &packageName) const{
447447
Package::Ptr foundPackage(nullptr);
448448

449+
std::string packageNameScope = packageName;
450+
Utf8::replaceAll(packageNameScope, ".", "/");
451+
449452
std::vector<std::string> paths = packageImportPaths();
450453
for ( auto it = paths.begin(); it != paths.end(); ++it ){
451-
std::string path = *it + "/" + packageName;
454+
std::string path = *it + "/" + packageNameScope;
452455
if ( Package::existsIn(path) ){
453456
Package::Ptr p = Package::createFromPath(path);
454457

@@ -518,9 +521,9 @@ void PackageGraph::setPackageImportPaths(const std::vector<std::string> &paths){
518521
* \brief Adds internal package
519522
*/
520523
void PackageGraph::addInternalPackage(const Package::Ptr &package){
521-
auto it = internals().find(package->name());
524+
auto it = internals().find(package->nameScope());
522525
if ( it == internals().end() ){
523-
internals()[package->name()] = package;
526+
internals()[package->nameScope()] = package;
524527
if ( internalsContextOwner() ){
525528
package->assignContext(internalsContextOwner());
526529
}
@@ -580,12 +583,12 @@ void PackageGraph::loadRunningPackageAndModule(const Package::Ptr &package, cons
580583

581584
Utf8::replaceAll(uriFromPackage, "/", ".");
582585
Utf8::replaceAll(uriFromPackage, "\\", ".");
583-
module->context()->importId = uriFromPackage.empty() ? package->name() : package->name() + "." + uriFromPackage;
586+
module->context()->importId = uriFromPackage.empty() ? package->nameScope() : package->nameScope() + "." + uriFromPackage;
584587

585-
if ( package->name() != "." ){
586-
auto it = m_d->packages.find(package->name());
588+
if ( package->nameScope() != "." ){
589+
auto it = m_d->packages.find(package->nameScope());
587590
if ( it == m_d->packages.end() ){
588-
m_d->packages[package->name()] = package;
591+
m_d->packages[package->nameScope()] = package;
589592
} else if ( it->second->path() != package->path() ){
590593
addRunningPackage(package);
591594
}
@@ -611,14 +614,22 @@ Module::Ptr PackageGraph::loadModule(const std::vector<std::string> &importSegme
611614
THROW_EXCEPTION(lv::Exception, "Given import path is empty.", 5);
612615

613616
std::string packageName = importSegments[0];
617+
size_t modulePathIndex = 1;
618+
if ( packageName.size() && packageName[0] == '@' ){
619+
if ( importSegments.size() < 2 ){
620+
THROW_EXCEPTION(lv::Exception, Utf8("Cannot import package scope without package: %").format(packageName), lv::Exception::toCode("~Import"));
621+
}
622+
modulePathIndex = 2;
623+
packageName = importSegments[0] + "." + importSegments[1];
624+
}
614625

615626
Package::Ptr foundPackage = nullptr;
616627

617628
if ( requestingModule ){
618629
Package::Ptr requestingPackage = requestingModule->context() ? requestingModule->context()->packageUnwrapped() : nullptr;
619630

620631
if ( requestingPackage ){
621-
if ( requestingPackage->name() == packageName || (requestingPackage->name() == "." && packageName.empty() )){
632+
if ( requestingPackage->nameScope() == packageName || (requestingPackage->nameScope() == "." && packageName.empty() )){
622633
foundPackage = requestingPackage;
623634
}
624635
}
@@ -650,7 +661,7 @@ Module::Ptr PackageGraph::loadModule(const std::vector<std::string> &importSegme
650661
if ( !foundPackage->filePath().empty() ){ // some internal packages may not have the package file
651662
std::string modulePath = foundPackage->path();
652663
std::string importId = packageName;
653-
for ( size_t i = 1; i < importSegments.size(); ++i ){
664+
for ( size_t i = modulePathIndex; i < importSegments.size(); ++i ){
654665
modulePath += "/" + importSegments[i];
655666
importId += "." + importSegments[i];
656667
}
@@ -774,13 +785,13 @@ bool PackageGraph::hasDependency(const Module::Ptr &module, const Module::Ptr &d
774785

775786
std::string PackageGraph::toString(Package::Ptr package, const std::string &indent) const{
776787
std::stringstream ss;
777-
ss << indent << package->name() << "[" << package->version().toString() << "]" << std::endl;
788+
ss << indent << package->nameScope() << "[" << package->version().toString() << "]" << std::endl;
778789
return ss.str();
779790
}
780791

781792
std::string PackageGraph::toStringRecurse(Package::Ptr package, const std::string &indent) const{
782793
std::stringstream ss;
783-
ss << indent << package->name() << "[" << package->version().toString() << "]" << std::endl;
794+
ss << indent << package->nameScope() << "[" << package->version().toString() << "]" << std::endl;
784795
for ( auto it = package->context()->dependencies.begin(); it != package->context()->dependencies.end(); ++it ){
785796
ss << toStringRecurse(*it, indent + " ");
786797
}

lib/lvbase/src/sourcelocation.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ class LV_BASE_EXPORT SourcePoint{
2323
int column() const{ return m_column; }
2424
int offset() const{ return m_offset; }
2525

26-
2726
static SourcePoint createFromLine(int line);
2827

2928
private:

lib/lvbase/src/utf8.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,13 @@ Utf8 Utf8::toUpper() const{
263263
}
264264

265265
std::vector<Utf8> Utf8::split(const char *sep){
266+
if ( isEmpty() )
267+
return std::vector<Utf8>();
268+
269+
if ( strlen(sep) == 0 ){
270+
THROW_EXCEPTION(lv::Exception, "Utf8 split using an empty string argument.", lv::Exception::toCode("~String"));
271+
}
272+
266273
std::vector<Utf8> tokens;
267274
std::size_t start = 0, end = 0;
268275
while ((end = m_data->find(sep, start)) != std::string::npos) {

0 commit comments

Comments
 (0)