diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:44:14 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:44:14 +0000 |
commit | 2b6b257f4e5503a7a2675bdb8735693db769f75c (patch) | |
tree | e85e046ae7003fe3bcc8b5454cd0fa3f7407b470 /include/clang/Tooling | |
parent | b4348ed0b7e90c0831b925fbee00b5f179a99796 (diff) |
Notes
Diffstat (limited to 'include/clang/Tooling')
-rw-r--r-- | include/clang/Tooling/CommonOptionsParser.h | 2 | ||||
-rw-r--r-- | include/clang/Tooling/Core/QualTypeNames.h | 79 | ||||
-rw-r--r-- | include/clang/Tooling/Core/Replacement.h | 53 | ||||
-rw-r--r-- | include/clang/Tooling/FixIt.h | 72 | ||||
-rw-r--r-- | include/clang/Tooling/Refactoring.h | 18 | ||||
-rw-r--r-- | include/clang/Tooling/Tooling.h | 7 |
6 files changed, 209 insertions, 22 deletions
diff --git a/include/clang/Tooling/CommonOptionsParser.h b/include/clang/Tooling/CommonOptionsParser.h index 1e8462c631c3..3d630c5f7609 100644 --- a/include/clang/Tooling/CommonOptionsParser.h +++ b/include/clang/Tooling/CommonOptionsParser.h @@ -98,7 +98,7 @@ public: } /// Returns a list of source file paths to process. - std::vector<std::string> getSourcePathList() { + const std::vector<std::string> &getSourcePathList() const { return SourcePathList; } diff --git a/include/clang/Tooling/Core/QualTypeNames.h b/include/clang/Tooling/Core/QualTypeNames.h new file mode 100644 index 000000000000..7248356e748e --- /dev/null +++ b/include/clang/Tooling/Core/QualTypeNames.h @@ -0,0 +1,79 @@ +//===--- QualTypeNames.h - Generate Complete QualType Names ----*- C++ -*-===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +// ===----------------------------------------------------------------------===// +// +// \file +// Functionality to generate the fully-qualified names of QualTypes, +// including recursively expanding any subtypes and template +// parameters. +// +// More precisely: Generates a name that can be used to name the same +// type if used at the end of the current translation unit--with +// certain limitations. See below. +// +// This code desugars names only very minimally, so in this code: +// +// namespace A { +// struct X {}; +// } +// using A::X; +// namespace B { +// using std::tuple; +// typedef tuple<X> TX; +// TX t; +// } +// +// B::t's type is reported as "B::TX", rather than std::tuple<A::X>. +// +// Also, this code replaces types found via using declarations with +// their more qualified name, so for the code: +// +// using std::tuple; +// tuple<int> TInt; +// +// TInt's type will be named, "std::tuple<int>". +// +// Limitations: +// +// Some types have ambiguous names at the end of a translation unit, +// are not namable at all there, or are special cases in other ways. +// +// 1) Types with only local scope will have their local names: +// +// void foo() { +// struct LocalType {} LocalVar; +// } +// +// LocalVar's type will be named, "struct LocalType", without any +// qualification. +// +// 2) Types that have been shadowed are reported normally, but a +// client using that name at the end of the translation unit will be +// referring to a different type. +// +// ===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H +#define LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H + +#include "clang/AST/ASTContext.h" + +namespace clang { +namespace TypeName { +/// \brief Get the fully qualified name for a type. This includes full +/// qualification of all template parameters etc. +/// +/// \param[in] QT - the type for which the fully qualified name will be +/// returned. +/// \param[in] Ctx - the ASTContext to be used. +/// \param[in] WithGlobalNsPrefix - If true, then the global namespace +/// specifier "::" will be prepended to the fully qualified name. +std::string getFullyQualifiedName(QualType QT, + const ASTContext &Ctx, + bool WithGlobalNsPrefix = false); +} // end namespace TypeName +} // end namespace clang +#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H diff --git a/include/clang/Tooling/Core/Replacement.h b/include/clang/Tooling/Core/Replacement.h index 37389ac91566..4815302ee455 100644 --- a/include/clang/Tooling/Core/Replacement.h +++ b/include/clang/Tooling/Core/Replacement.h @@ -22,6 +22,8 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include <map> #include <set> #include <string> #include <vector> @@ -56,6 +58,11 @@ public: return RHS.Offset >= Offset && (RHS.Offset + RHS.Length) <= (Offset + Length); } + + /// \brief Whether this range equals to \p RHS or not. + bool operator==(const Range &RHS) const { + return Offset == RHS.getOffset() && Length == RHS.getLength(); + } /// @} private: @@ -159,9 +166,13 @@ bool applyAllReplacements(const std::vector<Replacement> &Replaces, /// \brief Applies all replacements in \p Replaces to \p Code. /// -/// This completely ignores the path stored in each replacement. If one or more -/// replacements cannot be applied, this returns an empty \c string. -std::string applyAllReplacements(StringRef Code, const Replacements &Replaces); +/// This completely ignores the path stored in each replacement. If all +/// replacements are applied successfully, this returns the code with +/// replacements applied; otherwise, an llvm::Error carrying llvm::StringError +/// is returned (the Error message can be converted to string using +/// `llvm::toString()` and 'std::error_code` in the `Error` should be ignored). +llvm::Expected<std::string> applyAllReplacements(StringRef Code, + const Replacements &Replaces); /// \brief Calculates how a code \p Position is shifted when \p Replaces are /// applied. @@ -197,28 +208,30 @@ struct TranslationUnitReplacements { std::vector<Replacement> Replacements; }; -/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite. +/// \brief Calculates the ranges in a single file that are affected by the +/// Replacements. Overlapping ranges will be merged. /// -/// Replacement applications happen independently of the success of -/// other applications. +/// \pre Replacements must be for the same file. /// -/// \returns true if all replacements apply. false otherwise. -bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite); +/// \returns a non-overlapping and sorted ranges. +std::vector<Range> calculateChangedRanges(const Replacements &Replaces); -/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite. +/// \brief Calculates the new ranges after \p Replaces are applied. These +/// include both the original \p Ranges and the affected ranges of \p Replaces +/// in the new code. /// -/// Replacement applications happen independently of the success of -/// other applications. -/// -/// \returns true if all replacements apply. false otherwise. -bool applyAllReplacements(const std::vector<Replacement> &Replaces, - Rewriter &Rewrite); - -/// \brief Applies all replacements in \p Replaces to \p Code. +/// \pre Replacements must be for the same file. /// -/// This completely ignores the path stored in each replacement. If one or more -/// replacements cannot be applied, this returns an empty \c string. -std::string applyAllReplacements(StringRef Code, const Replacements &Replaces); +/// \return The new ranges after \p Replaces are applied. The new ranges will be +/// sorted and non-overlapping. +std::vector<Range> +calculateRangesAfterReplacements(const Replacements &Replaces, + const std::vector<Range> &Ranges); + +/// \brief Groups a random set of replacements by file path. Replacements +/// related to the same file entry are put into the same vector. +std::map<std::string, Replacements> +groupReplacementsByFile(const Replacements &Replaces); /// \brief Merges two sets of replacements with the second set referring to the /// code after applying the first set. Within both 'First' and 'Second', diff --git a/include/clang/Tooling/FixIt.h b/include/clang/Tooling/FixIt.h new file mode 100644 index 000000000000..e2259d4357bc --- /dev/null +++ b/include/clang/Tooling/FixIt.h @@ -0,0 +1,72 @@ +//===--- FixIt.h - FixIt Hint utilities -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements functions to ease source rewriting from AST-nodes. +// +// Example swapping A and B expressions: +// +// Expr *A, *B; +// tooling::fixit::createReplacement(*A, *B); +// tooling::fixit::createReplacement(*B, *A); +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_FIXIT_H +#define LLVM_CLANG_TOOLING_FIXIT_H + +#include "clang/AST/ASTContext.h" + +namespace clang { +namespace tooling { +namespace fixit { + +namespace internal { +StringRef getText(SourceRange Range, const ASTContext &Context); + +/// \brief Returns the SourceRange of a SourceRange. This identity function is +/// used by the following template abstractions. +inline SourceRange getSourceRange(const SourceRange &Range) { return Range; } + +/// \brief Returns the SourceRange of the token at Location \p Loc. +inline SourceRange getSourceRange(const SourceLocation &Loc) { + return SourceRange(Loc); +} + +/// \brief Returns the SourceRange of an given Node. \p Node is typically a +/// 'Stmt', 'Expr' or a 'Decl'. +template <typename T> SourceRange getSourceRange(const T &Node) { + return Node.getSourceRange(); +} +} // end namespace internal + +// \brief Returns a textual representation of \p Node. +template <typename T> +StringRef getText(const T &Node, const ASTContext &Context) { + return internal::getText(internal::getSourceRange(Node), Context); +} + +// \brief Returns a FixItHint to remove \p Node. +// TODO: Add support for related syntactical elements (i.e. comments, ...). +template <typename T> FixItHint createRemoval(const T &Node) { + return FixItHint::CreateRemoval(internal::getSourceRange(Node)); +} + +// \brief Returns a FixItHint to replace \p Destination by \p Source. +template <typename D, typename S> +FixItHint createReplacement(const D &Destination, const S &Source, + const ASTContext &Context) { + return FixItHint::CreateReplacement(internal::getSourceRange(Destination), + getText(Source, Context)); +} + +} // end namespace fixit +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_FIXINT_H diff --git a/include/clang/Tooling/Refactoring.h b/include/clang/Tooling/Refactoring.h index 54deff6e3661..06ec8b087629 100644 --- a/include/clang/Tooling/Refactoring.h +++ b/include/clang/Tooling/Refactoring.h @@ -68,6 +68,24 @@ private: Replacements Replace; }; +/// \brief Groups \p Replaces by the file path and applies each group of +/// Replacements on the related file in \p Rewriter. In addition to applying +/// given Replacements, this function also formats the changed code. +/// +/// \pre Replacements must be conflict-free. +/// +/// Replacement applications happen independently of the success of other +/// applications. +/// +/// \param[in] Replaces Replacements to apply. +/// \param[in] Rewrite The `Rewritter` to apply replacements on. +/// \param[in] Style The style name used for reformatting. See ```getStyle``` in +/// "include/clang/Format/Format.h" for all possible style forms. +/// +/// \returns true if all replacements applied and formatted. false otherwise. +bool formatAndApplyAllReplacements(const Replacements &Replaces, + Rewriter &Rewrite, StringRef Style = "file"); + } // end namespace tooling } // end namespace clang diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h index b7a9b25acd0e..ca232f409831 100644 --- a/include/clang/Tooling/Tooling.h +++ b/include/clang/Tooling/Tooling.h @@ -163,6 +163,8 @@ typedef std::vector<std::pair<std::string, std::string>> FileContentMappings; /// \param Code C++ code. /// \param Args Additional flags to pass on. /// \param FileName The file name which 'Code' will be mapped as. +/// \param ToolName The name of the binary running the tool. Standard library +/// header paths will be resolved relative to this. /// \param PCHContainerOps The PCHContainerOperations for loading and creating /// clang modules. /// @@ -170,6 +172,7 @@ typedef std::vector<std::pair<std::string, std::string>> FileContentMappings; bool runToolOnCodeWithArgs( clang::FrontendAction *ToolAction, const Twine &Code, const std::vector<std::string> &Args, const Twine &FileName = "input.cc", + const Twine &ToolName = "clang-tool", std::shared_ptr<PCHContainerOperations> PCHContainerOps = std::make_shared<PCHContainerOperations>(), const FileContentMappings &VirtualMappedFiles = FileContentMappings()); @@ -192,13 +195,15 @@ buildASTFromCode(const Twine &Code, const Twine &FileName = "input.cc", /// \param Code C++ code. /// \param Args Additional flags to pass on. /// \param FileName The file name which 'Code' will be mapped as. +/// \param ToolName The name of the binary running the tool. Standard library +/// header paths will be resolved relative to this. /// \param PCHContainerOps The PCHContainerOperations for loading and creating /// clang modules. /// /// \return The resulting AST or null if an error occurred. std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs( const Twine &Code, const std::vector<std::string> &Args, - const Twine &FileName = "input.cc", + const Twine &FileName = "input.cc", const Twine &ToolName = "clang-tool", std::shared_ptr<PCHContainerOperations> PCHContainerOps = std::make_shared<PCHContainerOperations>()); |