The following script produces a failed assertion, because double namespaces (like namespace Foo::Bar
) aren't properly scoped in script builder: (they are added, but not removed properly)
namespace Foo::Bar {
int a = 5;
}
namespace Thing {
[Setting]
int b = 10;
}
I made a quick patch that fixes the problem, though I'm not sure this is how you would like it to be implemented (and it has not been battle-tested yet). Note that the diff is on an already modified version of scriptbuilder so the line numbers are gonna be off. You may just not wanna use this diff at all 😅
--- a/scriptbuilder.cpp
+++ b/scriptbuilder.cpp
@@ -396,6 +396,7 @@ int CScriptBuilder::ProcessScriptSection(const char *script, unsigned int length
if( token == "namespace" )
{
// Get the scope after "namespace". It can be composed of multiple nested namespaces, e.g. A::B::C
+ int n = 0;
do
{
do
@@ -409,8 +410,10 @@ int CScriptBuilder::ProcessScriptSection(const char *script, unsigned int length
if (currentNamespace != "")
currentNamespace += "::";
currentNamespace += modifiedScript.substr(pos, len);
+ n++;
}
} while (t == asTC_IDENTIFIER || (t == asTC_KEYWORD && modifiedScript.substr(pos, len) == "::"));
+ currentNamespaceStack.push_back(n);
// Search until first { is encountered
while( pos < modifiedScript.length() )
@@ -434,14 +437,19 @@ int CScriptBuilder::ProcessScriptSection(const char *script, unsigned int length
// Check if end of namespace
if( currentNamespace != "" && token == "}" )
{
- size_t found = currentNamespace.rfind( "::" );
- if( found != string::npos )
- {
- currentNamespace.erase( found );
- }
- else
- {
- currentNamespace = "";
+ assert( currentNamespaceStack.size() > 0 );
+ int n = currentNamespaceStack[currentNamespaceStack.size()];
+ currentNamespaceStack.pop_back();
+ while (n-- > 0) {
+ size_t found = currentNamespace.rfind( "::" );
+ if( found != string::npos )
+ {
+ currentNamespace.erase( found );
+ }
+ else
+ {
+ currentNamespace = "";
+ }
}
pos += len;
continue;
--- a/scriptbuilder.h
+++ b/scriptbuilder.h
@@ -181,6 +181,7 @@ protected:
std::vector<SMetadataDecl> foundDeclarations;
std::string currentClass;
std::string currentNamespace;
+ std::vector<int> currentNamespaceStack;
// Storage of metadata for global declarations
std::map<int, std::vector<std::string>> typeMetadataMap;