Index: clang-tools-extra/trunk/clang-tidy/google/CMakeLists.txt =================================================================== --- clang-tools-extra/trunk/clang-tidy/google/CMakeLists.txt +++ clang-tools-extra/trunk/clang-tidy/google/CMakeLists.txt @@ -10,6 +10,7 @@ NamedParameterCheck.cpp OverloadedUnaryAndCheck.cpp StringReferenceMemberCheck.cpp + TodoCommentCheck.cpp UnnamedNamespaceInHeaderCheck.cpp UsingNamespaceDirectiveCheck.cpp Index: clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp =================================================================== --- clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp +++ clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp @@ -18,6 +18,7 @@ #include "NamedParameterCheck.h" #include "OverloadedUnaryAndCheck.h" #include "StringReferenceMemberCheck.h" +#include "TodoCommentCheck.h" #include "UnnamedNamespaceInHeaderCheck.h" #include "UsingNamespaceDirectiveCheck.h" @@ -49,6 +50,8 @@ "google-readability-casting"); CheckFactories.registerCheck( "google-readability-function"); + CheckFactories.registerCheck( + "google-readability-todo"); } }; Index: clang-tools-extra/trunk/clang-tidy/google/TodoCommentCheck.h =================================================================== --- clang-tools-extra/trunk/clang-tidy/google/TodoCommentCheck.h +++ clang-tools-extra/trunk/clang-tidy/google/TodoCommentCheck.h @@ -0,0 +1,33 @@ +//===--- TodoCommentCheck.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_GOOGLE_TODOCOMMENTCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_TODOCOMMENTCHECK_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace readability { + +/// \brief Finds TODO comments without a username or bug number. +/// +/// Corresponding cpplint.py check: readability/todo +class TodoCommentCheck : public ClangTidyCheck { +public: + TodoCommentCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerPPCallbacks(CompilerInstance &Compiler) override; +}; + +} // namespace readability +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_TODOCOMMENTCHECK_H Index: clang-tools-extra/trunk/clang-tidy/google/TodoCommentCheck.cpp =================================================================== --- clang-tools-extra/trunk/clang-tidy/google/TodoCommentCheck.cpp +++ clang-tools-extra/trunk/clang-tidy/google/TodoCommentCheck.cpp @@ -0,0 +1,65 @@ +//===--- TodoCommentCheck.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 "TodoCommentCheck.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Preprocessor.h" + +namespace clang { +namespace tidy { +namespace readability { + +namespace { +class TodoCommentHandler : public CommentHandler { +public: + explicit TodoCommentHandler(TodoCommentCheck &Check) + : Check(Check), TodoMatch("^// *TODO(\\(.*\\))?:?( )?(.*)$") {} + + bool HandleComment(Preprocessor &PP, SourceRange Range) override { + StringRef Text = + Lexer::getSourceText(CharSourceRange::getCharRange(Range), + PP.getSourceManager(), PP.getLangOpts()); + + SmallVector Matches; + if (!TodoMatch.match(Text, &Matches)) + return false; + + StringRef Username = Matches[1]; + StringRef Comment = Matches[3]; + + if (!Username.empty()) + return false; + + // If the username is missing put in the current user's name. Not ideal but + // works for running tidy locally. + // FIXME: Can we get this from a more reliable source? + const char *User = std::getenv("USER"); + if (!User) + User = "unknown"; + std::string NewText = ("// TODO(" + Twine(User) + "): " + Comment).str(); + + Check.diag(Range.getBegin(), "missing username/bug in TODO") + << FixItHint::CreateReplacement(CharSourceRange::getCharRange(Range), + NewText); + return false; + } + +private: + TodoCommentCheck &Check; + llvm::Regex TodoMatch; +}; +} // namespace + +void TodoCommentCheck::registerPPCallbacks(CompilerInstance &Compiler) { + Compiler.getPreprocessor().addCommentHandler(new TodoCommentHandler(*this)); +} + +} // namespace readability +} // namespace tidy +} // namespace clang Index: clang-tools-extra/trunk/test/clang-tidy/check_clang_tidy_fix.sh =================================================================== --- clang-tools-extra/trunk/test/clang-tidy/check_clang_tidy_fix.sh +++ clang-tools-extra/trunk/test/clang-tidy/check_clang_tidy_fix.sh @@ -20,7 +20,7 @@ # Remove the contents of the CHECK lines to avoid CHECKs matching on themselves. # We need to keep the comments to preserve line numbers while avoiding empty # lines which could potentially trigger formatting-related checks. -sed 's#// *[A-Z-][A-Z-]*:.*#//#' ${INPUT_FILE} > ${TEMPORARY_FILE} +sed 's#// *CHECK-[A-Z-]*:.*#//#' ${INPUT_FILE} > ${TEMPORARY_FILE} clang-tidy ${TEMPORARY_FILE} -fix --checks="-*,${CHECK_TO_RUN}" \ -- --std=c++11 $* > ${TEMPORARY_FILE}.msg 2>&1 Index: clang-tools-extra/trunk/test/clang-tidy/google-readability-todo.cpp =================================================================== --- clang-tools-extra/trunk/test/clang-tidy/google-readability-todo.cpp +++ clang-tools-extra/trunk/test/clang-tidy/google-readability-todo.cpp @@ -0,0 +1,25 @@ +// RUN: $(dirname %s)/check_clang_tidy_fix.sh %s google-readability-todo %t +// REQUIRES: shell + +// TODOfix this1 +// CHECK-MESSAGES: [[@LINE-1]]:1: warning: missing username/bug in TODO +// CHECK-FIXES: // TODO({{[^)]+}}): fix this1 + +// TODO fix this2 +// CHECK-MESSAGES: [[@LINE-1]]:1: warning: missing username/bug in TODO +// CHECK-FIXES: // TODO({{[^)]+}}): fix this2 + +// TODO fix this3 +// CHECK-MESSAGES: [[@LINE-1]]:1: warning: missing username/bug in TODO +// CHECK-FIXES: // TODO({{[^)]+}}): fix this3 + +// TODO: fix this4 +// CHECK-MESSAGES: [[@LINE-1]]:1: warning: missing username/bug in TODO +// CHECK-FIXES: // TODO({{[^)]+}}): fix this4 + +// TODO(clang)fix this5 + +// TODO(foo):shave yaks +// TODO(bar): +// TODO(foo): paint bikeshed +// TODO(b/12345): find the holy grail