Browse Source

BindingGenerator: Move template specialization into GlobalFunctionAnalyzer; Improve XmlAnalyzers (#2751)

1vanK 5 years ago
parent
commit
c823a0a419

+ 9 - 6
Source/Tools/BindingGenerator/ASGlobalFunctionBinder.cpp

@@ -102,10 +102,10 @@ static vector<map<string, string>> GetSpecializations(const GlobalFunctionAnalyz
     return result;
 }
 
-static void BindGlobalFunction(const GlobalFunctionAnalyzer& functionAnalyzer, const map<string, string>& templateSpecialization = map<string, string>())
+static void BindGlobalFunction(const GlobalFunctionAnalyzer& functionAnalyzer)
 {
     string declParams = "";
-    vector<ParamAnalyzer> params = functionAnalyzer.GetParams(templateSpecialization);
+    vector<ParamAnalyzer> params = functionAnalyzer.GetParams();
     string outGlue;
 
     bool needWrapper = false;
@@ -139,7 +139,7 @@ static void BindGlobalFunction(const GlobalFunctionAnalyzer& functionAnalyzer, c
         convertedParams.push_back(conv);
     }
 
-    shared_ptr<FuncReturnTypeConv> retConv = CppFunctionReturnTypeToAS(functionAnalyzer.GetReturnType(templateSpecialization));
+    shared_ptr<FuncReturnTypeConv> retConv = CppFunctionReturnTypeToAS(functionAnalyzer.GetReturnType());
     if (!retConv->success_)
     {
         processedGlobalFunction.registration_ = "// " + GetLastErrorMessage();
@@ -164,7 +164,7 @@ static void BindGlobalFunction(const GlobalFunctionAnalyzer& functionAnalyzer, c
     if (needWrapper)
         processedGlobalFunction.registration_ += "asFUNCTION(" + GenerateWrapperName(functionAnalyzer) + "), asCALL_CDECL);";
     else
-        processedGlobalFunction.registration_ += Generate_asFUNCTIONPR(functionAnalyzer, templateSpecialization) + ", asCALL_CDECL);";
+        processedGlobalFunction.registration_ += Generate_asFUNCTIONPR(functionAnalyzer) + ", asCALL_CDECL);";
 
     Result::globalFunctions_.push_back(processedGlobalFunction);
 
@@ -182,7 +182,7 @@ static void BindGlobalFunction(const GlobalFunctionAnalyzer& functionAnalyzer, c
         if (needWrapper)
             processedGlobalFunction.registration_ += "asFUNCTION(" + GenerateWrapperName(functionAnalyzer) + "), asCALL_CDECL);";
         else
-            processedGlobalFunction.registration_ += Generate_asFUNCTIONPR(functionAnalyzer, templateSpecialization) + ", asCALL_CDECL);";
+            processedGlobalFunction.registration_ += Generate_asFUNCTIONPR(functionAnalyzer) + ", asCALL_CDECL);";
 
         Result::globalFunctions_.push_back(processedGlobalFunction);
     }
@@ -226,7 +226,10 @@ static void ProcessGlobalFunction(const GlobalFunctionAnalyzer& globalFunctionAn
     if (globalFunctionAnalyzer.IsTemplate())
     {
         for (const map<string, string>& specialization : specializations)
-            BindGlobalFunction(globalFunctionAnalyzer, specialization);
+        {
+            GlobalFunctionAnalyzer specializedAnalyzer(globalFunctionAnalyzer.GetMemberdef(), specialization);
+            BindGlobalFunction(specializedAnalyzer);
+        }
     }
     else
     {

+ 4 - 4
Source/Tools/BindingGenerator/ASUtils.cpp

@@ -67,7 +67,7 @@ shared_ptr<EnumAnalyzer> FindEnum(const string& name)
     NamespaceAnalyzer namespaceAnalyzer(SourceData::namespaceUrho3D_);
     vector<EnumAnalyzer> enumAnalyzers = namespaceAnalyzer.GetEnums();
 
-    for (EnumAnalyzer enumAnalyzer : enumAnalyzers)
+    for (const EnumAnalyzer& enumAnalyzer : enumAnalyzers)
     {
         if (enumAnalyzer.GetTypeName() == name)
             return make_shared<EnumAnalyzer>(enumAnalyzer);
@@ -731,11 +731,11 @@ string GenerateWrapper(const ClassFunctionAnalyzer& functionAnalyzer, bool templ
 
 // =================================================================================
 
-string Generate_asFUNCTIONPR(const GlobalFunctionAnalyzer& functionAnalyzer, const map<string, string>& templateSpecialization)
+string Generate_asFUNCTIONPR(const GlobalFunctionAnalyzer& functionAnalyzer)
 {
     string functionName = functionAnalyzer.GetName();
-    string cppParams = "(" + JoinParamsTypes(functionAnalyzer.GetMemberdef(), templateSpecialization) + ")";
-    string returnType = functionAnalyzer.GetReturnType(templateSpecialization).ToString();
+    string cppParams = "(" + JoinParamsTypes(functionAnalyzer.GetMemberdef(), functionAnalyzer.GetTemplateSpecialization()) + ")";
+    string returnType = functionAnalyzer.GetReturnType().ToString();
     return "asFUNCTIONPR(" + functionName + ", " + cppParams + ", " + returnType + ")";
 }
 

+ 1 - 1
Source/Tools/BindingGenerator/ASUtils.h

@@ -77,7 +77,7 @@ string GenerateWrapper(const GlobalFunctionAnalyzer& functionAnalyzer, vector<sh
 string GenerateWrapper(const ClassStaticFunctionAnalyzer& functionAnalyzer, vector<shared_ptr<FuncParamConv> >& convertedParams, shared_ptr<FuncReturnTypeConv> convertedReturn);
 string GenerateWrapper(const ClassFunctionAnalyzer& functionAnalyzer, bool templateVersion, vector<shared_ptr<FuncParamConv> >& convertedParams, shared_ptr<FuncReturnTypeConv> convertedReturn);
 
-string Generate_asFUNCTIONPR(const GlobalFunctionAnalyzer& functionAnalyzer, const map<string, string>& templateSpecialization = map<string, string>());
+string Generate_asFUNCTIONPR(const GlobalFunctionAnalyzer& functionAnalyzer);
 string Generate_asFUNCTIONPR(const ClassStaticFunctionAnalyzer& functionAnalyzer, const map<string, string>& templateSpecialization = map<string, string>());
 string Generate_asMETHODPR(const ClassFunctionAnalyzer& functionAnalyzer, bool templateVersion, const map<string, string>& templateSpecialization = map<string, string>());
 

+ 59 - 0
Source/Tools/BindingGenerator/Utils.cpp

@@ -168,6 +168,24 @@ vector<string> Split(const string& str, char delim)
     return result;
 }
 
+vector<string> Split(const string& str, const string& delim)
+{
+    vector<string> result;
+    size_t lastPos = 0;
+    size_t findPos = str.find(delim, lastPos);
+
+    while (findPos != string::npos)
+    {
+        result.push_back(str.substr(lastPos, findPos - lastPos));
+        lastPos = findPos + delim.length();
+        findPos = str.find(delim, lastPos);
+    }
+
+    result.push_back(str.substr(lastPos));
+
+    return result;
+}
+
 string CutStart(const string& str, const string& value)
 {
     if (!StartsWith(str, value))
@@ -199,3 +217,44 @@ string FirstCharToLower(const string& str)
 
     return result;
 }
+
+string Join(const vector<string>& values, const string& separator)
+{
+    string result;
+
+    for (const string& value : values)
+    {
+        if (!result.empty())
+            result += separator;
+
+        result += value;
+    }
+
+    return result;
+}
+
+string JoinNonEmpty(const vector<string>& strings, const string& separator)
+{
+    string result;
+
+    for (const string& str : strings)
+    {
+        if (str.empty())
+            continue;
+
+        if (!result.empty())
+            result += separator;
+
+        result += str;
+    }
+
+    return result;
+}
+
+string ToIdentifier(const string& str)
+{
+    string result = ReplaceAll(str, ", ", "_comma_");
+    result = ReplaceAll(result, "<", "_leftAngleBracket_");
+    result = ReplaceAll(result, ">", "_rightAngleBracket_");
+    return result;
+}

+ 6 - 0
Source/Tools/BindingGenerator/Utils.h

@@ -42,6 +42,8 @@ string RemoveAll(const string& src, const string& value);
 string ReplaceFirst(const string& src, const string& from, const string& to);
 string RemoveFirst(const string& src, const string& value);
 vector<string> Split(const string& str, char delim);
+vector<string> Split(const string& str, const string& delim);
+string Join(const vector<string>& values, const string& separator);
 bool Contains(const string& str, const string& substr);
 
 // Return all after last found substring
@@ -58,3 +60,7 @@ string FirstCharToLower(const string& str);
 
 string GetLastErrorMessage();
 void SetLastErrorMessage(const string& message);
+
+string JoinNonEmpty(const vector<string>& strings, const string& separator);
+
+string ToIdentifier(const string& str);

+ 42 - 33
Source/Tools/BindingGenerator/XmlAnalyzer.cpp

@@ -213,25 +213,6 @@ string ExtractArgsstring(xml_node memberdef)
     return argsstring.child_value();
 }
 
-vector<string> ExtractTemplateParams(xml_node memberdef)
-{
-    assert(IsMemberdef(memberdef));
-
-    vector<string> result;
-
-    xml_node templateparamlist = memberdef.child("templateparamlist");
-    for (xml_node param : templateparamlist.children("param"))
-    {
-        string type = param.child_value("type");
-        type = CutStart(type, "class ");
-        type = CutStart(type, "typename ");
-        
-        result.push_back(type);
-    }
-
-    return result;
-}
-
 string ExtractProt(xml_node memberdef)
 {
     assert(IsMemberdef(memberdef));
@@ -429,6 +410,25 @@ bool IsTemplate(xml_node node)
     return node.child("templateparamlist");
 }
 
+vector<string> ExtractTemplateParams(xml_node node)
+{
+    assert(IsMemberdef(node) || IsCompounddef(node));
+
+    vector<string> result;
+
+    xml_node templateparamlist = node.child("templateparamlist");
+    for (xml_node param : templateparamlist.children("param"))
+    {
+        string type = param.child_value("type");
+        type = CutStart(type, "class ");
+        type = CutStart(type, "typename ");
+
+        result.push_back(type);
+    }
+
+    return result;
+}
+
 // ============================================================================
 
 EnumAnalyzer::EnumAnalyzer(xml_node memberdef)
@@ -764,6 +764,22 @@ bool ClassAnalyzer::HasThisConstructor() const
     return false;
 }
 
+bool ClassAnalyzer::IsRefCounted() const
+{
+    if (GetClassName() == "RefCounted")
+        return true;
+
+    vector<ClassAnalyzer> baseClasses = GetAllBaseClasses();
+
+    for (const ClassAnalyzer& classAnalyzer : baseClasses)
+    {
+        if (classAnalyzer.GetClassName() == "RefCounted")
+            return true;
+    }
+
+    return false;
+}
+
 // ============================================================================
 
 ClassFunctionAnalyzer::ClassFunctionAnalyzer(ClassAnalyzer classAnalyzer, xml_node memberdef)
@@ -855,11 +871,6 @@ string GetFunctionLocation(xml_node memberdef)
     return result;
 }
 
-string ClassFunctionAnalyzer::GetLocation() const
-{
-    return GetFunctionLocation(memberdef_);
-}
-
 bool ClassFunctionAnalyzer::IsConst() const
 {
     string constAttr = memberdef_.attribute("const").value();
@@ -954,6 +965,9 @@ string ClassVariableAnalyzer::GetLocation() const
 
     result += " | File: " + GetHeaderFile();
 
+    if (!classAnalyzer_.usingLocation_.empty())
+        result = classAnalyzer_.usingLocation_ + " | " + result;
+
     return result;
 }
 
@@ -990,10 +1004,7 @@ vector<GlobalVariableAnalyzer> NamespaceAnalyzer::GetVariables()
     vector<GlobalVariableAnalyzer> result;
 
     for (xml_node memberdef : sectiondef.children("memberdef"))
-    {
-        GlobalVariableAnalyzer analyzer(memberdef);
-        result.push_back(analyzer);
-    }
+        result.push_back(GlobalVariableAnalyzer(memberdef));
 
     return result;
 }
@@ -1006,10 +1017,7 @@ vector<GlobalFunctionAnalyzer> NamespaceAnalyzer::GetFunctions()
     vector<GlobalFunctionAnalyzer> result;
 
     for (xml_node memberdef : sectiondef.children("memberdef"))
-    {
-        GlobalFunctionAnalyzer analyzer(memberdef);
-        result.push_back(analyzer);
-    }
+        result.push_back(GlobalFunctionAnalyzer(memberdef));
 
     return result;
 }
@@ -1025,8 +1033,9 @@ UsingAnalyzer::UsingAnalyzer(xml_node memberdef)
 
 // ============================================================================
 
-GlobalFunctionAnalyzer::GlobalFunctionAnalyzer(xml_node memberdef)
+GlobalFunctionAnalyzer::GlobalFunctionAnalyzer(xml_node memberdef, const map<string, string>& templateSpecialization)
     : memberdef_(memberdef)
+    , templateSpecialization_(templateSpecialization)
 {
     assert(IsMemberdef(memberdef));
     assert(ExtractKind(memberdef) == "function");

+ 17 - 12
Source/Tools/BindingGenerator/XmlAnalyzer.h

@@ -135,12 +135,6 @@ string ExtractDefinition(xml_node memberdef);
 //     <argsstring>...</argsstring>
 string ExtractArgsstring(xml_node memberdef);
 
-// <memberdef kind="function">
-//     <templateparamlist>
-//         <param>...</param>
-//         <param>...</param>
-vector<string> ExtractTemplateParams(xml_node memberdef);
-
 // <memberdef prot="...">
 string ExtractProt(xml_node memberdef);
 
@@ -196,6 +190,12 @@ string ExtractHeaderFile(xml_node node);
 //     <templateparamlist>
 bool IsTemplate(xml_node node);
 
+// <compounddef|memberdef>
+//     <templateparamlist>
+//         <param>...</param>
+//         <param>...</param>
+vector<string> ExtractTemplateParams(xml_node node);
+
 // <compounddef kind="namespace">
 //     <sectiondef kind="enum">
 //         <memberdef kind="enum">...</memberdef>
@@ -250,6 +250,8 @@ private:
     vector<xml_node> GetMemberdefs() const;
 
 public:
+    string usingLocation_;
+
     ClassAnalyzer(xml_node compounddef);
 
     string GetClassName() const;
@@ -263,7 +265,7 @@ public:
     bool ContainsFunction(const string& name) const;
     ClassFunctionAnalyzer GetFunction(const string& name) const;
     int NumFunctions(const string& name) const;
-    bool IsRefCounted() const { return ContainsFunction("AddRef") && ContainsFunction("ReleaseRef"); }
+    bool IsRefCounted() const;
     bool HasDestructor() const { return ContainsFunction("~" + GetClassName()); }
     bool HasThisConstructor() const;
     bool IsAbstract() const;
@@ -312,7 +314,7 @@ public:
     bool IsParentConstructor() const;
     bool IsThisDestructor() const { return GetName() == "~" + GetClassName(); }
     bool IsParentDestructor() const;
-    string GetLocation() const;
+    string GetLocation() const { return JoinNonEmpty({ classAnalyzer_.usingLocation_, GetFunctionLocation(memberdef_) }, " | "); }
     string GetHeaderFile() const { return ExtractHeaderFile(memberdef_); }
     TypeAnalyzer GetReturnType(const map<string, string>& templateSpecialization = map<string, string>()) const { return ExtractType(memberdef_, templateSpecialization); }
     bool CanBeGetProperty() const;
@@ -355,17 +357,20 @@ public:
 class GlobalFunctionAnalyzer
 {
     xml_node memberdef_;
+    map<string, string> templateSpecialization_;
 
 public:
-    GlobalFunctionAnalyzer(xml_node memberdef);
+    GlobalFunctionAnalyzer(xml_node memberdef, const map<string, string>& templateSpecialization = map<string, string>());
+
+    xml_node GetMemberdef() const { return memberdef_; }
+    const map<string, string>& GetTemplateSpecialization() const { return templateSpecialization_; }
 
     string GetName() const { return ExtractName(memberdef_); }
     string GetHeaderFile() const { return ExtractHeaderFile(memberdef_); }
     bool IsTemplate() const { return ::IsTemplate(memberdef_); }
     string GetComment() const { return ExtractComment(memberdef_); }
-    vector<ParamAnalyzer> GetParams(const map<string, string>& templateSpecialization = map<string, string>()) const { return ExtractParams(memberdef_, templateSpecialization); }
-    TypeAnalyzer GetReturnType(const map<string, string>& templateSpecialization = map<string, string>()) const { return ExtractType(memberdef_, templateSpecialization); }
-    xml_node GetMemberdef() const { return memberdef_; }
+    vector<ParamAnalyzer> GetParams() const { return ExtractParams(memberdef_, templateSpecialization_); }
+    TypeAnalyzer GetReturnType() const { return ExtractType(memberdef_, templateSpecialization_); }
     vector<string> GetTemplateParams() const { return ExtractTemplateParams(memberdef_); }
     string JoinParamsNames() const { return ::JoinParamsNames(memberdef_); }
     string JoinParamsTypes() const { return ::JoinParamsTypes(memberdef_); }