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