//===--- RenamedSymbol.h - ---------------------------------*- C++ -*------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLING_REFACTOR_RENAMED_SYMBOL_H
#define LLVM_CLANG_TOOLING_REFACTOR_RENAMED_SYMBOL_H

#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Tooling/Refactor/SymbolName.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSet.h"

namespace clang {

class NamedDecl;

namespace tooling {
namespace rename {

/// \brief A symbol that has to be renamed.
class Symbol {
public:
  SymbolName Name;
  /// The index of this symbol in a \c SymbolOperation.
  unsigned SymbolIndex;
  /// The declaration that was used to initiate a refactoring operation for this
  /// symbol. May not be the most canonical declaration.
  const NamedDecl *FoundDecl;
  /// An optional Objective-C selector.
  llvm::Optional<Selector> ObjCSelector;

  Symbol(const NamedDecl *FoundDecl, unsigned SymbolIndex,
         const LangOptions &LangOpts);

  Symbol(Symbol &&) = default;
  Symbol &operator=(Symbol &&) = default;
};

/// \brief An occurrence of a renamed symbol.
///
/// Provides information about an occurrence of symbol that helps renaming tools
/// determine if they can rename this symbol automatically and which source
/// ranges they have to replace.
///
/// A single occurrence of a symbol can span more than one source range to
/// account for things like Objective-C selectors.
// TODO: Rename
class SymbolOccurrence {
  /// The source locations that correspond to the occurence of the symbol.
  SmallVector<SourceLocation, 4> Locations;

public:
  enum OccurrenceKind {
    /// \brief This occurrence is an exact match and can be renamed
    /// automatically.
    MatchingSymbol,

    /// \brief This is an occurrence of a matching selector. It can't be renamed
    /// automatically unless the indexer proves that this selector refers only
    /// to the declarations that correspond to the renamed symbol.
    MatchingSelector,

    /// \brief This is an occurrence of an implicit property that uses the
    /// renamed method.
    MatchingImplicitProperty,

    /// \brief This is a textual occurrence of a symbol in a comment.
    MatchingComment,

    /// \brief This is a textual occurrence of a symbol in a doc comment.
    MatchingDocComment,

    /// \brief This is an occurrence of a symbol in an inclusion directive.
    MatchingFilename
  };

  OccurrenceKind Kind;
  /// Whether or not this occurrence is inside a macro. When this is true, the
  /// locations of the occurrence contain just one location that points to
  /// the location of the macro expansion.
  bool IsMacroExpansion;
  /// The index of the symbol stored in a \c SymbolOperation which matches this
  /// occurrence.
  unsigned SymbolIndex;

  SymbolOccurrence()
      : Kind(MatchingSymbol), IsMacroExpansion(false), SymbolIndex(0) {}

  SymbolOccurrence(OccurrenceKind Kind, bool IsMacroExpansion,
                   unsigned SymbolIndex, ArrayRef<SourceLocation> Locations)
      : Locations(Locations.begin(), Locations.end()), Kind(Kind),
        IsMacroExpansion(IsMacroExpansion), SymbolIndex(SymbolIndex) {
    assert(!Locations.empty() && "Renamed occurence without locations!");
  }

  SymbolOccurrence(SymbolOccurrence &&) = default;
  SymbolOccurrence &operator=(SymbolOccurrence &&) = default;

  ArrayRef<SourceLocation> locations() const {
    if (Kind == MatchingImplicitProperty && Locations.size() == 2)
      return llvm::makeArrayRef(Locations).drop_back();
    return Locations;
  }

  /// Return the source range that corresponds to an individual source location
  /// in this occurrence.
  SourceRange getLocationRange(SourceLocation Loc, size_t OldNameSize) const {
    SourceLocation EndLoc;
    // Implicit property references might store the end as the second location
    // to take into account the match for 'prop' when the old name is 'setProp'.
    if (Kind == MatchingImplicitProperty && Locations.size() == 2) {
      assert(Loc == Locations[0] && "invalid loc");
      EndLoc = Locations[1];
    } else
      EndLoc = IsMacroExpansion ? Loc : Loc.getLocWithOffset(OldNameSize);
    return SourceRange(Loc, EndLoc);
  }

  friend bool operator<(const SymbolOccurrence &LHS,
                        const SymbolOccurrence &RHS);
  friend bool operator==(const SymbolOccurrence &LHS,
                         const SymbolOccurrence &RHS);
};

/// \brief Less-than operator between the two renamed symbol occurrences.
bool operator<(const SymbolOccurrence &LHS, const SymbolOccurrence &RHS);

/// \brief Equal-to operator between the two renamed symbol occurrences.
bool operator==(const SymbolOccurrence &LHS, const SymbolOccurrence &RHS);

} // end namespace rename
} // end namespace tooling
} // end namespace clang

#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAMED_SYMBOL_H
