office-gobmx/compilerplugins/clang/store/stylepolice.cxx
Stephan Bergmann 9ad252b2e7 Drop o3tl::optional wrapper
...now that macOS builds are guaranteed to have std::optional since
358146bbbd "Bump macOS build baseline to
Xcode 11.3 and macOS 10.14.4".

The change is done mostly mechanically with

> for i in $(git grep -Fl optional); do
>  sed -i -e 's:<o3tl/optional\.hxx>\|\"o3tl/optional\.hxx\":<optional>:' \
>   -e 's/\<o3tl::optional\>/std::optional/g' \
>   -e 's/\<o3tl::make_optional\>/std::make_optional/g' "$i"
> done
> for i in $(git grep -Flw o3tl::nullopt); do
>  sed -i -e 's/\<o3tl::nullopt\>/std::nullopt/g' "$i"
> done

(though that causes some of the resulting

  #include <optional>

to appear at different places relative to other includes than if they had been
added manually), plus a few manual modifications:

* adapt bin/find-unneeded-includes
* adapt desktop/IwyuFilter_desktop.yaml
* remove include/o3tl/optional.hxx
* quote resulting "<"/">" as "&lt;"/"&gt;" in officecfg/registry/cppheader.xsl
* and then solenv/clang-format/reformat-formatted-files

Change-Id: I68833d9f7945e57aa2bc703349cbc5a56b342273
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89165
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2020-02-21 14:50:28 +01:00

