r310853 - [rename] Introduce symbol occurrences
Alex L via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 14 09:21:01 PDT 2017
It's an NFC, thus untested.
On 14 August 2017 at 17:19, Alex Lorenz via cfe-commits <
cfe-commits at lists.llvm.org> wrote:
> Author: arphaman
> Date: Mon Aug 14 09:19:24 2017
> New Revision: 310853
>
> URL: http://llvm.org/viewvc/llvm-project?rev=310853&view=rev
> Log:
> [rename] Introduce symbol occurrences
>
> Symbol occurrences store the results of local rename and will also be used
> for
> the global, indexed rename results. Their kind is used to determine
> whether they
> should be renamed automatically or not. They can be converted to a set of
> AtomicChanges as well.
>
> Differential Revision: https://reviews.llvm.org/D36156
>
> Added:
> cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolName.h
> cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h
> cfe/trunk/lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp
> Modified:
> cfe/trunk/include/clang/Tooling/Refactoring/Rename/RenamingAction.h
> cfe/trunk/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h
> cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt
> cfe/trunk/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
> cfe/trunk/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
>
> Modified: cfe/trunk/include/clang/Tooling/Refactoring/Rename/
> RenamingAction.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Tooling/Refactoring/Rename/RenamingAction.h?rev=
> 310853&r1=310852&r2=310853&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Tooling/Refactoring/Rename/RenamingAction.h
> (original)
> +++ cfe/trunk/include/clang/Tooling/Refactoring/Rename/RenamingAction.h
> Mon Aug 14 09:19:24 2017
> @@ -16,6 +16,9 @@
> #define LLVM_CLANG_TOOLING_REFACTOR_RENAME_RENAMING_ACTION_H
>
> #include "clang/Tooling/Refactoring.h"
> +#include "clang/Tooling/Refactoring/AtomicChange.h"
> +#include "clang/Tooling/Refactoring/Rename/SymbolOccurrences.h"
> +#include "llvm/Support/Error.h"
>
> namespace clang {
> class ASTConsumer;
> @@ -42,6 +45,13 @@ private:
> bool PrintLocations;
> };
>
> +/// Returns source replacements that correspond to the rename of the given
> +/// symbol occurrences.
> +llvm::Expected<std::vector<AtomicChange>>
> +createRenameReplacements(const SymbolOccurrences &Occurrences,
> + const SourceManager &SM,
> + ArrayRef<StringRef> NewNameStrings);
> +
> /// Rename all symbols identified by the given USRs.
> class QualifiedRenamingAction {
> public:
>
> Added: cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolName.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Tooling/Refactoring/Rename/SymbolName.h?rev=310853&view=auto
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolName.h
> (added)
> +++ cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolName.h Mon
> Aug 14 09:19:24 2017
> @@ -0,0 +1,49 @@
> +//===--- SymbolName.h - Clang refactoring library
> -------------------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +#ifndef LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_NAME_H
> +#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_NAME_H
> +
> +#include "clang/Basic/LLVM.h"
> +#include "llvm/ADT/ArrayRef.h"
> +#include "llvm/ADT/SmallVector.h"
> +#include "llvm/ADT/StringRef.h"
> +
> +namespace clang {
> +namespace tooling {
> +
> +/// A name of a symbol.
> +///
> +/// Symbol's name can be composed of multiple strings. For example,
> Objective-C
> +/// methods can contain multiple argument lables:
> +///
> +/// \code
> +/// - (void) myMethodNamePiece: (int)x anotherNamePieces:(int)y;
> +/// // ^~ string 0 ~~~~~ ^~ string 1 ~~~~~
> +/// \endcode
> +class SymbolName {
> +public:
> + SymbolName(StringRef Name) {
> + // While empty symbol names are valid (Objective-C selectors can have
> empty
> + // name pieces), occurrences Objective-C selectors are created using
> an
> + // array of strings instead of just one string.
> + assert(!Name.empty() && "Invalid symbol name!");
> + this->Name.push_back(Name.str());
> + }
> +
> + ArrayRef<std::string> getNamePieces() const { return Name; }
> +
> +private:
> + llvm::SmallVector<std::string, 1> Name;
> +};
> +
> +} // end namespace tooling
> +} // end namespace clang
> +
> +#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_NAME_H
>
> Added: cfe/trunk/include/clang/Tooling/Refactoring/Rename/
> SymbolOccurrences.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Tooling/Refactoring/Rename/SymbolOccurrences.h?rev=310853&view=auto
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h
> (added)
> +++ cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h
> Mon Aug 14 09:19:24 2017
> @@ -0,0 +1,91 @@
> +//===--- SymbolOccurrences.h - Clang refactoring library
> ------------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +#ifndef LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_OCCURRENCES_H
> +#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_OCCURRENCES_H
> +
> +#include "clang/Basic/LLVM.h"
> +#include "clang/Basic/SourceLocation.h"
> +#include "llvm/ADT/ArrayRef.h"
> +#include "llvm/ADT/StringRef.h"
> +#include <vector>
> +
> +namespace clang {
> +namespace tooling {
> +
> +class SymbolName;
> +
> +/// An occurrence of a symbol in the source.
> +///
> +/// Occurrences can have difference kinds, that describe whether this
> occurrence
> +/// is an exact semantic match, or whether this is a weaker textual match
> that's
> +/// not guaranteed to represent the exact declaration.
> +///
> +/// A single occurrence of a symbol can span more than one source range.
> For
> +/// example, Objective-C selectors can contain multiple argument labels:
> +///
> +/// \code
> +/// [object selectorPiece1: ... selectorPiece2: ...];
> +/// // ^~~ range 0 ~~ ^~~ range 1 ~~
> +/// \endcode
> +///
> +/// We have to replace the text in both range 0 and range 1 when renaming
> the
> +/// Objective-C method 'selectorPiece1:selectorPiece2'.
> +class SymbolOccurrence {
> +public:
> + enum OccurrenceKind {
> + /// This occurrence is an exact match and can be renamed
> automatically.
> + ///
> + /// Note:
> + /// Symbol occurrences in macro arguments that expand to different
> + /// declarations get marked as exact matches, and thus the renaming
> engine
> + /// will rename them e.g.:
> + ///
> + /// \code
> + /// #define MACRO(x) x + ns::x
> + /// int foo(int var) {
> + /// return MACRO(var); // var is renamed automatically here when
> + /// // either var or ns::var is renamed.
> + /// };
> + /// \endcode
> + ///
> + /// The user will have to fix their code manually after performing
> such a
> + /// rename.
> + /// FIXME: The rename verifier should notify user about this issue.
> + MatchingSymbol
> + };
> +
> + SymbolOccurrence(const SymbolName &Name, OccurrenceKind Kind,
> + ArrayRef<SourceLocation> Locations);
> +
> + SymbolOccurrence(SymbolOccurrence &&) = default;
> + SymbolOccurrence &operator=(SymbolOccurrence &&) = default;
> +
> + OccurrenceKind getKind() const { return Kind; }
> +
> + ArrayRef<SourceRange> getNameRanges() const {
> + if (MultipleRanges) {
> + return llvm::makeArrayRef(MultipleRanges.get(),
> + RangeOrNumRanges.getBegin().
> getRawEncoding());
> + }
> + return RangeOrNumRanges;
> + }
> +
> +private:
> + OccurrenceKind Kind;
> + std::unique_ptr<SourceRange[]> MultipleRanges;
> + SourceRange RangeOrNumRanges;
> +};
> +
> +using SymbolOccurrences = std::vector<SymbolOccurrence>;
> +
> +} // end namespace tooling
> +} // end namespace clang
> +
> +#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_OCCURRENCES_H
>
> Modified: cfe/trunk/include/clang/Tooling/Refactoring/Rename/
> USRLocFinder.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Tooling/Refactoring/Rename/USRLocFinder.h?rev=
> 310853&r1=310852&r2=310853&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h
> (original)
> +++ cfe/trunk/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h Mon
> Aug 14 09:19:24 2017
> @@ -19,6 +19,7 @@
> #include "clang/AST/AST.h"
> #include "clang/Tooling/Core/Replacement.h"
> #include "clang/Tooling/Refactoring/AtomicChange.h"
> +#include "clang/Tooling/Refactoring/Rename/SymbolOccurrences.h"
> #include "llvm/ADT/StringRef.h"
> #include <string>
> #include <vector>
> @@ -38,10 +39,13 @@ std::vector<tooling::AtomicChange>
> createRenameAtomicChanges(llvm::ArrayRef<std::string> USRs,
> llvm::StringRef NewName, Decl
> *TranslationUnitDecl);
>
> -// FIXME: make this an AST matcher. Wouldn't that be awesome??? I agree!
> -std::vector<SourceLocation>
> -getLocationsOfUSRs(const std::vector<std::string> &USRs,
> - llvm::StringRef PrevName, Decl *Decl);
> +/// Finds the symbol occurrences for the symbol that's identified by the
> given
> +/// USR set.
> +///
> +/// \return SymbolOccurrences that can be converted to AtomicChanges when
> +/// renaming.
> +SymbolOccurrences getOccurrencesOfUSRs(ArrayRef<std::string> USRs,
> + StringRef PrevName, Decl *Decl);
>
> } // end namespace tooling
> } // end namespace clang
>
> Modified: cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/
> Refactoring/CMakeLists.txt?rev=310853&r1=310852&r2=310853&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt (original)
> +++ cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt Mon Aug 14 09:19:24
> 2017
> @@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS Support)
> add_clang_library(clangToolingRefactor
> AtomicChange.cpp
> Rename/RenamingAction.cpp
> + Rename/SymbolOccurrences.cpp
> Rename/USRFinder.cpp
> Rename/USRFindingAction.cpp
> Rename/USRLocFinder.cpp
>
> Modified: cfe/trunk/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/
> Refactoring/Rename/RenamingAction.cpp?rev=310853&
> r1=310852&r2=310853&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Tooling/Refactoring/Rename/RenamingAction.cpp (original)
> +++ cfe/trunk/lib/Tooling/Refactoring/Rename/RenamingAction.cpp Mon Aug
> 14 09:19:24 2017
> @@ -24,6 +24,7 @@
> #include "clang/Tooling/Refactoring.h"
> #include "clang/Tooling/Refactoring/Rename/USRLocFinder.h"
> #include "clang/Tooling/Tooling.h"
> +#include "llvm/ADT/STLExtras.h"
> #include <string>
> #include <vector>
>
> @@ -32,6 +33,45 @@ using namespace llvm;
> namespace clang {
> namespace tooling {
>
> +Expected<std::vector<AtomicChange>>
> +createRenameReplacements(const SymbolOccurrences &Occurrences,
> + const SourceManager &SM,
> + ArrayRef<StringRef> NewNameStrings) {
> + // FIXME: A true local rename can use just one AtomicChange.
> + std::vector<AtomicChange> Changes;
> + for (const auto &Occurrence : Occurrences) {
> + ArrayRef<SourceRange> Ranges = Occurrence.getNameRanges();
> + assert(NewNameStrings.size() == Ranges.size() &&
> + "Mismatching number of ranges and name pieces");
> + AtomicChange Change(SM, Ranges[0].getBegin());
> + for (const auto &Range : llvm::enumerate(Ranges)) {
> + auto Error =
> + Change.replace(SM, CharSourceRange::getCharRange(
> Range.value()),
> + NewNameStrings[Range.index()]);
> + if (Error)
> + return std::move(Error);
> + }
> + Changes.push_back(std::move(Change));
> + }
> + return Changes;
> +}
> +
> +/// Takes each atomic change and inserts its replacements into the set of
> +/// replacements that belong to the appropriate file.
> +static void convertChangesToFileReplacements(
> + ArrayRef<AtomicChange> AtomicChanges,
> + std::map<std::string, tooling::Replacements> *FileToReplaces) {
> + for (const auto &AtomicChange : AtomicChanges) {
> + for (const auto &Replace : AtomicChange.getReplacements()) {
> + llvm::Error Err = (*FileToReplaces)[Replace.
> getFilePath()].add(Replace);
> + if (Err) {
> + llvm::errs() << "Renaming failed in " << Replace.getFilePath() <<
> "! "
> + << llvm::toString(std::move(Err)) << "\n";
> + }
> + }
> + }
> +}
> +
> class RenamingASTConsumer : public ASTConsumer {
> public:
> RenamingASTConsumer(
> @@ -52,29 +92,29 @@ public:
> const std::string &PrevName,
> const std::vector<std::string> &USRs) {
> const SourceManager &SourceMgr = Context.getSourceManager();
> - std::vector<SourceLocation> RenamingCandidates;
> - std::vector<SourceLocation> NewCandidates;
>
> - NewCandidates = tooling::getLocationsOfUSRs(
> + SymbolOccurrences Occurrences = tooling::getOccurrencesOfUSRs(
> USRs, PrevName, Context.getTranslationUnitDecl());
> - RenamingCandidates.insert(RenamingCandidates.end(),
> NewCandidates.begin(),
> - NewCandidates.end());
> -
> - unsigned PrevNameLen = PrevName.length();
> - for (const auto &Loc : RenamingCandidates) {
> - if (PrintLocations) {
> - FullSourceLoc FullLoc(Loc, SourceMgr);
> - errs() << "clang-rename: renamed at: " <<
> SourceMgr.getFilename(Loc)
> + if (PrintLocations) {
> + for (const auto &Occurrence : Occurrences) {
> + FullSourceLoc FullLoc(Occurrence.getNameRanges()[0].getBegin(),
> + SourceMgr);
> + errs() << "clang-rename: renamed at: " <<
> SourceMgr.getFilename(FullLoc)
> << ":" << FullLoc.getSpellingLineNumber() << ":"
> << FullLoc.getSpellingColumnNumber() << "\n";
> }
> - // FIXME: better error handling.
> - tooling::Replacement Replace(SourceMgr, Loc, PrevNameLen, NewName);
> - llvm::Error Err = FileToReplaces[Replace.
> getFilePath()].add(Replace);
> - if (Err)
> - llvm::errs() << "Renaming failed in " << Replace.getFilePath() <<
> "! "
> - << llvm::toString(std::move(Err)) << "\n";
> }
> + // FIXME: Support multi-piece names.
> + // FIXME: better error handling (propagate error out).
> + StringRef NewNameRef = NewName;
> + Expected<std::vector<AtomicChange>> Change =
> + createRenameReplacements(Occurrences, SourceMgr, NewNameRef);
> + if (!Change) {
> + llvm::errs() << "Failed to create renaming replacements for '" <<
> PrevName
> + << "'! " << llvm::toString(Change.takeError()) <<
> "\n";
> + return;
> + }
> + convertChangesToFileReplacements(*Change, &FileToReplaces);
> }
>
> private:
> @@ -103,15 +143,7 @@ public:
> // ready.
> auto AtomicChanges = tooling::createRenameAtomicChanges(
> USRList[I], NewNames[I], Context.getTranslationUnitDecl());
> - for (const auto AtomicChange : AtomicChanges) {
> - for (const auto &Replace : AtomicChange.getReplacements()) {
> - llvm::Error Err = FileToReplaces[Replace.
> getFilePath()].add(Replace);
> - if (Err) {
> - llvm::errs() << "Renaming failed in " << Replace.getFilePath()
> - << "! " << llvm::toString(std::move(Err)) <<
> "\n";
> - }
> - }
> - }
> + convertChangesToFileReplacements(AtomicChanges, &FileToReplaces);
> }
> }
>
>
> Added: cfe/trunk/lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/
> Refactoring/Rename/SymbolOccurrences.cpp?rev=310853&view=auto
> ============================================================
> ==================
> --- cfe/trunk/lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp (added)
> +++ cfe/trunk/lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp Mon
> Aug 14 09:19:24 2017
> @@ -0,0 +1,37 @@
> +//===--- SymbolOccurrences.cpp - Clang refactoring library
> ----------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +#include "clang/Tooling/Refactoring/Rename/SymbolOccurrences.h"
> +#include "clang/Tooling/Refactoring/Rename/SymbolName.h"
> +#include "llvm/ADT/STLExtras.h"
> +
> +using namespace clang;
> +using namespace tooling;
> +
> +SymbolOccurrence::SymbolOccurrence(const SymbolName &Name,
> OccurrenceKind Kind,
> + ArrayRef<SourceLocation> Locations)
> + : Kind(Kind) {
> + ArrayRef<std::string> NamePieces = Name.getNamePieces();
> + assert(Locations.size() == NamePieces.size() &&
> + "mismatching number of locations and lengths");
> + assert(!Locations.empty() && "no locations");
> + if (Locations.size() == 1) {
> + RangeOrNumRanges = SourceRange(
> + Locations[0], Locations[0].getLocWithOffset(
> NamePieces[0].size()));
> + return;
> + }
> + MultipleRanges = llvm::make_unique<SourceRange[]>(Locations.size());
> + RangeOrNumRanges.setBegin(
> + SourceLocation::getFromRawEncoding(Locations.size()));
> + for (const auto &Loc : llvm::enumerate(Locations)) {
> + MultipleRanges[Loc.index()] = SourceRange(
> + Loc.value(),
> + Loc.value().getLocWithOffset(NamePieces[Loc.index()].size()));
> + }
> +}
>
> Modified: cfe/trunk/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/
> Refactoring/Rename/USRLocFinder.cpp?rev=310853&
> r1=310852&r2=310853&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp (original)
> +++ cfe/trunk/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp Mon Aug 14
> 09:19:24 2017
> @@ -23,6 +23,7 @@
> #include "clang/Lex/Lexer.h"
> #include "clang/Tooling/Core/Lookup.h"
> #include "clang/Tooling/Refactoring/RecursiveSymbolVisitor.h"
> +#include "clang/Tooling/Refactoring/Rename/SymbolName.h"
> #include "clang/Tooling/Refactoring/Rename/USRFinder.h"
> #include "llvm/ADT/StringRef.h"
> #include "llvm/Support/Casting.h"
> @@ -68,11 +69,9 @@ public:
>
> // Non-visitors:
>
> - // \brief Returns a list of unique locations. Duplicate or overlapping
> - // locations are erroneous and should be reported!
> - const std::vector<clang::SourceLocation> &getLocationsFound() const {
> - return LocationsFound;
> - }
> + /// \brief Returns a set of unique symbol occurrences. Duplicate or
> + /// overlapping occurrences are erroneous and should be reported!
> + SymbolOccurrences takeOccurrences() { return std::move(Occurrences); }
>
> private:
> void checkAndAddLocation(SourceLocation Loc) {
> @@ -82,17 +81,18 @@ private:
> StringRef TokenName =
> Lexer::getSourceText(CharSourceRange::getTokenRange(BeginLoc,
> EndLoc),
> Context.getSourceManager(),
> Context.getLangOpts());
> - size_t Offset = TokenName.find(PrevName);
> + size_t Offset = TokenName.find(PrevName.getNamePieces()[0]);
>
> // The token of the source location we find actually has the old
> // name.
> if (Offset != StringRef::npos)
> - LocationsFound.push_back(BeginLoc.getLocWithOffset(Offset));
> + Occurrences.emplace_back(PrevName, SymbolOccurrence::
> MatchingSymbol,
> + BeginLoc.getLocWithOffset(Offset));
> }
>
> const std::set<std::string> USRSet;
> - const std::string PrevName;
> - std::vector<clang::SourceLocation> LocationsFound;
> + const SymbolName PrevName;
> + SymbolOccurrences Occurrences;
> const ASTContext &Context;
> };
>
> @@ -391,12 +391,11 @@ private:
>
> } // namespace
>
> -std::vector<SourceLocation>
> -getLocationsOfUSRs(const std::vector<std::string> &USRs, StringRef
> PrevName,
> - Decl *Decl) {
> +SymbolOccurrences getOccurrencesOfUSRs(ArrayRef<std::string> USRs,
> + StringRef PrevName, Decl *Decl) {
> USRLocFindingASTVisitor Visitor(USRs, PrevName, Decl->getASTContext());
> Visitor.TraverseDecl(Decl);
> - return Visitor.getLocationsFound();
> + return Visitor.takeOccurrences();
> }
>
> std::vector<tooling::AtomicChange>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170814/430b4434/attachment-0001.html>
More information about the cfe-commits
mailing list