diff options
-rw-r--r-- | compilerplugins/clang/test/xmlimport.cxx | 36 | ||||
-rw-r--r-- | compilerplugins/clang/xmlimport.cxx | 152 | ||||
-rw-r--r-- | reportdesign/source/filter/xml/xmlfilter.cxx | 4 | ||||
-rw-r--r-- | sw/source/filter/xml/xmlfmt.cxx | 5 |
4 files changed, 145 insertions, 52 deletions
diff --git a/compilerplugins/clang/test/xmlimport.cxx b/compilerplugins/clang/test/xmlimport.cxx index 965d4936e41c..36230ffdb2d8 100644 --- a/compilerplugins/clang/test/xmlimport.cxx +++ b/compilerplugins/clang/test/xmlimport.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -12,6 +12,13 @@ // Cannot include this, makes clang crash //#include "xmloff/xmlimp.hxx" +#include <com/sun/star/uno/Reference.hxx> + +namespace com::sun::star::xml::sax +{ +class XAttributeList; +} + class SvXMLImportContext { public: @@ -20,6 +27,10 @@ public: virtual void createFastChildContext() {} virtual void startFastElement() {} virtual void endFastElement() {} + + virtual void StartElement(const css::uno::Reference<css::xml::sax::XAttributeList>&) {} + virtual void EndElement() {} + virtual void Characters(const OUString&) {} }; class Test1 : public SvXMLImportContext @@ -51,4 +62,27 @@ public: virtual void endFastElement() override; }; +class Test5 : public SvXMLImportContext +{ +public: + // expected-error@+1 {{overrides startElement, but looks like a fastparser context class, no constructor that takes slowparser args [loplugin:xmlimport]}} + virtual void + StartElement(const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList) override; + // expected-error@+1 {{overrides startElement, but looks like a fastparser context class, no constructor that takes slowparser args [loplugin:xmlimport]}} + virtual void EndElement() override; + // expected-error@+1 {{overrides startElement, but looks like a fastparser context class, no constructor that takes slowparser args [loplugin:xmlimport]}} + virtual void Characters(const OUString&) override; +}; + +// no warning expected +class Test6 : public SvXMLImportContext +{ +public: + Test6(sal_uInt16, const OUString&); + virtual void + StartElement(const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList) override; + virtual void EndElement() override; + virtual void Characters(const OUString&) override; +}; + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/xmlimport.cxx b/compilerplugins/clang/xmlimport.cxx index bdb41f616859..d6b1aa78e325 100644 --- a/compilerplugins/clang/xmlimport.cxx +++ b/compilerplugins/clang/xmlimport.cxx @@ -52,81 +52,141 @@ public: bool VisitCXXMethodDecl(const CXXMethodDecl*); }; -static bool containsStartFastElementMethod(const CXXRecordDecl* cxxRecordDecl, - bool& rbFoundImportContext) +static bool containsStartFastElementMethod(const CXXRecordDecl* cxxRecordDecl) { auto dc = loplugin::DeclCheck(cxxRecordDecl); - if (dc.Class("SvXMLImportContext")) - { - rbFoundImportContext = true; - return false; - } if (dc.Class("XFastContextHandler")) return false; for (auto it = cxxRecordDecl->method_begin(); it != cxxRecordDecl->method_end(); ++it) { auto i = *it; if (i->getIdentifier() && i->getName() == "startFastElement") - { - // i->dump(); return true; - } } return false; } + bool XmlImport::VisitCXXMethodDecl(const CXXMethodDecl* methodDecl) { auto beginLoc = compat::getBeginLoc(methodDecl); if (!beginLoc.isValid() || ignoreLocation(beginLoc)) return true; - auto cxxRecordDecl = methodDecl->getParent(); - if (!cxxRecordDecl || !cxxRecordDecl->getIdentifier()) - return true; - auto className = cxxRecordDecl->getName(); - if (className == "OOXMLFactory") // writerfilter - return true; - if (className == "SvXMLLegacyToFastDocHandler" || className == "ImportDocumentHandler" - || className == "ExportDocumentHandler") // reportdesign - return true; - if (className == "XMLEmbeddedObjectExportFilter" || className == "XMLBasicExportFilter" - || className == "XMLTransformerBase" || className == "SvXMLMetaExport") // xmloff - return true; if (!methodDecl->getIdentifier()) return true; - if (!(methodDecl->getName() == "createFastChildContext" || methodDecl->getName() == "characters" - || methodDecl->getName() == "endFastElement")) + + auto cxxRecordDecl = methodDecl->getParent(); + if (!cxxRecordDecl || !cxxRecordDecl->getIdentifier()) return true; + if (loplugin::DeclCheck(cxxRecordDecl).Class("SvXMLImportContext")) return true; - bool foundImportContext = false; - if (containsStartFastElementMethod(cxxRecordDecl, foundImportContext)) - return true; + if (methodDecl->getName() == "createFastChildContext" || methodDecl->getName() == "characters" + || methodDecl->getName() == "endFastElement") + { + auto className = cxxRecordDecl->getName(); + if (className == "OOXMLFactory") // writerfilter + return true; + if (className == "SvXMLLegacyToFastDocHandler" || className == "ImportDocumentHandler" + || className == "ExportDocumentHandler") // reportdesign + return true; + if (className == "XMLEmbeddedObjectExportFilter" || className == "XMLBasicExportFilter" + || className == "XMLTransformerBase" || className == "SvXMLMetaExport") // xmloff + return true; - bool foundStartFastElement = false; - CXXBasePaths aPaths; - cxxRecordDecl->lookupInBases( - [&](const CXXBaseSpecifier* Specifier, CXXBasePath & /*Path*/) -> bool { - if (!Specifier->getType().getTypePtr()) - return false; - const CXXRecordDecl* baseCXXRecordDecl = Specifier->getType()->getAsCXXRecordDecl(); - if (!baseCXXRecordDecl) + if (containsStartFastElementMethod(cxxRecordDecl)) + return true; + + bool foundStartFastElement = false; + bool foundImportContext = false; + + CXXBasePaths aPaths; + cxxRecordDecl->lookupInBases( + [&](const CXXBaseSpecifier* Specifier, CXXBasePath & /*Path*/) -> bool { + if (!Specifier->getType().getTypePtr()) + return false; + const CXXRecordDecl* baseCXXRecordDecl = Specifier->getType()->getAsCXXRecordDecl(); + if (!baseCXXRecordDecl) + return false; + if (baseCXXRecordDecl->isInvalidDecl()) + return false; + if (loplugin::DeclCheck(baseCXXRecordDecl).Class("SvXMLImportContext")) + foundImportContext |= true; + else + foundStartFastElement |= containsStartFastElementMethod(baseCXXRecordDecl); return false; - if (baseCXXRecordDecl->isInvalidDecl()) + }, + aPaths); + + if (foundImportContext && !foundStartFastElement) + report(DiagnosticsEngine::Warning, "must override startFastElement too", + compat::getBeginLoc(methodDecl)) + << methodDecl->getSourceRange(); + } + else if (methodDecl->getName() == "StartElement" || methodDecl->getName() == "EndElement" + || methodDecl->getName() == "Characters") + { + if (loplugin::DeclCheck(cxxRecordDecl).Class("SchXMLAxisContext")) + return true; + if (loplugin::DeclCheck(cxxRecordDecl).Class("SchXMLChartContext")) + return true; + if (loplugin::DeclCheck(cxxRecordDecl).Class("SchXMLParagraphContext")) + return true; + if (loplugin::DeclCheck(cxxRecordDecl).Class("SchXMLLegendContext")) + return true; + if (loplugin::DeclCheck(cxxRecordDecl).Class("SchXMLPropertyMappingContext")) + return true; + + bool foundImportContext = false; + CXXBasePaths aPaths; + cxxRecordDecl->lookupInBases( + [&](const CXXBaseSpecifier* Specifier, CXXBasePath & /*Path*/) -> bool { + if (!Specifier->getType().getTypePtr()) + return false; + const CXXRecordDecl* baseCXXRecordDecl = Specifier->getType()->getAsCXXRecordDecl(); + if (!baseCXXRecordDecl) + return false; + if (baseCXXRecordDecl->isInvalidDecl()) + return false; + if (loplugin::DeclCheck(baseCXXRecordDecl).Class("SvXMLImportContext")) + foundImportContext |= true; return false; - foundStartFastElement - |= containsStartFastElementMethod(baseCXXRecordDecl, foundImportContext); - return false; - }, - aPaths); + }, + aPaths); - if (foundStartFastElement || !foundImportContext) - return true; + if (!foundImportContext) + return true; + + bool foundConstructor = false; + for (auto it = cxxRecordDecl->ctor_begin(); it != cxxRecordDecl->ctor_end(); ++it) + { + const CXXConstructorDecl* ctor = *it; + bool foundInt16 = false; + for (auto paramIt = ctor->param_begin(); paramIt != ctor->param_end(); ++paramIt) + { + const ParmVarDecl* pvd = *paramIt; + auto tc = loplugin::TypeCheck(pvd->getType()); + if (tc.Typedef("sal_uInt16")) + foundInt16 = true; + else if (tc.LvalueReference().Const().Class("OUString") && foundInt16) + foundConstructor = true; + else + foundInt16 = false; + if (tc.LvalueReference().Const().Class("OUString") + && pvd->getName() == "rLocalName") + foundConstructor = true; + } + } + + if (!foundConstructor) + report(DiagnosticsEngine::Warning, + "overrides startElement, but looks like a fastparser context class, no " + "constructor that takes slowparser args", + compat::getBeginLoc(methodDecl)) + << methodDecl->getSourceRange(); + } - report(DiagnosticsEngine::Warning, "must override startFastElement too", - compat::getBeginLoc(methodDecl)) - << methodDecl->getSourceRange(); return true; } diff --git a/reportdesign/source/filter/xml/xmlfilter.cxx b/reportdesign/source/filter/xml/xmlfilter.cxx index e5d84148f61f..5c65664625f3 100644 --- a/reportdesign/source/filter/xml/xmlfilter.cxx +++ b/reportdesign/source/filter/xml/xmlfilter.cxx @@ -93,7 +93,7 @@ public: RptMLMasterStylesContext_Impl(const RptMLMasterStylesContext_Impl&) = delete; RptMLMasterStylesContext_Impl& operator=(const RptMLMasterStylesContext_Impl&) = delete; - virtual void EndElement() override; + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; }; } @@ -103,7 +103,7 @@ RptMLMasterStylesContext_Impl::RptMLMasterStylesContext_Impl( ORptFilter& rImpor { } -void RptMLMasterStylesContext_Impl::EndElement() +void RptMLMasterStylesContext_Impl::endFastElement(sal_Int32 ) { FinishStyles( true ); GetImport().FinishStyles(); diff --git a/sw/source/filter/xml/xmlfmt.cxx b/sw/source/filter/xml/xmlfmt.cxx index e1aebad2ed0b..446b5fd13aa3 100644 --- a/sw/source/filter/xml/xmlfmt.cxx +++ b/sw/source/filter/xml/xmlfmt.cxx @@ -738,14 +738,13 @@ protected: public: - SwXMLStylesContext_Impl( SwXMLImport& rImport, bool bAuto ); virtual bool InsertStyleFamily( XmlStyleFamily nFamily ) const override; - virtual void EndElement() override; + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; }; } @@ -929,7 +928,7 @@ OUString SwXMLStylesContext_Impl::GetServiceName( XmlStyleFamily nFamily ) const return SvXMLStylesContext::GetServiceName( nFamily ); } -void SwXMLStylesContext_Impl::EndElement() +void SwXMLStylesContext_Impl::endFastElement(sal_Int32 ) { GetSwImport().InsertStyles( IsAutomaticStyle() ); } |