196 lines
7.7 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <memory>
#include <regex>
#include <string>
#include <set>
#include "plugin.hxx"
// Check for some basic naming mismatches which make the code harder to read
//
// This plugin is deliberately fairly lax, and only targets the most egregeriously faulty code,
// since we have a broad range of styles in our code and we don't want to generate unnecessary
// churn.
namespace {
class StylePolice :
public loplugin::FilteringPlugin<StylePolice>
{
public:
explicit StylePolice(InstantiationData const & data): FilteringPlugin(data) {}
virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
bool VisitVarDecl(const VarDecl *);
private:
StringRef getFilename(SourceLocation loc);
};
StringRef StylePolice::getFilename(SourceLocation loc)
{
SourceLocation spellingLocation = compiler.getSourceManager().getSpellingLoc(loc);
StringRef name { getFilenameOfLocation(spellingLocation) };
return name;
}
bool startswith(const std::string& rStr, const char* pSubStr) {
return rStr.compare(0, strlen(pSubStr), pSubStr) == 0;
}
bool isUpperLetter(char c) {
return c >= 'A' && c <= 'Z';
}
bool isLowerLetter(char c) {
return c >= 'a' && c <= 'z';
}
bool isIdentifierLetter(char c) {
return isUpperLetter(c) || isLowerLetter(c);
}
bool matchPointerVar(const std::string& s) {
return s.size() > 2 && s[0] == 'p' && isUpperLetter(s[1]);
}
bool matchRefCountedPointerVar(const std::string& s) {
return s.size() > 2 && s[0] == 'x' && isUpperLetter(s[1]);
}
bool matchMember(const std::string& s) {
return s.size() > 3 && s[0] == 'm'
&& ( ( strchr("abnprsx", s[1]) && isUpperLetter(s[2]) )
|| ( s[1] == '_' && isIdentifierLetter(s[2]) ) );
}
bool StylePolice::VisitVarDecl(const VarDecl * varDecl)
{
if (ignoreLocation(varDecl)) {
return true;
}
StringRef aFileName = getFilename(varDecl->getLocStart());
std::string name = varDecl->getName();
if (!varDecl->isLocalVarDecl()) {
return true;
}
if (matchMember(name))
{
// these names appear to be taken from some scientific paper
if (aFileName == SRCDIR "/scaddins/source/analysis/bessel.cxx" ) {
}
// lots of places where we are storing a "method id" here
else if (aFileName.startswith(SRCDIR "/connectivity/source/drivers/jdbc") && name.compare(0,3,"mID") == 0) {
}
else {
report(
DiagnosticsEngine::Warning,
"this local variable follows our member field naming convention, which is confusing",
varDecl->getLocation())
<< varDecl->getType() << varDecl->getSourceRange();
}
}
QualType qt = varDecl->getType().getDesugaredType(compiler.getASTContext()).getCanonicalType();
qt = qt.getNonReferenceType();
std::string typeName = qt.getAsString();
if (startswith(typeName, "const "))
typeName = typeName.substr(6);
if (startswith(typeName, "class "))
typeName = typeName.substr(6);
if (startswith(typeName, "struct "))
typeName = typeName.substr(7);
std::string aOriginalTypeName = varDecl->getType().getAsString();
if (startswith(aOriginalTypeName, "const "))
aOriginalTypeName = aOriginalTypeName.substr(6);
if (!qt->isPointerType() && !qt->isArrayType() && !qt->isFunctionPointerType() && !qt->isMemberPointerType()
&& matchPointerVar(name)
&& !startswith(typeName, "boost::intrusive_ptr")
&& !startswith(typeName, "std::optional")
&& !startswith(typeName, "boost::shared_ptr")
&& !startswith(typeName, "com::sun::star::uno::Reference")
&& !startswith(typeName, "cppu::OInterfaceIteratorHelper")
&& !startswith(typeName, "formula::FormulaCompiler::CurrentFactor")
&& aOriginalTypeName != "GLXPixmap"
&& !startswith(typeName, "rtl::Reference")
&& !startswith(typeName, "ScopedVclPtr")
&& typeName.find("::mem_fun") == std::string::npos
&& typeName.find("shared_ptr") == std::string::npos
&& typeName.find("unique_ptr") == std::string::npos
&& typeName.find("::weak_ptr") == std::string::npos
&& !startswith(typeName, "_LOKDocViewPrivate")
&& !startswith(typeName, "sw::UnoCursorPointer")
&& !startswith(typeName, "tools::SvRef")
&& !startswith(typeName, "VclPtr")
&& !startswith(typeName, "vcl::ScopedBitmapAccess")
// lots of the code seems to regard iterator objects as being "pointer-like"
&& typeName.find("iterator<") == std::string::npos
&& typeName.find("iter<") == std::string::npos
// libc++ std::__1::__wrap_iter<...>
&& aOriginalTypeName != "sal_IntPtr" )
{
if (aFileName.startswith(SRCDIR "/bridges/") ) {
} else if (aFileName.startswith(SRCDIR "/vcl/source/fontsubset/sft.cxx") ) {
} else {
report(
DiagnosticsEngine::Warning,
"this local variable of type '%0' follows our pointer naming convention, but it is not a pointer, %1",
varDecl->getLocation())
<< typeName << aOriginalTypeName << varDecl->getSourceRange();
}
}
if (matchRefCountedPointerVar(name)
&& !startswith(typeName, "boost::intrusive_ptr")
&& !startswith(typeName, "com::sun::star::uno::Reference")
&& !startswith(typeName, "com::sun::star::uno::Sequence")
&& !startswith(typeName, "com::sun::star::uno::WeakReference")
&& !startswith(typeName, "drawinglayer::primitive2d::Primitive2DContainer")
&& !startswith(typeName, "drawinglayer::primitive3d::Primitive3DContainer")
&& !startswith(typeName, "jfw::CXPathObjectPtr")
&& !startswith(typeName, "_LOKDocViewPrivate")
&& !startswith(typeName, "oox::dump::BinaryInputStreamRef")
&& !startswith(typeName, "oox::drawingml::chart::ModelRef")
&& !startswith(typeName, "rtl::Reference")
&& !startswith(typeName, "Reference")
&& !startswith(typeName, "SfxObjectShellLock")
&& !startswith(typeName, "store::PageHolderObject")
&& !startswith(typeName, "store::ResourceHolder")
&& !startswith(typeName, "store::OStoreHandle")
&& typeName.find("unique_ptr") == std::string::npos
&& typeName.find("shared_ptr") == std::string::npos
&& !startswith(typeName, "ScopedVclPtr")
&& !startswith(typeName, "svt::EmbeddedObjectRef")
&& !startswith(typeName, "tools::SvRef")
&& !startswith(typeName, "tools::WeakReference")
&& !startswith(typeName, "utl::SharedUNOComponent")
&& !startswith(typeName, "VclPtr")
&& !startswith(typeName, "vcl::DeleteOnDeinit")
&& !startswith(typeName, "vcl::DeleteUnoReferenceOnDeinit")
// there are lots of coordinate/position vars that start with "x"
&& !qt->isArithmeticType()
&& !startswith(typeName, "float [")
)
{
report(
DiagnosticsEngine::Warning,
"this local variable of type '%0' follows our ref-counted-pointer naming convention, but it is not a ref-counted-pointer, %1",
varDecl->getLocation())
<< typeName << aOriginalTypeName << varDecl->getSourceRange();
}
return true;
}
loplugin::Plugin::Registration< StylePolice > X("stylepolice");
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */