Index: clang-tidy/readability/CMakeLists.txt =================================================================== --- clang-tidy/readability/CMakeLists.txt +++ clang-tidy/readability/CMakeLists.txt @@ -5,6 +5,7 @@ ContainerSizeEmptyCheck.cpp ElseAfterReturnCheck.cpp FunctionSizeCheck.cpp + IdentifierNamingCheck.cpp NamedParameterCheck.cpp NamespaceCommentCheck.cpp ReadabilityTidyModule.cpp Index: clang-tidy/readability/IdentifierNamingCheck.h =================================================================== --- /dev/null +++ clang-tidy/readability/IdentifierNamingCheck.h @@ -0,0 +1,72 @@ +//===--- IdentifierNamingCheck.h - clang-tidy -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace readability { + +/// \brief Checks for identifiers naming style mismatch. +class IdentifierNamingCheck : public ClangTidyCheck { +public: + IdentifierNamingCheck(StringRef Name, ClangTidyContext *Context); + + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + void onEndOfTranslationUnit() override; + +private: + enum CaseType { + AnyCase = 0, + LowerCase, + CamelBack, + UpperCase, + CamelCase, + }; + + struct NamingStyle { + NamingStyle() : Case(CaseType::AnyCase) {} + + NamingStyle(CaseType Case, std::string Prefix, std::string Suffix) + : Case(Case), Prefix(std::move(Prefix)), Suffix(std::move(Suffix)) {} + + CaseType Case; + std::string Prefix; + std::string Suffix; + + bool isSet() { + return !(Case == CaseType::AnyCase && Prefix.empty() && Suffix.empty()); + } + }; + + std::vector NamingStyles; + bool IgnoreFailedSplit; + + struct NamingCheckFailure { + std::string KindName; + std::string Fixup; + bool ShouldFix; + std::vector Usages; + + NamingCheckFailure() : ShouldFix(true) {} + }; + + llvm::DenseMap NamingCheckFailures; +}; + +} // namespace readability +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H Index: clang-tidy/readability/IdentifierNamingCheck.cpp =================================================================== --- /dev/null +++ clang-tidy/readability/IdentifierNamingCheck.cpp @@ -0,0 +1,627 @@ +//===--- IdentifierNamingCheck.cpp - clang-tidy ---------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "IdentifierNamingCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace readability { + +#define NAMING_KEYS(m) \ + m(Namespace) \ + m(InlineNamespace) \ + m(EnumConstant) \ + m(ConstexprVariable) \ + m(MemberConstant) \ + m(MemberPrivate) \ + m(MemberProtected) \ + m(MemberPublic) \ + m(Member) \ + m(ClassConstant) \ + m(ClassMember) \ + m(GlobalConstant) \ + m(GlobalVariable) \ + m(LocalConstant) \ + m(LocalVariable) \ + m(StaticConstant) \ + m(StaticVariable) \ + m(Constant) \ + m(Variable) \ + m(ParameterConstant) \ + m(ParameterPack) \ + m(Parameter) \ + m(Abstract) \ + m(Struct) \ + m(Class) \ + m(Union) \ + m(Enum) \ + m(GlobalFunction) \ + m(ConstexprFunction) \ + m(Function) \ + m(ConstexprMethod) \ + m(VirtualMethod) \ + m(ClassMethod) \ + m(MethodPrivate) \ + m(MethodProtected) \ + m(MethodPublic) \ + m(Method) \ + m(Typedef) \ + m(TypeTemplateParameter) \ + m(ValueTemplateParameter) \ + m(TemplateTemplateParameter) \ + m(TemplateParameter) + +enum StyleConst { +#define ENUMERATE(v) v, + NAMING_KEYS(ENUMERATE) +#undef ENUMERATE +}; + +static StyleConst const StyleKeys[] = { +#define ENUMERATE(v) v, + NAMING_KEYS(ENUMERATE) +#undef ENUMERATE +}; + +static StringRef const StyleNames[] = { +#define STRINGIZE(v) #v, + NAMING_KEYS(STRINGIZE) +#undef STRINGIZE +}; + +#undef NAMING_KEYS + +IdentifierNamingCheck::IdentifierNamingCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) { + auto const fromString = [](StringRef Str) { + if (Str.equals("any") || Str.equals("aNy_CasE")) + return AnyCase; + + if (Str.equals("lower") || Str.equals("lower_case")) + return LowerCase; + + if (Str.equals("camelBack")) + return CamelBack; + + if (Str.equals("upper") || Str.equals("UPPER_CASE")) + return UpperCase; + + if (Str.equals("CamelCase")) + return CamelCase; + + return AnyCase; + }; + + for (const auto &Key : StyleKeys) { + NamingStyles.push_back(NamingStyle( + fromString(Options.get((StyleNames[Key] + "Case").str(), "aNy_CasE")), + Options.get((StyleNames[Key] + "Prefix").str(), ""), + Options.get((StyleNames[Key] + "Suffix").str(), ""))); + } + + IgnoreFailedSplit = Options.get("IgnoreFailedSplit", 0); +} + +void IdentifierNamingCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + auto const toString = [](CaseType Type) { + switch (Type) { + default: + case AnyCase: + return "aNy_CasE"; + case LowerCase: + return "lower_case"; + case CamelBack: + return "camelBack"; + case UpperCase: + return "UPPER_CASE"; + case CamelCase: + return "CamelCase"; + } + }; + + for (const auto &Key : StyleKeys) { + Options.store(Opts, (StyleNames[Key] + "Case").str(), + toString(NamingStyles[Key].Case)); + Options.store(Opts, (StyleNames[Key] + "Prefix").str(), + NamingStyles[Key].Prefix); + Options.store(Opts, (StyleNames[Key] + "Suffix").str(), + NamingStyles[Key].Suffix); + } + + Options.store(Opts, "IgnoreFailedSplit", IgnoreFailedSplit); +} + +void IdentifierNamingCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(namedDecl().bind("decl"), this); + Finder->addMatcher(declRefExpr().bind("declref"), this); +} + +void IdentifierNamingCheck::check(const MatchFinder::MatchResult &Result) { + if (const auto *DeclRef = Result.Nodes.getNodeAs("declref")) { + auto It = NamingCheckFailures.find(cast(DeclRef->getDecl())); + if (It == NamingCheckFailures.end()) + return; + + auto &Failure = It->second; + auto Range = DeclRef->getNameInfo().getSourceRange(); + + Failure.Usages.push_back(Range); + Failure.ShouldFix = Failure.ShouldFix && + Result.SourceManager->isInMainFile(Range.getBegin()) && + Result.SourceManager->isInMainFile(Range.getEnd()) && + !Range.getBegin().isMacroID() && + !Range.getEnd().isMacroID(); + + return; + } + + if (const auto *Decl = Result.Nodes.getNodeAs("decl")) { + if (!Decl->getIdentifier() || Decl->getName().empty() || Decl->isImplicit()) + return; + } + + auto KindName = "identifier"; + auto Style = NamingStyle(); + + if (Result.Nodes.getNodeAs("decl")) { + if (NamingStyles[Typedef].isSet()) { + KindName = "typedef"; + Style = NamingStyles[Typedef]; + } + } + + if (const auto *Decl = Result.Nodes.getNodeAs("decl")) { + if (Decl->isAnonymousNamespace()) + return; + + if (Decl->isInline() && NamingStyles[InlineNamespace].isSet()) { + KindName = "inline namespace"; + Style = NamingStyles[InlineNamespace]; + + } else if (NamingStyles[Namespace].isSet()) { + KindName = "namespace"; + Style = NamingStyles[Namespace]; + } + } + + if (const auto *Decl = Result.Nodes.getNodeAs("decl")) { + if (Decl->isAnonymousStructOrUnion()) + return; + + if (Decl->hasDefinition() && Decl->isAbstract() && + NamingStyles[Abstract].isSet()) { + KindName = "abstract class"; + Style = NamingStyles[Abstract]; + + } else if (Decl->isStruct() && NamingStyles[Struct].isSet()) { + KindName = "struct"; + Style = NamingStyles[Struct]; + + } else if (Decl->isStruct() && NamingStyles[Class].isSet()) { + KindName = "struct"; + Style = NamingStyles[Class]; + + } else if (Decl->isClass() && NamingStyles[Class].isSet()) { + KindName = "class"; + Style = NamingStyles[Class]; + + } else if (Decl->isClass() && NamingStyles[Struct].isSet()) { + KindName = "class"; + Style = NamingStyles[Struct]; + + } else if (Decl->isUnion() && NamingStyles[Union].isSet()) { + KindName = "union"; + Style = NamingStyles[Union]; + + } else if (Decl->isEnum() && NamingStyles[Enum].isSet()) { + KindName = "enum"; + Style = NamingStyles[Enum]; + } + } + + if (const auto *Decl = Result.Nodes.getNodeAs("decl")) { + auto Type = Decl->getType(); + + if (!Type.isNull() && Type.isLocalConstQualified() && + NamingStyles[MemberConstant].isSet()) { + KindName = "constant member"; + Style = NamingStyles[MemberConstant]; + + } else if (!Type.isNull() && Type.isLocalConstQualified() && + NamingStyles[Constant].isSet()) { + KindName = "constant member"; + Style = NamingStyles[Constant]; + + } else if (Decl->getAccess() == clang::AS_private && + NamingStyles[MemberPrivate].isSet()) { + KindName = "private member"; + Style = NamingStyles[MemberPrivate]; + + } else if (Decl->getAccess() == clang::AS_protected && + NamingStyles[MemberProtected].isSet()) { + KindName = "protected member"; + Style = NamingStyles[MemberProtected]; + + } else if (Decl->getAccess() == clang::AS_public && + NamingStyles[MemberPublic].isSet()) { + KindName = "public member"; + Style = NamingStyles[MemberPublic]; + + } else if (NamingStyles[Member].isSet()) { + KindName = "member"; + Style = NamingStyles[Member]; + } + + } else if (const auto *Decl = Result.Nodes.getNodeAs("decl")) { + auto Type = Decl->getType(); + + if (Decl->isConstexpr() && NamingStyles[ConstexprVariable].isSet()) { + KindName = "constexpr"; + Style = NamingStyles[ConstexprVariable]; + + } else if (!Type.isNull() && Type.isLocalConstQualified() && + NamingStyles[ParameterConstant].isSet()) { + KindName = "constant parameter"; + Style = NamingStyles[Constant]; + + } else if (!Type.isNull() && Type.isLocalConstQualified() && + NamingStyles[Constant].isSet()) { + KindName = "constant parameter"; + Style = NamingStyles[Constant]; + + } else if (Decl->isParameterPack() && NamingStyles[ParameterPack].isSet()) { + KindName = "parameter pack"; + Style = NamingStyles[ParameterPack]; + + } else if (NamingStyles[Parameter].isSet()) { + KindName = "parameter"; + Style = NamingStyles[Parameter]; + } + + } else if (const auto *Decl = Result.Nodes.getNodeAs("decl")) { + auto Type = Decl->getType(); + + if (Decl->isConstexpr() && NamingStyles[ConstexprVariable].isSet()) { + KindName = "constexpr"; + Style = NamingStyles[ConstexprVariable]; + + } else if (!Type.isNull() && Type.isLocalConstQualified() && + Decl->isStaticDataMember() && + NamingStyles[ClassConstant].isSet()) { + KindName = "class constant"; + Style = NamingStyles[ClassConstant]; + + } else if (!Type.isNull() && Type.isLocalConstQualified() && + Decl->isFileVarDecl() && NamingStyles[GlobalConstant].isSet()) { + KindName = "global constant"; + Style = NamingStyles[GlobalConstant]; + + } else if (!Type.isNull() && Type.isLocalConstQualified() && + Decl->isStaticLocal() && NamingStyles[StaticConstant].isSet()) { + KindName = "static constant"; + Style = NamingStyles[StaticConstant]; + + } else if (!Type.isNull() && Type.isLocalConstQualified() && + Decl->isLocalVarDecl() && NamingStyles[LocalConstant].isSet()) { + KindName = "local constant"; + Style = NamingStyles[LocalConstant]; + + } else if (!Type.isNull() && Type.isLocalConstQualified() && + Decl->isFunctionOrMethodVarDecl() && + NamingStyles[LocalConstant].isSet()) { + KindName = "local constant"; + Style = NamingStyles[LocalConstant]; + + } else if (!Type.isNull() && Type.isLocalConstQualified() && + NamingStyles[Constant].isSet()) { + KindName = "constant"; + Style = NamingStyles[Constant]; + + } else if (Decl->isStaticDataMember() && + NamingStyles[ClassMember].isSet()) { + KindName = "class member"; + Style = NamingStyles[ClassMember]; + + } else if (Decl->isFileVarDecl() && NamingStyles[GlobalVariable].isSet()) { + KindName = "global variable"; + Style = NamingStyles[GlobalVariable]; + + } else if (Decl->isStaticLocal() && NamingStyles[StaticVariable].isSet()) { + KindName = "static variable"; + Style = NamingStyles[StaticVariable]; + + } else if (Decl->isLocalVarDecl() && NamingStyles[LocalVariable].isSet()) { + KindName = "local variable"; + Style = NamingStyles[LocalVariable]; + + } else if (Decl->isFunctionOrMethodVarDecl() && + NamingStyles[LocalVariable].isSet()) { + KindName = "local variable"; + Style = NamingStyles[LocalVariable]; + + } else if (NamingStyles[Variable].isSet()) { + KindName = "variable"; + Style = NamingStyles[Variable]; + } + } + + if (const auto *Decl = Result.Nodes.getNodeAs("decl")) { + if (Decl->isMain() || !Decl->isUserProvided() || + Decl->isUsualDeallocationFunction() || + Decl->isCopyAssignmentOperator() || Decl->isMoveAssignmentOperator() || + Decl->size_overridden_methods() > 0) + return; + + if (Decl->isConstexpr() && NamingStyles[ConstexprMethod].isSet()) { + KindName = "constexpr method"; + Style = NamingStyles[ConstexprMethod]; + + } else if (Decl->isConstexpr() && NamingStyles[ConstexprFunction].isSet()) { + KindName = "constexpr method"; + Style = NamingStyles[ConstexprFunction]; + + } else if (Decl->isStatic() && NamingStyles[ClassMethod].isSet()) { + KindName = "class method"; + Style = NamingStyles[ClassMethod]; + + } else if (Decl->isVirtual() && NamingStyles[VirtualMethod].isSet()) { + KindName = "virtual method"; + Style = NamingStyles[VirtualMethod]; + + } else if (Decl->getAccess() == clang::AS_private && + NamingStyles[MethodPrivate].isSet()) { + KindName = "private method"; + Style = NamingStyles[MethodPrivate]; + + } else if (Decl->getAccess() == clang::AS_protected && + NamingStyles[MethodProtected].isSet()) { + KindName = "protected method"; + Style = NamingStyles[MethodProtected]; + + } else if (Decl->getAccess() == clang::AS_public && + NamingStyles[MethodPublic].isSet()) { + KindName = "public method"; + Style = NamingStyles[MethodPublic]; + + } else if (NamingStyles[Method].isSet()) { + KindName = "method"; + Style = NamingStyles[Method]; + + } else if (NamingStyles[Function].isSet()) { + KindName = "method"; + Style = NamingStyles[Function]; + } + + } else if (const auto *Decl = Result.Nodes.getNodeAs("decl")) { + if (Decl->isMain()) + return; + + if (Decl->isConstexpr() && NamingStyles[ConstexprFunction].isSet()) { + KindName = "constexpr function"; + Style = NamingStyles[ConstexprFunction]; + + } else if (Decl->isGlobal() && NamingStyles[GlobalFunction].isSet()) { + KindName = "global function"; + Style = NamingStyles[GlobalFunction]; + + } else if (NamingStyles[Function].isSet()) { + KindName = "function"; + Style = NamingStyles[Function]; + } + } + + if (Result.Nodes.getNodeAs("decl")) { + if (NamingStyles[Enum].isSet()) { + KindName = "enum"; + Style = NamingStyles[Enum]; + } + } + + if (Result.Nodes.getNodeAs("decl")) { + if (NamingStyles[EnumConstant].isSet()) { + KindName = "enum constant"; + Style = NamingStyles[EnumConstant]; + + } else if (NamingStyles[Constant].isSet()) { + KindName = "enum constant"; + Style = NamingStyles[Constant]; + } + } + + if (Result.Nodes.getNodeAs("decl")) { + if (NamingStyles[TypeTemplateParameter].isSet()) { + KindName = "type template parameter"; + Style = NamingStyles[TypeTemplateParameter]; + + } else if (NamingStyles[TemplateParameter].isSet()) { + KindName = "template parameter"; + Style = NamingStyles[TemplateParameter]; + } + + } else if (Result.Nodes.getNodeAs("decl")) { + if (NamingStyles[ValueTemplateParameter].isSet()) { + KindName = "value template parameter"; + Style = NamingStyles[ValueTemplateParameter]; + + } else if (NamingStyles[TemplateParameter].isSet()) { + KindName = "template parameter"; + Style = NamingStyles[TemplateParameter]; + } + + } else if (Result.Nodes.getNodeAs("decl")) { + if (NamingStyles[TemplateTemplateParameter].isSet()) { + KindName = "template template parameter"; + Style = NamingStyles[TemplateTemplateParameter]; + + } else if (NamingStyles[TemplateParameter].isSet()) { + KindName = "template parameter"; + Style = NamingStyles[TemplateParameter]; + } + } + + if (!Style.isSet()) + return; + + auto matchesStyle = [](StringRef Name, NamingStyle Style) { + static llvm::Regex Matchers[] = { + llvm::Regex(StringRef("^.*$")), + llvm::Regex(StringRef("^[a-z][a-z0-9_]*$")), + llvm::Regex(StringRef("^[a-z][a-zA-Z0-9]*$")), + llvm::Regex(StringRef("^[A-Z][A-Z0-9_]*$")), + llvm::Regex(StringRef("^[A-Z][a-zA-Z0-9]*$")), + }; + + bool Matches = true; + if (Name.startswith(Style.Prefix)) + Name = Name.drop_front(Style.Prefix.size()); + else + Matches = false; + + if (Name.endswith(Style.Suffix)) + Name = Name.drop_back(Style.Suffix.size()); + else + Matches = false; + + if (!Matchers[static_cast(Style.Case)].match(Name)) + Matches = false; + + return Matches; + }; + + if (const auto *Decl = Result.Nodes.getNodeAs("decl")) { + if (matchesStyle(Decl->getName(), Style)) + return; + + auto fixupWithStyle = [](std::string Name, NamingStyle Style) { + static auto Splitter = llvm::Regex(StringRef( + "(([a-z0-9A-Z]*)(_+)|([A-Z]?[a-z0-9]+)([A-Z]|$)|([A-Z]+)([A-Z]|$))")); + + auto Words = SmallVector(); + auto Substrs = SmallVector(); + StringRef(Name).split(Substrs, "_", -1, false); + for (std::string Substr : Substrs) { + while (!Substr.empty()) { + auto Groups = SmallVector(); + if (!Splitter.match(Substr, &Groups)) + break; + + if (Groups[3].size() > 0) { + Words.emplace_back(std::move(Groups[2])); + Substr = Substr.substr(Groups[0].size()); + + } else if (Groups[4].size() > 0) { + Words.emplace_back(std::move(Groups[4])); + Substr = Substr.substr(Groups[0].size() - Groups[5].size()); + + } else if (Groups[6].size() > 0) { + Words.emplace_back(std::move(Groups[6])); + Substr = Substr.substr(Groups[0].size() - Groups[7].size()); + } + } + } + + if (Words.empty()) + return Name; + + std::string Fixup = Style.Prefix; + switch (Style.Case) { + case AnyCase: + Fixup += Name; + break; + + case LowerCase: + for (auto const &Word : Words) { + if (&Word != &Words.front()) + Fixup += "_"; + Fixup += StringRef(Word).lower(); + } + break; + + case UpperCase: + for (auto const &Word : Words) { + if (&Word != &Words.front()) + Fixup += "_"; + Fixup += StringRef(Word).upper(); + } + break; + + case CamelCase: + for (auto const &Word : Words) { + Fixup += StringRef(Word).substr(0, 1).upper(); + Fixup += StringRef(Word).substr(1).lower(); + } + break; + + case CamelBack: + for (auto const &Word : Words) { + if (&Word == &Words.front()) { + Fixup += StringRef(Word).lower(); + } else { + Fixup += StringRef(Word).substr(0, 1).upper(); + Fixup += StringRef(Word).substr(1).lower(); + } + } + break; + } + Fixup += Style.Suffix; + + return Fixup; + }; + + auto Name = Decl->getName(); + auto Fixup = fixupWithStyle(Name, Style); + if (StringRef(Fixup).equals(Name)) { + if (!IgnoreFailedSplit) { + diag(Decl->getLocStart(), "unable to split words for %0 '%1'") + << KindName << Name; + } + } else { + auto &Failure = NamingCheckFailures[Decl]; + auto Range = + clang::DeclarationNameInfo(Decl->getDeclName(), Decl->getLocation()) + .getSourceRange(); + + Failure.Fixup = std::move(Fixup); + Failure.KindName = std::move(KindName); + Failure.ShouldFix = + Failure.ShouldFix && + Result.SourceManager->isInMainFile(Range.getBegin()) && + Result.SourceManager->isInMainFile(Range.getEnd()) && + !Range.getBegin().isMacroID() && !Range.getEnd().isMacroID(); + } + } +} + +void IdentifierNamingCheck::onEndOfTranslationUnit() { + for (const auto &P : NamingCheckFailures) { + auto DeclRange = + clang::DeclarationNameInfo(P.first->getDeclName(), + P.first->getLocation()).getSourceRange(); + auto Diagn = diag(P.first->getLocStart(), "invalid case style for %0 '%1'") + << P.second.KindName << P.first->getName(); + + if (P.second.ShouldFix) { + Diagn << FixItHint::CreateReplacement( + CharSourceRange::getTokenRange(DeclRange), P.second.Fixup); + + for (const auto &Range : P.second.Usages) { + Diagn << FixItHint::CreateReplacement( + CharSourceRange::getTokenRange(Range), P.second.Fixup); + } + } + } +} + +} // namespace readability +} // namespace tidy +} // namespace clang Index: clang-tidy/readability/ReadabilityTidyModule.cpp =================================================================== --- clang-tidy/readability/ReadabilityTidyModule.cpp +++ clang-tidy/readability/ReadabilityTidyModule.cpp @@ -14,6 +14,7 @@ #include "ContainerSizeEmptyCheck.h" #include "ElseAfterReturnCheck.h" #include "FunctionSizeCheck.h" +#include "IdentifierNamingCheck.h" #include "NamedParameterCheck.h" #include "RedundantSmartptrGetCheck.h" #include "RedundantStringCStrCheck.h" @@ -35,6 +36,8 @@ "readability-else-after-return"); CheckFactories.registerCheck( "readability-function-size"); + CheckFactories.registerCheck( + "readability-identifier-naming"); CheckFactories.registerCheck( "readability-named-parameter"); CheckFactories.registerCheck( Index: test/clang-tidy/readability-identifier-naming.cpp =================================================================== --- /dev/null +++ test/clang-tidy/readability-identifier-naming.cpp @@ -0,0 +1,197 @@ +// RUN: $(dirname %s)/check_clang_tidy.sh %s readability-identifier-naming %t -config='{CheckOptions: [{key: readability-identifier-naming.AbstractCase, value: CamelCase}, {key: readability-identifier-naming.AbstractPrefix, value: 'A'}, {key: readability-identifier-naming.ClassCase, value: CamelCase}, {key: readability-identifier-naming.ClassPrefix, value: 'C'}, {key: readability-identifier-naming.ClassConstantCase, value: CamelCase}, {key: readability-identifier-naming.ClassConstantPrefix, value: 'k'}, {key: readability-identifier-naming.ClassMemberCase, value: CamelCase}, {key: readability-identifier-naming.ClassMethodCase, value: camelBack}, {key: readability-identifier-naming.ConstantCase, value: UPPER_CASE}, {key: readability-identifier-naming.ConstantSuffix, value: '_CST'}, {key: readability-identifier-naming.ConstexprFunctionCase, value: lower_case}, {key: readability-identifier-naming.ConstexprMethodCase, value: lower_case}, {key: readability-identifier-naming.ConstexprVariableCase, value: lower_case}, {key: readability-identifier-naming.EnumCase, value: CamelCase}, {key: readability-identifier-naming.EnumPrefix, value: 'E'}, {key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE}, {key: readability-identifier-naming.FunctionCase, value: camelBack}, {key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE}, {key: readability-identifier-naming.GlobalFunctionCase, value: CamelCase}, {key: readability-identifier-naming.GlobalVariableCase, value: lower_case}, {key: readability-identifier-naming.GlobalVariablePrefix, value: 'g_'}, {key: readability-identifier-naming.InlineNamespaceCase, value: lower_case}, {key: readability-identifier-naming.LocalConstantCase, value: CamelCase}, {key: readability-identifier-naming.LocalConstantPrefix, value: 'k'}, {key: readability-identifier-naming.LocalVariableCase, value: lower_case}, {key: readability-identifier-naming.MemberCase, value: CamelCase}, {key: readability-identifier-naming.MemberPrefix, value: 'm_'}, {key: readability-identifier-naming.MemberConstantCase, value: lower_case}, {key: readability-identifier-naming.MemberPrivatePrefix, value: '__'}, {key: readability-identifier-naming.MemberProtectedPrefix, value: '_'}, {key: readability-identifier-naming.MemberPublicCase, value: lower_case}, {key: readability-identifier-naming.MethodCase, value: camelBack}, {key: readability-identifier-naming.MethodPrivatePrefix, value: '__'}, {key: readability-identifier-naming.MethodProtectedPrefix, value: '_'}, {key: readability-identifier-naming.NamespaceCase, value: lower_case}, {key: readability-identifier-naming.ParameterCase, value: camelBack}, {key: readability-identifier-naming.ParameterPrefix, value: 'a_'}, {key: readability-identifier-naming.ParameterConstantCase, value: camelBack}, {key: readability-identifier-naming.ParameterConstantPrefix, value: 'i_'}, {key: readability-identifier-naming.ParameterPackCase, value: camelBack}, {key: readability-identifier-naming.PureFunctionCase, value: lower_case}, {key: readability-identifier-naming.PureMethodCase, value: camelBack}, {key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE}, {key: readability-identifier-naming.StaticVariableCase, value: camelBack}, {key: readability-identifier-naming.StaticVariablePrefix, value: 's_'}, {key: readability-identifier-naming.StructCase, value: lower_case}, {key: readability-identifier-naming.TemplateParameterCase, value: UPPER_CASE}, {key: readability-identifier-naming.TemplateTemplateParameterCase, value: CamelCase}, {key: readability-identifier-naming.TemplateUsingCase, value: lower_case}, {key: readability-identifier-naming.TemplateUsingPrefix, value: 'u_'}, {key: readability-identifier-naming.TypeTemplateParameterCase, value: camelBack}, {key: readability-identifier-naming.TypeTemplateParameterSuffix, value: '_t'}, {key: readability-identifier-naming.TypedefCase, value: lower_case}, {key: readability-identifier-naming.TypedefSuffix, value: '_t'}, {key: readability-identifier-naming.UnionCase, value: CamelCase}, {key: readability-identifier-naming.UnionPrefix, value: 'U'}, {key: readability-identifier-naming.UsingCase, value: lower_case}, {key: readability-identifier-naming.ValueTemplateParameterCase, value: camelBack}, {key: readability-identifier-naming.VariableCase, value: lower_case}, {key: readability-identifier-naming.VirtualMethodCase, value: UPPER_CASE}, {key: readability-identifier-naming.VirtualMethodPrefix, value: 'v_'}, {key: readability-identifier-naming.IgnoreFailedSplit, value: 0}]}' -- -std=c++11 +// REQUIRES: shell + +namespace FOO_NS { +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for namespace 'FOO_NS' [readability-identifier-naming] +// CHECK-FIXES: foo_ns +inline namespace InlineNamespace { +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for inline namespace 'InlineNamespace' [readability-identifier-naming] +// CHECK-FIXES: inline_namespace + +#define BLA int FOO_bar +BLA; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for global variable 'FOO_bar' [readability-identifier-naming] +// NO fix expected as FOO_bar is from macro expansion + +enum my_enumeration { +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for enum 'my_enumeration' [readability-identifier-naming] +// CHECK-FIXES: EMyEnumeration + MyConstant = 1, +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for enum constant 'MyConstant' [readability-identifier-naming] +// CHECK-FIXES: MY_CONSTANT + your_CONST = 1, +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for enum constant 'your_CONST' [readability-identifier-naming] +// CHECK-FIXES: YOUR_CONST + THIS_ConstValue = 1, +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for enum constant 'THIS_ConstValue' [readability-identifier-naming] +// CHECK-FIXES: THIS_CONST_VALUE +}; + +constexpr int ConstExpr_variable = MyConstant; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for constexpr 'ConstExpr_variable' [readability-identifier-naming] +// CHECK-FIXES: const_expr_variable +// CHECK-FIXES: MY_CONSTANT + +class my_class { +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for class 'my_class' [readability-identifier-naming] +// CHECK-FIXES: CMyClass + my_class(); + + const int MEMBER_one_1 = ConstExpr_variable; +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: invalid case style for constant member 'MEMBER_one_1' [readability-identifier-naming] +// CHECK-FIXES: member_one_1 +// CHECK-FIXES: const_expr_variable + int member2 = 2; +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: invalid case style for private member 'member2' [readability-identifier-naming] +// CHECK-FIXES: __member2 + +private: + int private_member = 3; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for private member 'private_member' [readability-identifier-naming] +// CHECK-FIXES: __private_member + +protected: + int ProtMember; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for protected member 'ProtMember' [readability-identifier-naming] +// CHECK-FIXES: _ProtMember + +public: + int PubMem; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for public member 'PubMem' [readability-identifier-naming] +// CHECK-FIXES: pub_mem + + static const int classConstant; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for class constant 'classConstant' [readability-identifier-naming] +// CHECK-FIXES: kClassConstant + static int ClassMember_2; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for class member 'ClassMember_2' [readability-identifier-naming] +// CHECK-FIXES: ClassMember2 +}; + +const int my_class::classConstant = 4; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for class constant 'classConstant' [readability-identifier-naming] +// CHECK-FIXES: kClassConstant +int my_class::ClassMember_2 = 5; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for class member 'ClassMember_2' [readability-identifier-naming] +// CHECK-FIXES: ClassMember2 + +const int global_Constant = 6; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for global constant 'global_Constant' [readability-identifier-naming] +// CHECK-FIXES: GLOBAL_CONSTANT +int Global_variable = 7; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for global variable 'Global_variable' [readability-identifier-naming] +// CHECK-FIXES: g_global_variable + +void global_function(int PARAMETER_1, int const CONST_parameter) { +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for global function 'global_function' [readability-identifier-naming] +// CHECK-FIXES: GlobalFunction +// CHECK-MESSAGES: :[[@LINE-3]]:22: warning: invalid case style for parameter 'PARAMETER_1' [readability-identifier-naming] +// CHECK-FIXES: a_parameter1 +// CHECK-MESSAGES: :[[@LINE-5]]:39: warning: invalid case style for constant parameter 'CONST_parameter' [readability-identifier-naming] +// CHECK-FIXES: CONST_PARAMETER_CST + static const int THIS_static_ConsTant = 4; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for static constant 'THIS_static_ConsTant' [readability-identifier-naming] +// CHECK-FIXES: THIS_STATIC_CONS_TANT + static int THIS_static_variable; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for static variable 'THIS_static_variable' [readability-identifier-naming] +// CHECK-FIXES: s_thisStaticVariable + int const local_Constant = 3; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for local constant 'local_Constant' [readability-identifier-naming] +// CHECK-FIXES: kLocalConstant + int LOCAL_VARIABLE; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for local variable 'LOCAL_VARIABLE' [readability-identifier-naming] +// CHECK-FIXES: local_variable + + int LOCAL_Array__[] = {0, 1, 2}; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for local variable 'LOCAL_Array__' [readability-identifier-naming] +// CHECK-FIXES: local_array + + for (auto _ : LOCAL_Array__) { +// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: unable to split words for local variable '_' [readability-identifier-naming] + } +} + +template +// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for type template parameter 'TYPE_parameters' [readability-identifier-naming] +// CHECK-FIXES: typeParameters_t +void Global_Fun(TYPE_parameters... PARAMETER_PACK) { +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for global function 'Global_Fun' [readability-identifier-naming] +// CHECK-FIXES: GlobalFun +// CHECK-MESSAGES: :[[@LINE-3]]:17: warning: invalid case style for parameter pack 'PARAMETER_PACK' [readability-identifier-naming] +// CHECK-FIXES: parameterPack + global_function(1, 2); +// CHECK-FIXES: GlobalFunction + FOO_bar = Global_variable; +// CHECK-FIXES: g_global_variable +// NO fix expected for FOO_bar declared in macro expansion +} + +template class TPL_parameter, int COUNT_params, typename ... TYPE_parameters> +// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for template template parameter 'TPL_parameter' [readability-identifier-naming] +// CHECK-FIXES: TplParameter +// CHECK-MESSAGES: :[[@LINE-3]]:50: warning: invalid case style for value template parameter 'COUNT_params' [readability-identifier-naming] +// CHECK-FIXES: countParams +// CHECK-MESSAGES: :[[@LINE-5]]:68: warning: invalid case style for type template parameter 'TYPE_parameters' [readability-identifier-naming] +// CHECK-FIXES: typeParameters_t +class test_CLASS { +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for class 'test_CLASS' [readability-identifier-naming] +// CHECK-FIXES: CTestClass +}; + +class abstract_class { +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for abstract class 'abstract_class' [readability-identifier-naming] +// CHECK-FIXES: AAbstractClass + virtual ~abstract_class() = 0; + virtual void VIRTUAL_METHOD(); +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for virtual method 'VIRTUAL_METHOD' [readability-identifier-naming] +// CHECK-FIXES: v_VIRTUAL_METHOD + void non_Virtual_METHOD() {} +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for private method 'non_Virtual_METHOD' [readability-identifier-naming] +// CHECK-FIXES: __non_Virtual_METHOD + static void CLASS_METHOD() {} +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for class method 'CLASS_METHOD' [readability-identifier-naming] +// CHECK-FIXES: classMethod + + constexpr int CST_expr_Method() { return 2; } +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for constexpr method 'CST_expr_Method' [readability-identifier-naming] +// CHECK-FIXES: cst_expr_method + +private: + void PRIVate_Method(); +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for private method 'PRIVate_Method' [readability-identifier-naming] +// CHECK-FIXES: __PRIVate_Method +protected: + void protected_Method(); +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for protected method 'protected_Method' [readability-identifier-naming] +// CHECK-FIXES: _protected_Method +public: + void public_Method(); +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for method 'public_Method' [readability-identifier-naming] +// CHECK-FIXES: publicMethod +}; + +constexpr int CE_function() { return 3; } +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for constexpr function 'CE_function' [readability-identifier-naming] +// CHECK-FIXES: ce_function + +struct THIS___Structure { +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for struct 'THIS___Structure' [readability-identifier-naming] +// CHECK-FIXES: this_structure + THIS___Structure(); + + union __MyUnion_is_wonderful__ {}; +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: invalid case style for union '__MyUnion_is_wonderful__' [readability-identifier-naming] +// CHECK-FIXES: UMyUnionIsWonderful +}; + +typedef THIS___Structure struct_type; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for typedef 'struct_type' [readability-identifier-naming] +// CHECK-FIXES: struct_type_t + +static void static_Function() { +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for function 'static_Function' [readability-identifier-naming] +// CHECK-FIXES: staticFunction +} + +} +}