diff options
Diffstat (limited to 'clang-tools-extra/cpp11-migrate/Core/FileOverrides.h')
-rw-r--r-- | clang-tools-extra/cpp11-migrate/Core/FileOverrides.h | 202 |
1 files changed, 154 insertions, 48 deletions
diff --git a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h index 8cde7591303..3e81abc6d34 100644 --- a/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h +++ b/clang-tools-extra/cpp11-migrate/Core/FileOverrides.h @@ -16,8 +16,7 @@ #ifndef CPP11_MIGRATE_FILE_OVERRIDES_H #define CPP11_MIGRATE_FILE_OVERRIDES_H -#include "Core/Refactoring.h" -#include "clang-replace/Tooling/ApplyReplacements.h" +#include "clang/Tooling/Refactoring.h" #include "clang/Tooling/ReplacementsYaml.h" #include "llvm/ADT/StringMap.h" @@ -45,13 +44,13 @@ public: /// to remove replaced parts. /// /// Note that all replacements should come from the same file. - void adjustChangedRanges(const clang::tooling::ReplacementsVec &Replaces); + void adjustChangedRanges(const clang::tooling::Replacements &Replaces); /// \brief Iterators. - /// \{ + /// @{ const_iterator begin() const { return Ranges.begin(); } const_iterator end() const { return Ranges.end(); } - /// \} + /// @} private: void coalesceRanges(); @@ -59,71 +58,178 @@ private: RangeVec Ranges; }; -/// \brief Maintains current state of transformed files and tracks source ranges -/// where changes have been made. -class FileOverrides { +/// \brief Container for storing override information for a single headers. +class HeaderOverride { public: - /// \brief Maps file names to file contents. - typedef llvm::StringMap<std::string> FileStateMap; + /// \brief Constructors. + /// @{ + HeaderOverride() {} + HeaderOverride(llvm::StringRef HeaderPath, + llvm::StringRef MainSourceFile) : HeaderPath(HeaderPath) { + Replacements.MainSourceFile = MainSourceFile; + } + /// @} - /// \brief Maps file names to change tracking info for a file. - typedef llvm::StringMap<ChangedRanges> ChangeMap; + /// \brief Getter for HeaderPath. + llvm::StringRef getHeaderPath() const { + return HeaderPath; + } + /// \brief Accessor for ContentOverride. + /// @{ + llvm::StringRef getContentOverride() const { return ContentOverride; } + void setContentOverride(const llvm::StringRef S) { ContentOverride = S; } + /// @} - /// \brief Override file contents seen by \c SM for all files stored by this - /// object. - void applyOverrides(clang::SourceManager &SM) const; + /// \brief Getter for Changes. + const ChangedRanges &getChanges() const { return Changes; } - /// \brief Update change tracking information based on replacements stored in - /// \c Replaces. - void - adjustChangedRanges(const clang::replace::FileToReplacementsMap &Replaces); + /// \brief Swaps the content of ContentOverride with \p S. + void swapContentOverride(std::string &S) { ContentOverride.swap(S); } - /// \brief Accessor for change tracking information. - const ChangeMap &getChangedRanges() const { - return ChangeTracking; + /// \brief Getter for Replacements. + const clang::tooling::TranslationUnitReplacements &getReplacements() const { + return Replacements; } - /// \brief Coalesce changes stored in \c Rewrites and replace file contents - /// overrides stored in this object. + /// \brief Stores the replacements made by a transform to the header this + /// object represents. + void recordReplacements(const clang::tooling::Replacements &Replaces); + + /// \brief Helper function to adjust the changed ranges. + void adjustChangedRanges(const clang::tooling::Replacements &Replaces) { + Changes.adjustChangedRanges(Replaces); + } + +private: + std::string ContentOverride; + ChangedRanges Changes; + std::string HeaderPath; + clang::tooling::TranslationUnitReplacements Replacements; +}; + +/// \brief Container mapping header file names to override information. +typedef llvm::StringMap<HeaderOverride> HeaderOverrides; + +/// \brief Container storing the file content overrides for a source file and +/// any headers included by the source file either directly or indirectly to +/// which changes have been made. +class SourceOverrides { +public: + SourceOverrides(llvm::StringRef MainFileName, bool TrackChanges); + + /// \brief Accessors. + /// @{ + llvm::StringRef getMainFileName() const { return MainFileName; } + llvm::StringRef getMainFileContent() const { return MainFileOverride; } + const ChangedRanges &getChangedRanges() const { return MainFileChanges; } + + /// \brief Is file change tracking enabled? /// - /// \param Rewrites Rewriter containing changes to files. - void updateState(const clang::Rewriter &Rewrites); + /// Tracking file changes can be useful to reformat the code for example. + bool isTrackingFileChanges() const { return TrackChanges; } + /// @} - /// \brief Accessor for current file state. - const FileStateMap &getState() const { return FileStates; } + /// \brief Indicates if the source file has been overridden. + /// + /// It's possible for a source to remain unchanged while only headers are + /// changed. + bool isSourceOverriden() const { return !MainFileOverride.empty(); } - /// \brief Write all file contents overrides to disk. + /// \brief Override the file contents by applying all the replacements. /// - /// \param Diagnostics DiagnosticsEngine for error output. + /// \param Replaces The replacements to apply. + /// \param SM A user provided SourceManager to be used when applying rewrites. + void applyReplacements(clang::tooling::Replacements &Replaces, + clang::SourceManager &SM); + void applyReplacements(clang::tooling::Replacements &Replaces); + + /// \brief Convenience function for applying this source's overrides to + /// the given SourceManager. + void applyOverrides(clang::SourceManager &SM) const; + + /// \brief Iterators. + /// @{ + HeaderOverrides::iterator headers_begin() { return Headers.begin(); } + HeaderOverrides::iterator headers_end() { return Headers.end(); } + HeaderOverrides::const_iterator headers_begin() const { + return Headers.begin(); + } + HeaderOverrides::const_iterator headers_end() const { return Headers.end(); } + /// @} + +private: + typedef llvm::StringMap<clang::tooling::Replacements> ReplacementsMap; + + /// \brief Flatten the Rewriter buffers of \p Rewrite and store results as + /// file content overrides. + void applyRewrites(clang::Rewriter &Rewrite); + + /// \brief Adjust the changed ranges to reflect the parts of the files that + /// have been replaced. + void adjustChangedRanges(const clang::tooling::Replacements &Replaces, + const ReplacementsMap &HeadersReplaces); + + const std::string MainFileName; + std::string MainFileOverride; + const bool TrackChanges; + ChangedRanges MainFileChanges; + HeaderOverrides Headers; +}; + +/// \brief Maps source file names to content override information. +class FileOverrides { +public: + typedef llvm::StringMap<SourceOverrides *> SourceOverridesMap; + typedef SourceOverridesMap::const_iterator const_iterator; + + /// \brief Construct the SourceOverrides manager. /// - /// \returns \li true if all files with overridden file contents were written - /// to disk successfully. - /// \li false if any failure occurred. - bool writeToDisk(clang::DiagnosticsEngine &Diagnostics) const; + /// \param TrackChanges Wether or not the \c SourceOverrides should keep track + /// of changes. See \c SourceOverrides::isTrackingFileChanges(). + FileOverrides(bool TrackChanges) : TrackChanges(TrackChanges) {} + ~FileOverrides(); + + const_iterator find(llvm::StringRef Filename) const { + return Overrides.find(Filename); + } + + /// \brief Get the \c SourceOverrides for \p Filename, creating it if + /// necessary. + SourceOverrides &getOrCreate(llvm::StringRef Filename); + + /// \brief Iterators. + /// @{ + const_iterator begin() const { return Overrides.begin(); } + const_iterator end() const { return Overrides.end(); } + /// @} private: - FileStateMap FileStates; - ChangeMap ChangeTracking; + FileOverrides(const FileOverrides &) LLVM_DELETED_FUNCTION; + FileOverrides &operator=(const FileOverrides &) LLVM_DELETED_FUNCTION; + + SourceOverridesMap Overrides; + const bool TrackChanges; }; /// \brief Generate a unique filename to store the replacements. /// -/// Generates a unique filename in the same directory as \c MainSourceFile. The -/// filename is generated following this pattern: +/// Generates a unique filename in the same directory as the header file. The +/// filename is based on the following model: /// -/// MainSourceFile_%%_%%_%%_%%_%%_%%.yaml +/// source.cpp_header.h_%%_%%_%%_%%_%%_%%.yaml /// /// where all '%' will be replaced by a randomly chosen hex number. /// -/// \param[in] MainSourceFile Full path to the source file. -/// \param[out] Result The resulting unique filename in the same directory as -/// the \c MainSourceFile. -/// \param[out] Error If an error occurs a description of that error is -/// placed in this string. -/// \returns true on success, false if a unique file name could not be created. -bool generateReplacementsFileName(const llvm::StringRef MainSourceFile, - llvm::SmallVectorImpl<char> &Result, - llvm::SmallVectorImpl<char> &Error); +/// @param SourceFile Full path to the source file. +/// @param HeaderFile Full path to the header file. +/// @param Result The resulting unique filename in the same directory as the +/// header file. +/// @param Error Description of the error if there is any. +/// @returns true if succeeded, false otherwise. +bool generateReplacementsFileName(llvm::StringRef SourceFile, + llvm::StringRef HeaderFile, + llvm::SmallVectorImpl<char> &Result, + llvm::SmallVectorImpl<char> &Error); #endif // CPP11_MIGRATE_FILE_OVERRIDES_H |