From: Francesco Montorsi Date: Mon, 24 Mar 2008 18:44:46 +0000 (+0000) Subject: add pure virtual function parsing; give more informative warnings; fix the initial... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/a7be99c8034b3a1fc9b2caf23cdae09eb738dff9?ds=inline add pure virtual function parsing; give more informative warnings; fix the initial line to delete when in modify mode git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@52769 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/utils/ifacecheck/src/ifacecheck.cpp b/utils/ifacecheck/src/ifacecheck.cpp index b96f5ed60c..3a6a2bbec8 100644 --- a/utils/ifacecheck/src/ifacecheck.cpp +++ b/utils/ifacecheck/src/ifacecheck.cpp @@ -195,27 +195,20 @@ int IfaceCheckApp::CompareClasses(const wxClass* iface, const wxClassPtrArray& a searchedclasses += "/" + api[j]->GetName(); searchedclasses.Remove(0, 1); - // shorten the name of the header so the log file is more readable wxString header = iface->GetHeader().AfterLast('/'); for (unsigned int i=0; iGetMethodCount(); i++) { const wxMethod& m = iface->GetMethod(i); - const wxString& tofind = m.GetAsString(); int matches = 0; // search in the methods of the api classes provided for (unsigned int j=0; jFindMethod(m); - if (real) { - - // there is a matching prototype! It's ok! - //LogMessage("the doxygen method '%s' has a match in the real interface of '%s'!", - // tofind, api[j]->GetName()); - matches++; - } + if (real) + matches++; // there is a real matching prototype! It's ok! } if (matches == 0) @@ -232,33 +225,54 @@ int IfaceCheckApp::CompareClasses(const wxClass* iface, const wxClassPtrArray& a WX_APPEND_ARRAY(overloads, results); } - if (overloads.GetCount()>1) + if (overloads.GetCount()==0) { - // TODO: decide which of these overloads is the most "similar" to m - // and eventually modify it - LogWarning("%s: there are %d overloads of method '%s' in the classes '%s' " - "all with different signatures; manual fix is required", - header, overloads.GetCount(), tofind, searchedclasses); + LogMessage("%s: real '%s' class has no method '%s'", + header, searchedclasses, m.GetAsString()); + // we've found no overloads } - else if (overloads.GetCount() == 1) + else { - wxString tmp; - if (m_modify) tmp = "; fixing it..."; - - LogWarning("%s: the method '%s' of classes '%s' has a different signature%s", - header, tofind, searchedclasses, tmp); + // first, output a warning + wxString warning = header; + if (overloads.GetCount()>1) + warning += wxString::Format(": in the real headers there are %d overloads of '%s' for " + "'%s' all with different signatures:\n", + overloads.GetCount(), m.GetName(), searchedclasses); + else + warning += wxString::Format(": in the real headers there is a method '%s' for '%s'" + " but has different signature:\n", + m.GetName(), searchedclasses); + + warning += "\tdoxy header: " + m.GetAsString(); + for (unsigned int j=0; jGetAsString(); + + wxPrint(warning + "\n"); count++; - // try to modify it! - if (m_modify) - FixMethod(iface->GetHeader(), &m, overloads[0]); - } - else - { - LogMessage("%s: real '%s' class has no method '%s'", - header, searchedclasses, tofind); - count++; // count this type of warnings + if (overloads.GetCount()>1) + { + // TODO: decide which of these overloads is the most "similar" to m + // and eventually modify it + if (m_modify) + wxPrint("\tmanual fix is required\n"); + } + else + { + wxASSERT(overloads.GetCount() == 1); + + if (m_modify) + { + wxPrint("\tfixing it...\n"); + + // try to modify it! + FixMethod(iface->GetHeader(), &m, overloads[0]); + } + } } + + count++; } } @@ -283,11 +297,17 @@ void IfaceCheckApp::FixMethod(const wxString& header, const wxMethod* iface, con return; } + if (!file.GetLine(end).Contains(iface->GetName())) { + LogWarning("invalid location info for method '%s': %d.", + iface->GetAsString(), iface->GetLocation()); + return; + } + // find the start point of this prototype declaration: - int start = end; + int start = end-1; while (start > 0 && !file.GetLine(start).Contains(";") && - !file.GetLine(start).Contains("*/")) + !file.GetLine(start).Contains("*/")) start--; if (start <= 0) @@ -297,6 +317,10 @@ void IfaceCheckApp::FixMethod(const wxString& header, const wxMethod* iface, con return; } + // start-th line contains either the declaration of another prototype + // or the closing tag */ of a doxygen comment; start one line below + start++; + // remove the old prototype for (int i=start; i<=end; i++) file.RemoveLine(start); // remove (end-start)-nth times the start-th line diff --git a/utils/ifacecheck/src/xmlparser.cpp b/utils/ifacecheck/src/xmlparser.cpp index 78a12e8196..c8954f49fb 100644 --- a/utils/ifacecheck/src/xmlparser.cpp +++ b/utils/ifacecheck/src/xmlparser.cpp @@ -49,10 +49,30 @@ wxType wxEmptyType; void wxType::SetFromString(const wxString& t) { - m_strType = t.Strip(wxString::both); + /* + TODO: optimize the following code writing a single function + which works at char-level and does everything in a single pass + */ + + m_strType = t; // [] is the same as * for gccxml m_strType.Replace("[]", "*"); + m_strType.Replace("long int", "long"); // in wx typically we never write "long int", just "long" + + // make sure the * and & operator always use the same spacing rules + // (to make sure GetAsString() output is always consistent) + m_strType.Replace("*", "* "); + m_strType.Replace("&", "& "); + m_strType.Replace(" *", "*"); + m_strType.Replace(" &", "&"); + + while (m_strType.Contains(" ")) + m_strType.Replace(" ", " "); // do it once again + + m_strType.Replace(" ,", ","); + + m_strType = m_strType.Strip(wxString::both); } bool wxType::IsOk() const @@ -106,7 +126,7 @@ bool wxMethod::IsOk() const return false; // a function can't be both const and static or virtual and static! - if ((m_bConst && m_bStatic) || (m_bVirtual && m_bStatic)) { + if ((m_bConst && m_bStatic) || ((m_bVirtual || m_bPureVirtual) && m_bStatic)) { LogError("'%s' method can't be both const/static or virtual/static", m_strName); return false; } @@ -149,6 +169,7 @@ bool wxMethod::operator==(const wxMethod& m) const IsConst() != m.IsConst() || IsStatic() != m.IsStatic() || IsVirtual() != m.IsVirtual() || + IsPureVirtual() != m.IsPureVirtual() || IsDeprecated() != m.IsDeprecated()) return false; @@ -189,8 +210,10 @@ wxString wxMethod::GetAsString() const ret += " const"; if (m_bStatic) ret = "static " + ret; - if (m_bVirtual) + if (m_bVirtual || m_bPureVirtual) ret = "virtual " + ret; + if (m_bPureVirtual) + ret = ret + " = 0"; // in doxygen headers we don't need wxDEPRECATED: //if (m_bDeprecated) @@ -213,6 +236,8 @@ void wxMethod::Dump(wxTextOutputStream& stream) const stream << " STATIC"; if (IsVirtual()) stream << " VIRTUAL"; + if (IsPureVirtual()) + stream << " PURE-VIRTUAL"; if (IsDeprecated()) stream << " DEPRECATED"; @@ -825,6 +850,7 @@ bool wxXmlGccInterface::ParseMethod(const wxXmlNode *p, m.SetConst(p->GetAttribute("const") == "1"); m.SetStatic(p->GetAttribute("static") == "1"); m.SetVirtual(p->GetAttribute("virtual") == "1"); + m.SetPureVirtual(p->GetAttribute("pure_virtual") == "1"); m.SetDeprecated(p->GetAttribute("attributes") == "deprecated"); if (!m.IsOk()) { @@ -1110,6 +1136,7 @@ bool wxXmlDoxygenInterface::ParseMethod(const wxXmlNode* p, wxMethod& m, wxStrin m.SetConst(p->GetAttribute("const")=="yes"); m.SetStatic(p->GetAttribute("static")=="yes"); m.SetVirtual(p->GetAttribute("virt")=="virtual"); + m.SetPureVirtual(p->GetAttribute("virt")=="pure-virtual"); if (!m.IsOk()) { LogError("The prototype '%s' is not valid!", m.GetAsString()); diff --git a/utils/ifacecheck/src/xmlparser.h b/utils/ifacecheck/src/xmlparser.h index 68f183fd3b..cac59de9e8 100644 --- a/utils/ifacecheck/src/xmlparser.h +++ b/utils/ifacecheck/src/xmlparser.h @@ -71,7 +71,7 @@ class wxMethod { public: wxMethod() - { m_bConst=m_bVirtual=m_bStatic=m_bDeprecated=false; m_nLine=-1; } + { m_bConst=m_bVirtual=m_bPureVirtual=m_bStatic=m_bDeprecated=false; m_nLine=-1; } wxMethod(const wxType& rettype, const wxString& name, const wxTypeArray& arguments, const wxArrayString& defaults, @@ -105,6 +105,8 @@ public: // getters { return m_bStatic; } bool IsVirtual() const { return m_bVirtual; } + bool IsPureVirtual() const + { return m_bPureVirtual; } bool IsOk() const; bool IsCtor() const @@ -129,6 +131,8 @@ public: // setters { m_bStatic=c; } void SetVirtual(bool c = true) { m_bVirtual=c; } + void SetPureVirtual(bool c = true) + { m_bPureVirtual=c; } void SetDeprecated(bool c = true) { m_bDeprecated=c; } void SetLocation(int lineNumber) @@ -150,6 +154,7 @@ protected: bool m_bConst; bool m_bStatic; bool m_bVirtual; + bool m_bPureVirtual; bool m_bDeprecated; int m_nLine; };