diff options
author | thegeorg <thegeorg@yandex-team.com> | 2024-03-13 13:58:24 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.com> | 2024-03-13 14:11:53 +0300 |
commit | 11a895b7e15d1c5a1f52706396b82e3f9db953cb (patch) | |
tree | fabc6d883b0f946151f61ae7865cee9f529a1fdd /contrib/libs/clang16/include/clang/Tooling/Refactoring | |
parent | 9685917341315774aad5733b1793b1e533a88bbb (diff) | |
download | ydb-11a895b7e15d1c5a1f52706396b82e3f9db953cb.tar.gz |
Export clang-format16 via ydblib project
6e6be3a95868fde888d801b7590af4044049563f
Diffstat (limited to 'contrib/libs/clang16/include/clang/Tooling/Refactoring')
23 files changed, 2181 insertions, 0 deletions
diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/ASTSelection.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/ASTSelection.h new file mode 100644 index 0000000000..6ae38a98cc --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/ASTSelection.h @@ -0,0 +1,167 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- ASTSelection.h - Clang refactoring library -----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_ASTSELECTION_H +#define LLVM_CLANG_TOOLING_REFACTORING_ASTSELECTION_H + +#include "clang/AST/ASTTypeTraits.h" +#include "clang/AST/Stmt.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/Support/raw_ostream.h" +#include <optional> +#include <vector> + +namespace clang { + +class ASTContext; + +namespace tooling { + +enum class SourceSelectionKind { + /// A node that's not selected. + None, + + /// A node that's considered to be selected because the whole selection range + /// is inside of its source range. + ContainsSelection, + /// A node that's considered to be selected because the start of the selection + /// range is inside its source range. + ContainsSelectionStart, + /// A node that's considered to be selected because the end of the selection + /// range is inside its source range. + ContainsSelectionEnd, + + /// A node that's considered to be selected because the node is entirely in + /// the selection range. + InsideSelection, +}; + +/// Represents a selected AST node. +/// +/// AST selection is represented using a tree of \c SelectedASTNode. The tree +/// follows the top-down shape of the actual AST. Each selected node has +/// a selection kind. The kind might be none as the node itself might not +/// actually be selected, e.g. a statement in macro whose child is in a macro +/// argument. +struct SelectedASTNode { + DynTypedNode Node; + SourceSelectionKind SelectionKind; + std::vector<SelectedASTNode> Children; + + SelectedASTNode(const DynTypedNode &Node, SourceSelectionKind SelectionKind) + : Node(Node), SelectionKind(SelectionKind) {} + SelectedASTNode(SelectedASTNode &&) = default; + SelectedASTNode &operator=(SelectedASTNode &&) = default; + + void dump(llvm::raw_ostream &OS = llvm::errs()) const; + + using ReferenceType = std::reference_wrapper<const SelectedASTNode>; +}; + +/// Traverses the given ASTContext and creates a tree of selected AST nodes. +/// +/// \returns std::nullopt if no nodes are selected in the AST, or a selected AST +/// node that corresponds to the TranslationUnitDecl otherwise. +std::optional<SelectedASTNode> findSelectedASTNodes(const ASTContext &Context, + SourceRange SelectionRange); + +/// An AST selection value that corresponds to a selection of a set of +/// statements that belong to one body of code (like one function). +/// +/// For example, the following selection in the source. +/// +/// \code +/// void function() { +/// // selection begin: +/// int x = 0; +/// { +/// // selection end +/// x = 1; +/// } +/// x = 2; +/// } +/// \endcode +/// +/// Would correspond to a code range selection of statements "int x = 0" +/// and the entire compound statement that follows it. +/// +/// A \c CodeRangeASTSelection value stores references to the full +/// \c SelectedASTNode tree and should not outlive it. +class CodeRangeASTSelection { +public: + CodeRangeASTSelection(CodeRangeASTSelection &&) = default; + CodeRangeASTSelection &operator=(CodeRangeASTSelection &&) = default; + + /// Returns the parent hierarchy (top to bottom) for the selected nodes. + ArrayRef<SelectedASTNode::ReferenceType> getParents() { return Parents; } + + /// Returns the number of selected statements. + size_t size() const { + if (!AreChildrenSelected) + return 1; + return SelectedNode.get().Children.size(); + } + + const Stmt *operator[](size_t I) const { + if (!AreChildrenSelected) { + assert(I == 0 && "Invalid index"); + return SelectedNode.get().Node.get<Stmt>(); + } + return SelectedNode.get().Children[I].Node.get<Stmt>(); + } + + /// Returns true when a selected code range is in a function-like body + /// of code, like a function, method or a block. + /// + /// This function can be used to test against selected expressions that are + /// located outside of a function, e.g. global variable initializers, default + /// argument values, or even template arguments. + /// + /// Use the \c getFunctionLikeNearestParent to get the function-like parent + /// declaration. + bool isInFunctionLikeBodyOfCode() const; + + /// Returns the nearest function-like parent declaration or null if such + /// declaration doesn't exist. + const Decl *getFunctionLikeNearestParent() const; + + static std::optional<CodeRangeASTSelection> + create(SourceRange SelectionRange, const SelectedASTNode &ASTSelection); + +private: + CodeRangeASTSelection(SelectedASTNode::ReferenceType SelectedNode, + ArrayRef<SelectedASTNode::ReferenceType> Parents, + bool AreChildrenSelected) + : SelectedNode(SelectedNode), Parents(Parents.begin(), Parents.end()), + AreChildrenSelected(AreChildrenSelected) {} + + /// The reference to the selected node (or reference to the selected + /// child nodes). + SelectedASTNode::ReferenceType SelectedNode; + /// The parent hierarchy (top to bottom) for the selected noe. + llvm::SmallVector<SelectedASTNode::ReferenceType, 8> Parents; + /// True only when the children of the selected node are actually selected. + bool AreChildrenSelected; +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_ASTSELECTION_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/AtomicChange.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/AtomicChange.h new file mode 100644 index 0000000000..f5da7ec742 --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/AtomicChange.h @@ -0,0 +1,203 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- AtomicChange.h - AtomicChange class --------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines AtomicChange which is used to create a set of source +// changes, e.g. replacements and header insertions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_ATOMICCHANGE_H +#define LLVM_CLANG_TOOLING_REFACTORING_ATOMICCHANGE_H + +#include "clang/Basic/SourceManager.h" +#include "clang/Format/Format.h" +#include "clang/Tooling/Core/Replacement.h" +#include "llvm/ADT/Any.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" + +namespace clang { +namespace tooling { + +/// An atomic change is used to create and group a set of source edits, +/// e.g. replacements or header insertions. Edits in an AtomicChange should be +/// related, e.g. replacements for the same type reference and the corresponding +/// header insertion/deletion. +/// +/// An AtomicChange is uniquely identified by a key and will either be fully +/// applied or not applied at all. +/// +/// Calling setError on an AtomicChange stores the error message and marks it as +/// bad, i.e. none of its source edits will be applied. +class AtomicChange { +public: + /// Creates an atomic change around \p KeyPosition with the key being a + /// concatenation of the file name and the offset of \p KeyPosition. + /// \p KeyPosition should be the location of the key syntactical element that + /// is being changed, e.g. the call to a refactored method. + AtomicChange(const SourceManager &SM, SourceLocation KeyPosition); + + AtomicChange(const SourceManager &SM, SourceLocation KeyPosition, + llvm::Any Metadata); + + /// Creates an atomic change for \p FilePath with a customized key. + AtomicChange(llvm::StringRef FilePath, llvm::StringRef Key) + : Key(Key), FilePath(FilePath) {} + + AtomicChange(AtomicChange &&) = default; + AtomicChange(const AtomicChange &) = default; + + AtomicChange &operator=(AtomicChange &&) = default; + AtomicChange &operator=(const AtomicChange &) = default; + + bool operator==(const AtomicChange &Other) const; + + /// Returns the atomic change as a YAML string. + std::string toYAMLString(); + + /// Converts a YAML-encoded automic change to AtomicChange. + static AtomicChange convertFromYAML(llvm::StringRef YAMLContent); + + /// Returns the key of this change, which is a concatenation of the + /// file name and offset of the key position. + const std::string &getKey() const { return Key; } + + /// Returns the path of the file containing this atomic change. + const std::string &getFilePath() const { return FilePath; } + + /// If this change could not be created successfully, e.g. because of + /// conflicts among replacements, use this to set an error description. + /// Thereby, places that cannot be fixed automatically can be gathered when + /// applying changes. + void setError(llvm::StringRef Error) { this->Error = std::string(Error); } + + /// Returns whether an error has been set on this list. + bool hasError() const { return !Error.empty(); } + + /// Returns the error message or an empty string if it does not exist. + const std::string &getError() const { return Error; } + + /// Adds a replacement that replaces the given Range with + /// ReplacementText. + /// \returns An llvm::Error carrying ReplacementError on error. + llvm::Error replace(const SourceManager &SM, const CharSourceRange &Range, + llvm::StringRef ReplacementText); + + /// Adds a replacement that replaces range [Loc, Loc+Length) with + /// \p Text. + /// \returns An llvm::Error carrying ReplacementError on error. + llvm::Error replace(const SourceManager &SM, SourceLocation Loc, + unsigned Length, llvm::StringRef Text); + + /// Adds a replacement that inserts \p Text at \p Loc. If this + /// insertion conflicts with an existing insertion (at the same position), + /// this will be inserted before/after the existing insertion depending on + /// \p InsertAfter. Users should use `replace` with `Length=0` instead if they + /// do not want conflict resolving by default. If the conflicting replacement + /// is not an insertion, an error is returned. + /// + /// \returns An llvm::Error carrying ReplacementError on error. + llvm::Error insert(const SourceManager &SM, SourceLocation Loc, + llvm::StringRef Text, bool InsertAfter = true); + + /// Adds a header into the file that contains the key position. + /// Header can be in angle brackets or double quotation marks. By default + /// (header is not quoted), header will be surrounded with double quotes. + void addHeader(llvm::StringRef Header); + + /// Removes a header from the file that contains the key position. + void removeHeader(llvm::StringRef Header); + + /// Returns a const reference to existing replacements. + const Replacements &getReplacements() const { return Replaces; } + + Replacements &getReplacements() { return Replaces; } + + llvm::ArrayRef<std::string> getInsertedHeaders() const { + return InsertedHeaders; + } + + llvm::ArrayRef<std::string> getRemovedHeaders() const { + return RemovedHeaders; + } + + const llvm::Any &getMetadata() const { return Metadata; } + +private: + AtomicChange() {} + + AtomicChange(std::string Key, std::string FilePath, std::string Error, + std::vector<std::string> InsertedHeaders, + std::vector<std::string> RemovedHeaders, + clang::tooling::Replacements Replaces); + + // This uniquely identifies an AtomicChange. + std::string Key; + std::string FilePath; + std::string Error; + std::vector<std::string> InsertedHeaders; + std::vector<std::string> RemovedHeaders; + tooling::Replacements Replaces; + + // This field stores metadata which is ignored for the purposes of applying + // edits to source, but may be useful for other consumers of AtomicChanges. In + // particular, consumers can use this to direct how they want to consume each + // edit. + llvm::Any Metadata; +}; + +using AtomicChanges = std::vector<AtomicChange>; + +// Defines specs for applying changes. +struct ApplyChangesSpec { + // If true, cleans up redundant/erroneous code around changed code with + // clang-format's cleanup functionality, e.g. redundant commas around deleted + // parameter or empty namespaces introduced by deletions. + bool Cleanup = true; + + format::FormatStyle Style = format::getNoStyle(); + + // Options for selectively formatting changes with clang-format: + // kAll: Format all changed lines. + // kNone: Don't format anything. + // kViolations: Format lines exceeding the `ColumnLimit` in `Style`. + enum FormatOption { kAll, kNone, kViolations }; + + FormatOption Format = kNone; +}; + +/// Applies all AtomicChanges in \p Changes to the \p Code. +/// +/// This completely ignores the file path in each change and replaces them with +/// \p FilePath, i.e. callers are responsible for ensuring all changes are for +/// the same file. +/// +/// \returns The changed code if all changes are applied successfully; +/// otherwise, an llvm::Error carrying llvm::StringError is returned (the Error +/// message can be converted to string with `llvm::toString()` and the +/// error_code should be ignored). +llvm::Expected<std::string> +applyAtomicChanges(llvm::StringRef FilePath, llvm::StringRef Code, + llvm::ArrayRef<AtomicChange> Changes, + const ApplyChangesSpec &Spec); + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_ATOMICCHANGE_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/Extract/Extract.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Extract/Extract.h new file mode 100644 index 0000000000..16627c19ca --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Extract/Extract.h @@ -0,0 +1,65 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- Extract.h - Clang refactoring library ----------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_EXTRACT_EXTRACT_H +#define LLVM_CLANG_TOOLING_REFACTORING_EXTRACT_EXTRACT_H + +#include "clang/Tooling/Refactoring/ASTSelection.h" +#include "clang/Tooling/Refactoring/RefactoringActionRules.h" +#include <optional> + +namespace clang { +namespace tooling { + +/// An "Extract Function" refactoring moves code into a new function that's +/// then called from the place where the original code was. +class ExtractFunction final : public SourceChangeRefactoringRule { +public: + /// Initiates the extract function refactoring operation. + /// + /// \param Code The selected set of statements. + /// \param DeclName The name of the extract function. If None, + /// "extracted" is used. + static Expected<ExtractFunction> + initiate(RefactoringRuleContext &Context, CodeRangeASTSelection Code, + std::optional<std::string> DeclName); + + static const RefactoringDescriptor &describe(); + +private: + ExtractFunction(CodeRangeASTSelection Code, + std::optional<std::string> DeclName) + : Code(std::move(Code)), + DeclName(DeclName ? std::move(*DeclName) : "extracted") {} + + Expected<AtomicChanges> + createSourceReplacements(RefactoringRuleContext &Context) override; + + CodeRangeASTSelection Code; + + // FIXME: Account for naming collisions: + // - error when name is specified by user. + // - rename to "extractedN" when name is implicit. + std::string DeclName; +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_EXTRACT_EXTRACT_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/Extract/SourceExtraction.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Extract/SourceExtraction.h new file mode 100644 index 0000000000..03a173e23f --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Extract/SourceExtraction.h @@ -0,0 +1,62 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- SourceExtraction.cpp - Clang refactoring library -----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_EXTRACT_SOURCEEXTRACTION_H +#define LLVM_CLANG_TOOLING_REFACTORING_EXTRACT_SOURCEEXTRACTION_H + +#include "clang/Basic/LLVM.h" + +namespace clang { + +class LangOptions; +class SourceManager; +class SourceRange; +class Stmt; + +namespace tooling { + +/// Determines which semicolons should be inserted during extraction. +class ExtractionSemicolonPolicy { +public: + bool isNeededInExtractedFunction() const { + return IsNeededInExtractedFunction; + } + + bool isNeededInOriginalFunction() const { return IsNeededInOriginalFunction; } + + /// Returns the semicolon insertion policy that is needed for extraction of + /// the given statement from the given source range. + static ExtractionSemicolonPolicy compute(const Stmt *S, + SourceRange &ExtractedRange, + const SourceManager &SM, + const LangOptions &LangOpts); + +private: + ExtractionSemicolonPolicy(bool IsNeededInExtractedFunction, + bool IsNeededInOriginalFunction) + : IsNeededInExtractedFunction(IsNeededInExtractedFunction), + IsNeededInOriginalFunction(IsNeededInOriginalFunction) {} + bool IsNeededInExtractedFunction; + bool IsNeededInOriginalFunction; +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_EXTRACT_SOURCEEXTRACTION_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/Lookup.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Lookup.h new file mode 100644 index 0000000000..0a47f78aa9 --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Lookup.h @@ -0,0 +1,61 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- Lookup.h - Framework for clang refactoring tools --*- C++ -*------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines helper methods for clang tools performing name lookup. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_LOOKUP_H +#define LLVM_CLANG_TOOLING_REFACTORING_LOOKUP_H + +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" +#include <string> + +namespace clang { + +class DeclContext; +class NamedDecl; +class NestedNameSpecifier; + +namespace tooling { + +/// Emulate a lookup to replace one nested name specifier with another using as +/// few additional namespace qualifications as possible. +/// +/// This does not perform a full C++ lookup so ADL will not work. +/// +/// \param Use The nested name to be replaced. +/// \param UseLoc The location of name to be replaced. +/// \param UseContext The context in which the nested name is contained. This +/// will be used to minimize namespace qualifications. +/// \param FromDecl The declaration to which the nested name points. +/// \param ReplacementString The replacement nested name. Must be fully +/// qualified including a leading "::". +/// \returns The new name to be inserted in place of the current nested name. +std::string replaceNestedName(const NestedNameSpecifier *Use, + SourceLocation UseLoc, + const DeclContext *UseContext, + const NamedDecl *FromDecl, + StringRef ReplacementString); + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_LOOKUP_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h new file mode 100644 index 0000000000..09ce6217b4 --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h @@ -0,0 +1,164 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- RecursiveSymbolVisitor.h - Clang refactoring library -------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// A wrapper class around \c RecursiveASTVisitor that visits each +/// occurrences of a named symbol. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_RECURSIVESYMBOLVISITOR_H +#define LLVM_CLANG_TOOLING_REFACTORING_RECURSIVESYMBOLVISITOR_H + +#include "clang/AST/AST.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Lex/Lexer.h" + +namespace clang { +namespace tooling { + +/// Traverses the AST and visits the occurrence of each named symbol in the +/// given nodes. +template <typename T> +class RecursiveSymbolVisitor + : public RecursiveASTVisitor<RecursiveSymbolVisitor<T>> { + using BaseType = RecursiveASTVisitor<RecursiveSymbolVisitor<T>>; + +public: + RecursiveSymbolVisitor(const SourceManager &SM, const LangOptions &LangOpts) + : SM(SM), LangOpts(LangOpts) {} + + bool visitSymbolOccurrence(const NamedDecl *ND, + ArrayRef<SourceRange> NameRanges) { + return true; + } + + // Declaration visitors: + + bool VisitNamedDecl(const NamedDecl *D) { + return isa<CXXConversionDecl>(D) ? true : visit(D, D->getLocation()); + } + + bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD) { + for (const auto *Initializer : CD->inits()) { + // Ignore implicit initializers. + if (!Initializer->isWritten()) + continue; + if (const FieldDecl *FD = Initializer->getMember()) { + if (!visit(FD, Initializer->getSourceLocation(), + Lexer::getLocForEndOfToken(Initializer->getSourceLocation(), + 0, SM, LangOpts))) + return false; + } + } + return true; + } + + // Expression visitors: + + bool VisitDeclRefExpr(const DeclRefExpr *Expr) { + return visit(Expr->getFoundDecl(), Expr->getLocation()); + } + + bool VisitMemberExpr(const MemberExpr *Expr) { + return visit(Expr->getFoundDecl().getDecl(), Expr->getMemberLoc()); + } + + bool VisitOffsetOfExpr(const OffsetOfExpr *S) { + for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) { + const OffsetOfNode &Component = S->getComponent(I); + if (Component.getKind() == OffsetOfNode::Field) { + if (!visit(Component.getField(), Component.getEndLoc())) + return false; + } + // FIXME: Try to resolve dependent field references. + } + return true; + } + + // Other visitors: + + bool VisitTypeLoc(const TypeLoc Loc) { + const SourceLocation TypeBeginLoc = Loc.getBeginLoc(); + const SourceLocation TypeEndLoc = + Lexer::getLocForEndOfToken(TypeBeginLoc, 0, SM, LangOpts); + if (const auto *TemplateTypeParm = + dyn_cast<TemplateTypeParmType>(Loc.getType())) { + if (!visit(TemplateTypeParm->getDecl(), TypeBeginLoc, TypeEndLoc)) + return false; + } + if (const auto *TemplateSpecType = + dyn_cast<TemplateSpecializationType>(Loc.getType())) { + if (!visit(TemplateSpecType->getTemplateName().getAsTemplateDecl(), + TypeBeginLoc, TypeEndLoc)) + return false; + } + if (const Type *TP = Loc.getTypePtr()) { + if (TP->getTypeClass() == clang::Type::Record) + return visit(TP->getAsCXXRecordDecl(), TypeBeginLoc, TypeEndLoc); + } + return true; + } + + bool VisitTypedefTypeLoc(TypedefTypeLoc TL) { + const SourceLocation TypeEndLoc = + Lexer::getLocForEndOfToken(TL.getBeginLoc(), 0, SM, LangOpts); + return visit(TL.getTypedefNameDecl(), TL.getBeginLoc(), TypeEndLoc); + } + + bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { + // The base visitor will visit NNSL prefixes, so we should only look at + // the current NNS. + if (NNS) { + const NamespaceDecl *ND = NNS.getNestedNameSpecifier()->getAsNamespace(); + if (!visit(ND, NNS.getLocalBeginLoc(), NNS.getLocalEndLoc())) + return false; + } + return BaseType::TraverseNestedNameSpecifierLoc(NNS); + } + + bool VisitDesignatedInitExpr(const DesignatedInitExpr *E) { + for (const DesignatedInitExpr::Designator &D : E->designators()) { + if (D.isFieldDesignator() && D.getField()) { + const FieldDecl *Decl = D.getField(); + if (!visit(Decl, D.getFieldLoc(), D.getFieldLoc())) + return false; + } + } + return true; + } + +private: + const SourceManager &SM; + const LangOptions &LangOpts; + + bool visit(const NamedDecl *ND, SourceLocation BeginLoc, + SourceLocation EndLoc) { + return static_cast<T *>(this)->visitSymbolOccurrence( + ND, SourceRange(BeginLoc, EndLoc)); + } + bool visit(const NamedDecl *ND, SourceLocation Loc) { + return visit(ND, Loc, Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts)); + } +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_RECURSIVESYMBOLVISITOR_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringAction.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringAction.h new file mode 100644 index 0000000000..28d30fdf90 --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringAction.h @@ -0,0 +1,74 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- RefactoringAction.h - Clang refactoring library ------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTION_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTION_H + +#include "clang/Basic/LLVM.h" +#include "clang/Tooling/Refactoring/RefactoringActionRules.h" +#include <vector> + +namespace clang { +namespace tooling { + +/// A refactoring action is a class that defines a set of related refactoring +/// action rules. These rules get grouped under a common umbrella - a single +/// clang-refactor subcommand. +/// +/// A subclass of \c RefactoringAction is responsible for creating the set of +/// grouped refactoring action rules that represent one refactoring operation. +/// Although the rules in one action may have a number of different +/// implementations, they should strive to produce a similar result. It should +/// be easy for users to identify which refactoring action produced the result +/// regardless of which refactoring action rule was used. +/// +/// The distinction between actions and rules enables the creation of action +/// that uses very different rules, for example: +/// - local vs global: a refactoring operation like +/// "add missing switch cases" can be applied to one switch when it's +/// selected in an editor, or to all switches in a project when an enum +/// constant is added to an enum. +/// - tool vs editor: some refactoring operation can be initiated in the +/// editor when a declaration is selected, or in a tool when the name of +/// the declaration is passed using a command-line argument. +class RefactoringAction { +public: + virtual ~RefactoringAction() {} + + /// Returns the name of the subcommand that's used by clang-refactor for this + /// action. + virtual StringRef getCommand() const = 0; + + virtual StringRef getDescription() const = 0; + + RefactoringActionRules createActiveActionRules(); + +protected: + /// Returns a set of refactoring actions rules that are defined by this + /// action. + virtual RefactoringActionRules createActionRules() const = 0; +}; + +/// Returns the list of all the available refactoring actions. +std::vector<std::unique_ptr<RefactoringAction>> createRefactoringActions(); + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTION_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringActionRule.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringActionRule.h new file mode 100644 index 0000000000..2bc21b0714 --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringActionRule.h @@ -0,0 +1,82 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- RefactoringActionRule.h - Clang refactoring library -------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULE_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULE_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/StringRef.h" + +namespace clang { +namespace tooling { + +class RefactoringOptionVisitor; +class RefactoringResultConsumer; +class RefactoringRuleContext; + +struct RefactoringDescriptor { + /// A unique identifier for the specific refactoring. + StringRef Name; + /// A human readable title for the refactoring. + StringRef Title; + /// A human readable description of what the refactoring does. + StringRef Description; +}; + +/// A common refactoring action rule interface that defines the 'invoke' +/// function that performs the refactoring operation (either fully or +/// partially). +class RefactoringActionRuleBase { +public: + virtual ~RefactoringActionRuleBase() {} + + /// Initiates and performs a specific refactoring action. + /// + /// The specific rule will invoke an appropriate \c handle method on a + /// consumer to propagate the result of the refactoring action. + virtual void invoke(RefactoringResultConsumer &Consumer, + RefactoringRuleContext &Context) = 0; + + /// Returns the structure that describes the refactoring. + // static const RefactoringDescriptor &describe() = 0; +}; + +/// A refactoring action rule is a wrapper class around a specific refactoring +/// action rule (SourceChangeRefactoringRule, etc) that, in addition to invoking +/// the action, describes the requirements that determine when the action can be +/// initiated. +class RefactoringActionRule : public RefactoringActionRuleBase { +public: + /// Returns true when the rule has a source selection requirement that has + /// to be fulfilled before refactoring can be performed. + virtual bool hasSelectionRequirement() = 0; + + /// Traverses each refactoring option used by the rule and invokes the + /// \c visit callback in the consumer for each option. + /// + /// Options are visited in the order of use, e.g. if a rule has two + /// requirements that use options, the options from the first requirement + /// are visited before the options in the second requirement. + virtual void visitRefactoringOptions(RefactoringOptionVisitor &Visitor) = 0; +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULE_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h new file mode 100644 index 0000000000..438d80433b --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h @@ -0,0 +1,133 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- RefactoringActionRuleRequirements.h - Clang refactoring library --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULEREQUIREMENTS_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULEREQUIREMENTS_H + +#include "clang/Basic/LLVM.h" +#include "clang/Tooling/Refactoring/ASTSelection.h" +#include "clang/Tooling/Refactoring/RefactoringDiagnostic.h" +#include "clang/Tooling/Refactoring/RefactoringOption.h" +#include "clang/Tooling/Refactoring/RefactoringRuleContext.h" +#include "llvm/Support/Error.h" +#include <type_traits> + +namespace clang { +namespace tooling { + +/// A refactoring action rule requirement determines when a refactoring action +/// rule can be invoked. The rule can be invoked only when all of the +/// requirements are satisfied. +/// +/// Subclasses must implement the +/// 'Expected<T> evaluate(RefactoringRuleContext &) const' member function. +/// \c T is used to determine the return type that is passed to the +/// refactoring rule's constructor. +/// For example, the \c SourceRangeSelectionRequirement subclass defines +/// 'Expected<SourceRange> evaluate(RefactoringRuleContext &Context) const' +/// function. When this function returns a non-error value, the resulting +/// source range is passed to the specific refactoring action rule +/// constructor (provided all other requirements are satisfied). +class RefactoringActionRuleRequirement { + // Expected<T> evaluate(RefactoringRuleContext &Context) const; +}; + +/// A base class for any requirement that expects some part of the source to be +/// selected in an editor (or the refactoring tool with the -selection option). +class SourceSelectionRequirement : public RefactoringActionRuleRequirement {}; + +/// A selection requirement that is satisfied when any portion of the source +/// text is selected. +class SourceRangeSelectionRequirement : public SourceSelectionRequirement { +public: + Expected<SourceRange> evaluate(RefactoringRuleContext &Context) const { + if (Context.getSelectionRange().isValid()) + return Context.getSelectionRange(); + return Context.createDiagnosticError(diag::err_refactor_no_selection); + } +}; + +/// An AST selection requirement is satisfied when any portion of the AST +/// overlaps with the selection range. +/// +/// The requirement will be evaluated only once during the initiation and +/// search of matching refactoring action rules. +class ASTSelectionRequirement : public SourceRangeSelectionRequirement { +public: + Expected<SelectedASTNode> evaluate(RefactoringRuleContext &Context) const; +}; + +/// A selection requirement that is satisfied when the selection range overlaps +/// with a number of neighbouring statements in the AST. The statemenst must be +/// contained in declaration like a function. The selection range must be a +/// non-empty source selection (i.e. cursors won't be accepted). +/// +/// The requirement will be evaluated only once during the initiation and search +/// of matching refactoring action rules. +/// +/// \see CodeRangeASTSelection +class CodeRangeASTSelectionRequirement : public ASTSelectionRequirement { +public: + Expected<CodeRangeASTSelection> + evaluate(RefactoringRuleContext &Context) const; +}; + +/// A base class for any requirement that requires some refactoring options. +class RefactoringOptionsRequirement : public RefactoringActionRuleRequirement { +public: + virtual ~RefactoringOptionsRequirement() {} + + /// Returns the set of refactoring options that are used when evaluating this + /// requirement. + virtual ArrayRef<std::shared_ptr<RefactoringOption>> + getRefactoringOptions() const = 0; +}; + +/// A requirement that evaluates to the value of the given \c OptionType when +/// the \c OptionType is a required option. When the \c OptionType is an +/// optional option, the requirement will evaluate to \c None if the option is +/// not specified or to an appropriate value otherwise. +template <typename OptionType> +class OptionRequirement : public RefactoringOptionsRequirement { +public: + OptionRequirement() : Opt(createRefactoringOption<OptionType>()) {} + + ArrayRef<std::shared_ptr<RefactoringOption>> + getRefactoringOptions() const final { + return Opt; + } + + Expected<typename OptionType::ValueType> + evaluate(RefactoringRuleContext &) const { + return static_cast<OptionType *>(Opt.get())->getValue(); + } + +private: + /// The partially-owned option. + /// + /// The ownership of the option is shared among the different requirements + /// because the same option can be used by multiple rules in one refactoring + /// action. + std::shared_ptr<RefactoringOption> Opt; +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULEREQUIREMENTS_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringActionRules.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringActionRules.h new file mode 100644 index 0000000000..5ef11aee8e --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringActionRules.h @@ -0,0 +1,104 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- RefactoringActionRules.h - Clang refactoring library -------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULES_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULES_H + +#include "clang/Tooling/Refactoring/RefactoringActionRule.h" +#include "clang/Tooling/Refactoring/RefactoringActionRulesInternal.h" + +namespace clang { +namespace tooling { + +/// Creates a new refactoring action rule that constructs and invokes the +/// \c RuleType rule when all of the requirements are satisfied. +/// +/// This function takes in a list of values whose type derives from +/// \c RefactoringActionRuleRequirement. These values describe the initiation +/// requirements that have to be satisfied by the refactoring engine before +/// the provided action rule can be constructed and invoked. The engine +/// verifies that the requirements are satisfied by evaluating them (using the +/// 'evaluate' member function) and checking that the results don't contain +/// any errors. Once all requirements are satisfied, the provided refactoring +/// rule is constructed by passing in the values returned by the requirements' +/// evaluate functions as arguments to the constructor. The rule is then invoked +/// immediately after construction. +/// +/// The separation of requirements, their evaluation and the invocation of the +/// refactoring action rule allows the refactoring clients to: +/// - Disable refactoring action rules whose requirements are not supported. +/// - Gather the set of options and define a command-line / visual interface +/// that allows users to input these options without ever invoking the +/// action. +template <typename RuleType, typename... RequirementTypes> +std::unique_ptr<RefactoringActionRule> +createRefactoringActionRule(const RequirementTypes &... Requirements); + +/// A set of refactoring action rules that should have unique initiation +/// requirements. +using RefactoringActionRules = + std::vector<std::unique_ptr<RefactoringActionRule>>; + +/// A type of refactoring action rule that produces source replacements in the +/// form of atomic changes. +/// +/// This action rule is typically used for local refactorings that replace +/// source in a single AST unit. +class SourceChangeRefactoringRule : public RefactoringActionRuleBase { +public: + void invoke(RefactoringResultConsumer &Consumer, + RefactoringRuleContext &Context) final { + Expected<AtomicChanges> Changes = createSourceReplacements(Context); + if (!Changes) + Consumer.handleError(Changes.takeError()); + else + Consumer.handle(std::move(*Changes)); + } + +private: + virtual Expected<AtomicChanges> + createSourceReplacements(RefactoringRuleContext &Context) = 0; +}; + +/// A type of refactoring action rule that finds a set of symbol occurrences +/// that reference a particular symbol. +/// +/// This action rule is typically used for an interactive rename that allows +/// users to specify the new name and the set of selected occurrences during +/// the refactoring. +class FindSymbolOccurrencesRefactoringRule : public RefactoringActionRuleBase { +public: + void invoke(RefactoringResultConsumer &Consumer, + RefactoringRuleContext &Context) final { + Expected<SymbolOccurrences> Occurrences = findSymbolOccurrences(Context); + if (!Occurrences) + Consumer.handleError(Occurrences.takeError()); + else + Consumer.handle(std::move(*Occurrences)); + } + +private: + virtual Expected<SymbolOccurrences> + findSymbolOccurrences(RefactoringRuleContext &Context) = 0; +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULES_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h new file mode 100644 index 0000000000..2b6213da4b --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h @@ -0,0 +1,168 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- RefactoringActionRulesInternal.h - Clang refactoring library -----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULESINTERNAL_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULESINTERNAL_H + +#include "clang/Basic/LLVM.h" +#include "clang/Tooling/Refactoring/RefactoringActionRule.h" +#include "clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h" +#include "clang/Tooling/Refactoring/RefactoringResultConsumer.h" +#include "clang/Tooling/Refactoring/RefactoringRuleContext.h" +#include "llvm/Support/Error.h" +#include <type_traits> + +namespace clang { +namespace tooling { +namespace internal { + +inline llvm::Error findError() { return llvm::Error::success(); } + +inline void ignoreError() {} + +template <typename FirstT, typename... RestT> +void ignoreError(Expected<FirstT> &First, Expected<RestT> &... Rest) { + if (!First) + llvm::consumeError(First.takeError()); + ignoreError(Rest...); +} + +/// Scans the tuple and returns a valid \c Error if any of the values are +/// invalid. +template <typename FirstT, typename... RestT> +llvm::Error findError(Expected<FirstT> &First, Expected<RestT> &... Rest) { + if (!First) { + ignoreError(Rest...); + return First.takeError(); + } + return findError(Rest...); +} + +template <typename RuleType, typename... RequirementTypes, size_t... Is> +void invokeRuleAfterValidatingRequirements( + RefactoringResultConsumer &Consumer, RefactoringRuleContext &Context, + const std::tuple<RequirementTypes...> &Requirements, + std::index_sequence<Is...>) { + // Check if the requirements we're interested in can be evaluated. + auto Values = + std::make_tuple(std::get<Is>(Requirements).evaluate(Context)...); + auto Err = findError(std::get<Is>(Values)...); + if (Err) + return Consumer.handleError(std::move(Err)); + // Construct the target action rule by extracting the evaluated + // requirements from Expected<> wrappers and then run it. + auto Rule = + RuleType::initiate(Context, std::move((*std::get<Is>(Values)))...); + if (!Rule) + return Consumer.handleError(Rule.takeError()); + Rule->invoke(Consumer, Context); +} + +inline void visitRefactoringOptionsImpl(RefactoringOptionVisitor &) {} + +/// Scans the list of requirements in a rule and visits all the refactoring +/// options that are used by all the requirements. +template <typename FirstT, typename... RestT> +void visitRefactoringOptionsImpl(RefactoringOptionVisitor &Visitor, + const FirstT &First, const RestT &... Rest) { + struct OptionGatherer { + RefactoringOptionVisitor &Visitor; + + void operator()(const RefactoringOptionsRequirement &Requirement) { + for (const auto &Option : Requirement.getRefactoringOptions()) + Option->passToVisitor(Visitor); + } + void operator()(const RefactoringActionRuleRequirement &) {} + }; + (OptionGatherer{Visitor})(First); + return visitRefactoringOptionsImpl(Visitor, Rest...); +} + +template <typename... RequirementTypes, size_t... Is> +void visitRefactoringOptions( + RefactoringOptionVisitor &Visitor, + const std::tuple<RequirementTypes...> &Requirements, + std::index_sequence<Is...>) { + visitRefactoringOptionsImpl(Visitor, std::get<Is>(Requirements)...); +} + +/// A type trait that returns true when the given type list has at least one +/// type whose base is the given base type. +template <typename Base, typename First, typename... Rest> +struct HasBaseOf : std::conditional_t<HasBaseOf<Base, First>::value || + HasBaseOf<Base, Rest...>::value, + std::true_type, std::false_type> {}; + +template <typename Base, typename T> +struct HasBaseOf<Base, T> : std::is_base_of<Base, T> {}; + +/// A type trait that returns true when the given type list contains types that +/// derive from Base. +template <typename Base, typename First, typename... Rest> +struct AreBaseOf : std::conditional_t<AreBaseOf<Base, First>::value && + AreBaseOf<Base, Rest...>::value, + std::true_type, std::false_type> {}; + +template <typename Base, typename T> +struct AreBaseOf<Base, T> : std::is_base_of<Base, T> {}; + +} // end namespace internal + +template <typename RuleType, typename... RequirementTypes> +std::unique_ptr<RefactoringActionRule> +createRefactoringActionRule(const RequirementTypes &... Requirements) { + static_assert(std::is_base_of<RefactoringActionRuleBase, RuleType>::value, + "Expected a refactoring action rule type"); + static_assert(internal::AreBaseOf<RefactoringActionRuleRequirement, + RequirementTypes...>::value, + "Expected a list of refactoring action rules"); + + class Rule final : public RefactoringActionRule { + public: + Rule(std::tuple<RequirementTypes...> Requirements) + : Requirements(Requirements) {} + + void invoke(RefactoringResultConsumer &Consumer, + RefactoringRuleContext &Context) override { + internal::invokeRuleAfterValidatingRequirements<RuleType>( + Consumer, Context, Requirements, + std::index_sequence_for<RequirementTypes...>()); + } + + bool hasSelectionRequirement() override { + return internal::HasBaseOf<SourceSelectionRequirement, + RequirementTypes...>::value; + } + + void visitRefactoringOptions(RefactoringOptionVisitor &Visitor) override { + internal::visitRefactoringOptions( + Visitor, Requirements, + std::index_sequence_for<RequirementTypes...>()); + } + private: + std::tuple<RequirementTypes...> Requirements; + }; + + return std::make_unique<Rule>(std::make_tuple(Requirements...)); +} + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULESINTERNAL_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h new file mode 100644 index 0000000000..881e71a743 --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h @@ -0,0 +1,25 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- RefactoringDiagnostic.h - ------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGDIAGNOSTIC_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGDIAGNOSTIC_H + +#include "clang/Basic/DiagnosticRefactoring.h" + +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGDIAGNOSTIC_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringOption.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringOption.h new file mode 100644 index 0000000000..33b704d385 --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringOption.h @@ -0,0 +1,74 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- RefactoringOption.h - Clang refactoring library ------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTION_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTION_H + +#include "clang/Basic/LLVM.h" +#include <memory> +#include <type_traits> + +namespace clang { +namespace tooling { + +class RefactoringOptionVisitor; + +/// A refactoring option is an interface that describes a value that +/// has an impact on the outcome of a refactoring. +/// +/// Refactoring options can be specified using command-line arguments when +/// the clang-refactor tool is used. +class RefactoringOption { +public: + virtual ~RefactoringOption() {} + + /// Returns the name of the refactoring option. + /// + /// Each refactoring option must have a unique name. + virtual StringRef getName() const = 0; + + virtual StringRef getDescription() const = 0; + + /// True when this option must be specified before invoking the refactoring + /// action. + virtual bool isRequired() const = 0; + + /// Invokes the \c visit method in the option consumer that's appropriate + /// for the option's value type. + /// + /// For example, if the option stores a string value, this method will + /// invoke the \c visit method with a reference to an std::string value. + virtual void passToVisitor(RefactoringOptionVisitor &Visitor) = 0; +}; + +/// Constructs a refactoring option of the given type. +/// +/// The ownership of options is shared among requirements that use it because +/// one option can be used by multiple rules in a refactoring action. +template <typename OptionType> +std::shared_ptr<OptionType> createRefactoringOption() { + static_assert(std::is_base_of<RefactoringOption, OptionType>::value, + "invalid option type"); + return std::make_shared<OptionType>(); +} + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTION_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h new file mode 100644 index 0000000000..5a8d7dee14 --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h @@ -0,0 +1,74 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- RefactoringOptionVisitor.h - Clang refactoring library -----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTIONVISITOR_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTIONVISITOR_H + +#include "clang/Basic/LLVM.h" +#include <optional> +#include <type_traits> + +namespace clang { +namespace tooling { + +class RefactoringOption; + +/// An interface that declares functions that handle different refactoring +/// option types. +/// +/// A valid refactoring option type must have a corresponding \c visit +/// declaration in this interface. +class RefactoringOptionVisitor { +public: + virtual ~RefactoringOptionVisitor() {} + + virtual void visit(const RefactoringOption &Opt, + std::optional<std::string> &Value) = 0; +}; + +namespace traits { +namespace internal { + +template <typename T> struct HasHandle { +private: + template <typename ClassT> + static auto check(ClassT *) -> typename std::is_same< + decltype(std::declval<RefactoringOptionVisitor>().visit( + std::declval<RefactoringOption>(), + *std::declval<std::optional<T> *>())), + void>::type; + + template <typename> static std::false_type check(...); + +public: + using Type = decltype(check<RefactoringOptionVisitor>(nullptr)); +}; + +} // end namespace internal + +/// A type trait that returns true iff the given type is a type that can be +/// stored in a refactoring option. +template <typename T> +struct IsValidOptionType : internal::HasHandle<T>::Type {}; + +} // end namespace traits +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTIONVISITOR_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringOptions.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringOptions.h new file mode 100644 index 0000000000..fb1f71e9e6 --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringOptions.h @@ -0,0 +1,69 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- RefactoringOptions.h - Clang refactoring library -----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTIONS_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTIONS_H + +#include "clang/Basic/LLVM.h" +#include "clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h" +#include "clang/Tooling/Refactoring/RefactoringOption.h" +#include "clang/Tooling/Refactoring/RefactoringOptionVisitor.h" +#include "llvm/Support/Error.h" +#include <optional> +#include <type_traits> + +namespace clang { +namespace tooling { + +/// A refactoring option that stores a value of type \c T. +template <typename T, + typename = std::enable_if_t<traits::IsValidOptionType<T>::value>> +class OptionalRefactoringOption : public RefactoringOption { +public: + void passToVisitor(RefactoringOptionVisitor &Visitor) final { + Visitor.visit(*this, Value); + } + + bool isRequired() const override { return false; } + + using ValueType = std::optional<T>; + + const ValueType &getValue() const { return Value; } + +protected: + std::optional<T> Value; +}; + +/// A required refactoring option that stores a value of type \c T. +template <typename T, + typename = std::enable_if_t<traits::IsValidOptionType<T>::value>> +class RequiredRefactoringOption : public OptionalRefactoringOption<T> { +public: + using ValueType = T; + + const ValueType &getValue() const { + return *OptionalRefactoringOption<T>::Value; + } + bool isRequired() const final { return true; } +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTIONS_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h new file mode 100644 index 0000000000..fe6d95ccef --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h @@ -0,0 +1,62 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- RefactoringResultConsumer.h - Clang refactoring library ----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGRESULTCONSUMER_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGRESULTCONSUMER_H + +#include "clang/Basic/LLVM.h" +#include "clang/Tooling/Refactoring/AtomicChange.h" +#include "clang/Tooling/Refactoring/Rename/SymbolOccurrences.h" +#include "llvm/Support/Error.h" + +namespace clang { +namespace tooling { + +/// An abstract interface that consumes the various refactoring results that can +/// be produced by refactoring actions. +/// +/// A valid refactoring result must be handled by a \c handle method. +class RefactoringResultConsumer { +public: + virtual ~RefactoringResultConsumer() {} + + /// Handles an initiation or an invication error. An initiation error typically + /// has a \c DiagnosticError payload that describes why initiation failed. + virtual void handleError(llvm::Error Err) = 0; + + /// Handles the source replacements that are produced by a refactoring action. + virtual void handle(AtomicChanges SourceReplacements) { + defaultResultHandler(); + } + + /// Handles the symbol occurrences that are found by an interactive + /// refactoring action. + virtual void handle(SymbolOccurrences Occurrences) { defaultResultHandler(); } + +private: + void defaultResultHandler() { + handleError(llvm::make_error<llvm::StringError>( + "unsupported refactoring result", llvm::inconvertibleErrorCode())); + } +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGRESULTCONSUMER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringRuleContext.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringRuleContext.h new file mode 100644 index 0000000000..73a9652b1e --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/RefactoringRuleContext.h @@ -0,0 +1,100 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- RefactoringRuleContext.h - Clang refactoring library -------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGRULECONTEXT_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGRULECONTEXT_H + +#include "clang/Basic/DiagnosticError.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Tooling/Refactoring/ASTSelection.h" + +namespace clang { + +class ASTContext; + +namespace tooling { + +/// The refactoring rule context stores all of the inputs that might be needed +/// by a refactoring action rule. It can create the specialized +/// \c ASTRefactoringOperation or \c PreprocessorRefactoringOperation values +/// that can be used by the refactoring action rules. +/// +/// The following inputs are stored by the operation: +/// +/// - SourceManager: a reference to a valid source manager. +/// +/// - SelectionRange: an optional source selection ranges that can be used +/// to represent a selection in an editor. +class RefactoringRuleContext { +public: + RefactoringRuleContext(const SourceManager &SM) : SM(SM) {} + + const SourceManager &getSources() const { return SM; } + + /// Returns the current source selection range as set by the + /// refactoring engine. Can be invalid. + SourceRange getSelectionRange() const { return SelectionRange; } + + void setSelectionRange(SourceRange R) { SelectionRange = R; } + + bool hasASTContext() const { return AST; } + + ASTContext &getASTContext() const { + assert(AST && "no AST!"); + return *AST; + } + + void setASTContext(ASTContext &Context) { AST = &Context; } + + /// Creates an llvm::Error value that contains a diagnostic. + /// + /// The errors should not outlive the context. + llvm::Error createDiagnosticError(SourceLocation Loc, unsigned DiagID) { + return DiagnosticError::create(Loc, PartialDiagnostic(DiagID, DiagStorage)); + } + + llvm::Error createDiagnosticError(unsigned DiagID) { + return createDiagnosticError(SourceLocation(), DiagID); + } + + void setASTSelection(std::unique_ptr<SelectedASTNode> Node) { + ASTNodeSelection = std::move(Node); + } + +private: + /// The source manager for the translation unit / file on which a refactoring + /// action might operate on. + const SourceManager &SM; + /// An optional source selection range that's commonly used to represent + /// a selection in an editor. + SourceRange SelectionRange; + /// An optional AST for the translation unit on which a refactoring action + /// might operate on. + ASTContext *AST = nullptr; + /// The allocator for diagnostics. + PartialDiagnostic::DiagStorageAllocator DiagStorage; + + // FIXME: Remove when memoized. + std::unique_ptr<SelectedASTNode> ASTNodeSelection; +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGRULECONTEXT_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/RenamingAction.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/RenamingAction.h new file mode 100644 index 0000000000..cab565a95f --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/RenamingAction.h @@ -0,0 +1,133 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- RenamingAction.h - Clang refactoring library ---------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Provides an action to rename every symbol at a point. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_RENAME_RENAMINGACTION_H +#define LLVM_CLANG_TOOLING_REFACTORING_RENAME_RENAMINGACTION_H + +#include "clang/Tooling/Refactoring.h" +#include "clang/Tooling/Refactoring/AtomicChange.h" +#include "clang/Tooling/Refactoring/RefactoringActionRules.h" +#include "clang/Tooling/Refactoring/RefactoringOptions.h" +#include "clang/Tooling/Refactoring/Rename/SymbolOccurrences.h" +#include "llvm/Support/Error.h" + +namespace clang { +class ASTConsumer; + +namespace tooling { + +class RenamingAction { +public: + RenamingAction(const std::vector<std::string> &NewNames, + const std::vector<std::string> &PrevNames, + const std::vector<std::vector<std::string>> &USRList, + std::map<std::string, tooling::Replacements> &FileToReplaces, + bool PrintLocations = false) + : NewNames(NewNames), PrevNames(PrevNames), USRList(USRList), + FileToReplaces(FileToReplaces), PrintLocations(PrintLocations) {} + + std::unique_ptr<ASTConsumer> newASTConsumer(); + +private: + const std::vector<std::string> &NewNames, &PrevNames; + const std::vector<std::vector<std::string>> &USRList; + std::map<std::string, tooling::Replacements> &FileToReplaces; + bool PrintLocations; +}; + +class RenameOccurrences final : public SourceChangeRefactoringRule { +public: + static Expected<RenameOccurrences> initiate(RefactoringRuleContext &Context, + SourceRange SelectionRange, + std::string NewName); + + static const RefactoringDescriptor &describe(); + + const NamedDecl *getRenameDecl() const; + +private: + RenameOccurrences(const NamedDecl *ND, std::string NewName) + : ND(ND), NewName(std::move(NewName)) {} + + Expected<AtomicChanges> + createSourceReplacements(RefactoringRuleContext &Context) override; + + const NamedDecl *ND; + std::string NewName; +}; + +class QualifiedRenameRule final : public SourceChangeRefactoringRule { +public: + static Expected<QualifiedRenameRule> initiate(RefactoringRuleContext &Context, + std::string OldQualifiedName, + std::string NewQualifiedName); + + static const RefactoringDescriptor &describe(); + +private: + QualifiedRenameRule(const NamedDecl *ND, + std::string NewQualifiedName) + : ND(ND), NewQualifiedName(std::move(NewQualifiedName)) {} + + Expected<AtomicChanges> + createSourceReplacements(RefactoringRuleContext &Context) override; + + // A NamedDecl which identifies the symbol being renamed. + const NamedDecl *ND; + // The new qualified name to change the symbol to. + std::string NewQualifiedName; +}; + +/// 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, const SymbolName &NewName); + +/// Rename all symbols identified by the given USRs. +class QualifiedRenamingAction { +public: + QualifiedRenamingAction( + const std::vector<std::string> &NewNames, + const std::vector<std::vector<std::string>> &USRList, + std::map<std::string, tooling::Replacements> &FileToReplaces) + : NewNames(NewNames), USRList(USRList), FileToReplaces(FileToReplaces) {} + + std::unique_ptr<ASTConsumer> newASTConsumer(); + +private: + /// New symbol names. + const std::vector<std::string> &NewNames; + + /// A list of USRs. Each element represents USRs of a symbol being renamed. + const std::vector<std::vector<std::string>> &USRList; + + /// A file path to replacements map. + std::map<std::string, tooling::Replacements> &FileToReplaces; +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_RENAME_RENAMINGACTION_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/SymbolName.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/SymbolName.h new file mode 100644 index 0000000000..26915b6e4e --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/SymbolName.h @@ -0,0 +1,59 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- SymbolName.h - Clang refactoring library -------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_RENAME_SYMBOLNAME_H +#define LLVM_CLANG_TOOLING_REFACTORING_RENAME_SYMBOLNAME_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 labels: +/// +/// \code +/// - (void) myMethodNamePiece: (int)x anotherNamePieces:(int)y; +/// // ^~ string 0 ~~~~~ ^~ string 1 ~~~~~ +/// \endcode +class SymbolName { +public: + explicit 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_REFACTORING_RENAME_SYMBOLNAME_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h new file mode 100644 index 0000000000..e57212248c --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h @@ -0,0 +1,102 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- SymbolOccurrences.h - Clang refactoring library ------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_RENAME_SYMBOLOCCURRENCES_H +#define LLVM_CLANG_TOOLING_REFACTORING_RENAME_SYMBOLOCCURRENCES_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::ArrayRef(MultipleRanges.get(), NumRanges); + return SingleRange; + } + +private: + OccurrenceKind Kind; + std::unique_ptr<SourceRange[]> MultipleRanges; + union { + SourceRange SingleRange; + unsigned NumRanges; + }; +}; + +using SymbolOccurrences = std::vector<SymbolOccurrence>; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_RENAME_SYMBOLOCCURRENCES_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/USRFinder.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/USRFinder.h new file mode 100644 index 0000000000..197c7bdab9 --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/USRFinder.h @@ -0,0 +1,60 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- USRFinder.h - Clang refactoring library --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Methods for determining the USR of a symbol at a location in source +/// code. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRFINDER_H +#define LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRFINDER_H + +#include "clang/AST/AST.h" +#include "clang/AST/ASTContext.h" +#include <string> +#include <vector> + +namespace clang { + +class ASTContext; +class Decl; +class SourceLocation; +class NamedDecl; + +namespace tooling { + +// Given an AST context and a point, returns a NamedDecl identifying the symbol +// at the point. Returns null if nothing is found at the point. +const NamedDecl *getNamedDeclAt(const ASTContext &Context, + const SourceLocation Point); + +// Given an AST context and a fully qualified name, returns a NamedDecl +// identifying the symbol with a matching name. Returns null if nothing is +// found for the name. +const NamedDecl *getNamedDeclFor(const ASTContext &Context, + const std::string &Name); + +// Converts a Decl into a USR. +std::string getUSRForDecl(const Decl *Decl); + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRFINDER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h new file mode 100644 index 0000000000..dbdaed6ebc --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h @@ -0,0 +1,77 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- USRFindingAction.h - Clang refactoring library -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Provides an action to find all relevant USRs at a point. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRFINDINGACTION_H +#define LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRFINDINGACTION_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/ArrayRef.h" + +#include <string> +#include <vector> + +namespace clang { +class ASTConsumer; +class ASTContext; +class NamedDecl; + +namespace tooling { + +/// Returns the canonical declaration that best represents a symbol that can be +/// renamed. +/// +/// The following canonicalization rules are currently used: +/// +/// - A constructor is canonicalized to its class. +/// - A destructor is canonicalized to its class. +const NamedDecl *getCanonicalSymbolDeclaration(const NamedDecl *FoundDecl); + +/// Returns the set of USRs that correspond to the given declaration. +std::vector<std::string> getUSRsForDeclaration(const NamedDecl *ND, + ASTContext &Context); + +struct USRFindingAction { + USRFindingAction(ArrayRef<unsigned> SymbolOffsets, + ArrayRef<std::string> QualifiedNames, bool Force) + : SymbolOffsets(SymbolOffsets), QualifiedNames(QualifiedNames), + ErrorOccurred(false), Force(Force) {} + std::unique_ptr<ASTConsumer> newASTConsumer(); + + ArrayRef<std::string> getUSRSpellings() { return SpellingNames; } + ArrayRef<std::vector<std::string>> getUSRList() { return USRList; } + bool errorOccurred() { return ErrorOccurred; } + +private: + std::vector<unsigned> SymbolOffsets; + std::vector<std::string> QualifiedNames; + std::vector<std::string> SpellingNames; + std::vector<std::vector<std::string>> USRList; + bool ErrorOccurred; + bool Force; +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRFINDINGACTION_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h new file mode 100644 index 0000000000..9872165117 --- /dev/null +++ b/contrib/libs/clang16/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h @@ -0,0 +1,63 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===--- USRLocFinder.h - Clang refactoring library -----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Provides functionality for finding all instances of a USR in a given +/// AST. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRLOCFINDER_H +#define LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRLOCFINDER_H + +#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> + +namespace clang { +namespace tooling { + +/// Create atomic changes for renaming all symbol references which are +/// identified by the USRs set to a given new name. +/// +/// \param USRs The set containing USRs of a particular old symbol. +/// \param NewName The new name to replace old symbol name. +/// \param TranslationUnitDecl The translation unit declaration. +/// +/// \return Atomic changes for renaming. +std::vector<tooling::AtomicChange> +createRenameAtomicChanges(llvm::ArrayRef<std::string> USRs, + llvm::StringRef NewName, Decl *TranslationUnitDecl); + +/// 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 + +#endif // LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRLOCFINDER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif |