Home | History | Annotate | Download | only in Sema
      1 //===--- TypoCorrection.h - Class for typo correction results ---*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines the TypoCorrection class, which stores the results of
     11 // Sema's typo correction (Sema::CorrectTypo).
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_SEMA_TYPOCORRECTION_H
     16 #define LLVM_CLANG_SEMA_TYPOCORRECTION_H
     17 
     18 #include "clang/AST/DeclCXX.h"
     19 #include "llvm/ADT/SmallVector.h"
     20 
     21 namespace clang {
     22 
     23 /// @brief Simple class containing the result of Sema::CorrectTypo
     24 class TypoCorrection {
     25 public:
     26   TypoCorrection(const DeclarationName &Name, NamedDecl *NameDecl,
     27                  NestedNameSpecifier *NNS=0, unsigned distance=0)
     28       : CorrectionName(Name),
     29         CorrectionNameSpec(NNS),
     30         EditDistance(distance) {
     31     if (NameDecl)
     32       CorrectionDecls.push_back(NameDecl);
     33   }
     34 
     35   TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS=0,
     36                  unsigned distance=0)
     37       : CorrectionName(Name->getDeclName()),
     38         CorrectionNameSpec(NNS),
     39         EditDistance(distance) {
     40     if (Name)
     41       CorrectionDecls.push_back(Name);
     42   }
     43 
     44   TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS=0,
     45                  unsigned distance=0)
     46       : CorrectionName(Name),
     47         CorrectionNameSpec(NNS),
     48         EditDistance(distance) {}
     49 
     50   TypoCorrection()
     51       : CorrectionNameSpec(0), EditDistance(0) {}
     52 
     53   /// \brief Gets the DeclarationName of the typo correction
     54   DeclarationName getCorrection() const { return CorrectionName; }
     55   IdentifierInfo* getCorrectionAsIdentifierInfo() const {
     56     return CorrectionName.getAsIdentifierInfo();
     57   }
     58 
     59   /// \brief Gets the NestedNameSpecifier needed to use the typo correction
     60   NestedNameSpecifier* getCorrectionSpecifier() const {
     61     return CorrectionNameSpec;
     62   }
     63   void setCorrectionSpecifier(NestedNameSpecifier* NNS) {
     64     CorrectionNameSpec = NNS;
     65   }
     66 
     67   /// \brief Gets the "edit distance" of the typo correction from the typo
     68   unsigned getEditDistance() const { return EditDistance; }
     69 
     70   /// \brief Gets the pointer to the declaration of the typo correction
     71   NamedDecl* getCorrectionDecl() const {
     72     return hasCorrectionDecl() ? *(CorrectionDecls.begin()) : 0;
     73   }
     74   template <class DeclClass>
     75   DeclClass *getCorrectionDeclAs() const {
     76     return dyn_cast_or_null<DeclClass>(getCorrectionDecl());
     77   }
     78 
     79   /// \brief Clears the list of NamedDecls before adding the new one.
     80   void setCorrectionDecl(NamedDecl *CDecl) {
     81     CorrectionDecls.clear();
     82     addCorrectionDecl(CDecl);
     83   }
     84 
     85   /// \brief Add the given NamedDecl to the list of NamedDecls that are the
     86   /// declarations associated with the DeclarationName of this TypoCorrection
     87   void addCorrectionDecl(NamedDecl *CDecl);
     88 
     89   std::string getAsString(const LangOptions &LO) const;
     90   std::string getQuoted(const LangOptions &LO) const {
     91     return "'" + getAsString(LO) + "'";
     92   }
     93 
     94   /// \brief Returns whether this TypoCorrection has a non-empty DeclarationName
     95   operator bool() const { return bool(CorrectionName); }
     96 
     97   /// \brief Mark this TypoCorrection as being a keyword.
     98   /// Since addCorrectionDeclsand setCorrectionDecl don't allow NULL to be
     99   /// added to the list of the correction's NamedDecl pointers, NULL is added
    100   /// as the only element in the list to mark this TypoCorrection as a keyword.
    101   void makeKeyword() {
    102     CorrectionDecls.clear();
    103     CorrectionDecls.push_back(0);
    104   }
    105 
    106   // Check if this TypoCorrection is a keyword by checking if the first
    107   // item in CorrectionDecls is NULL.
    108   bool isKeyword() const {
    109     return !CorrectionDecls.empty() &&
    110         CorrectionDecls.front() == 0;
    111   }
    112 
    113   // Returns true if the correction either is a keyword or has a known decl.
    114   bool isResolved() const { return !CorrectionDecls.empty(); }
    115 
    116   bool isOverloaded() const {
    117     return CorrectionDecls.size() > 1;
    118   }
    119 
    120   typedef llvm::SmallVector<NamedDecl*, 1>::iterator decl_iterator;
    121   decl_iterator begin() {
    122     return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin();
    123   }
    124   decl_iterator end() { return CorrectionDecls.end(); }
    125 
    126 private:
    127   bool hasCorrectionDecl() const {
    128     return (!isKeyword() && !CorrectionDecls.empty());
    129   }
    130 
    131   // Results.
    132   DeclarationName CorrectionName;
    133   NestedNameSpecifier *CorrectionNameSpec;
    134   llvm::SmallVector<NamedDecl*, 1> CorrectionDecls;
    135   unsigned EditDistance;
    136 };
    137 
    138 }
    139 
    140 #endif
    141