TypoCorrection.h revision 60a09dcc4656b82c7f96f8719a403a83247f6742
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 21namespace clang { 22 23/// @brief Simple class containing the result of Sema::CorrectTypo 24class TypoCorrection { 25public: 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 // Check if this TypoCorrection is the given keyword. 114 template<std::size_t StrLen> 115 bool isKeyword(const char (&Str)[StrLen]) const { 116 return isKeyword() && getCorrectionAsIdentifierInfo()->isStr(Str); 117 } 118 119 // Returns true if the correction either is a keyword or has a known decl. 120 bool isResolved() const { return !CorrectionDecls.empty(); } 121 122 bool isOverloaded() const { 123 return CorrectionDecls.size() > 1; 124 } 125 126 typedef llvm::SmallVector<NamedDecl*, 1>::iterator decl_iterator; 127 decl_iterator begin() { 128 return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin(); 129 } 130 decl_iterator end() { return CorrectionDecls.end(); } 131 typedef llvm::SmallVector<NamedDecl*, 1>::const_iterator const_decl_iterator; 132 const_decl_iterator begin() const { 133 return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin(); 134 } 135 const_decl_iterator end() const { return CorrectionDecls.end(); } 136 137private: 138 bool hasCorrectionDecl() const { 139 return (!isKeyword() && !CorrectionDecls.empty()); 140 } 141 142 // Results. 143 DeclarationName CorrectionName; 144 NestedNameSpecifier *CorrectionNameSpec; 145 llvm::SmallVector<NamedDecl*, 1> CorrectionDecls; 146 unsigned EditDistance; 147}; 148 149/// @brief Base class for callback objects used by Sema::CorrectTypo to check 150/// the validity of a potential typo correction. 151class CorrectionCandidateCallback { 152 public: 153 CorrectionCandidateCallback() 154 : WantTypeSpecifiers(true), WantExpressionKeywords(true), 155 WantCXXNamedCasts(true), WantRemainingKeywords(true), 156 WantObjCSuper(false), 157 IsObjCIvarLookup(false) {} 158 159 virtual ~CorrectionCandidateCallback() {} 160 161 virtual bool ValidateCandidate(const TypoCorrection &candidate) { 162 return true; 163 } 164 165 // Flags for context-dependent keywords. 166 // TODO: Expand these to apply to non-keywords or possibly remove them. 167 bool WantTypeSpecifiers; 168 bool WantExpressionKeywords; 169 bool WantCXXNamedCasts; 170 bool WantRemainingKeywords; 171 bool WantObjCSuper; 172 // Temporary hack for the one case where a CorrectTypoContext enum is used 173 // when looking up results. 174 bool IsObjCIvarLookup; 175}; 176 177/// @brief Simple template class for restricting typo correction candidates 178/// to ones having a single Decl* of the given type. 179template <class C> 180class DeclFilterCCC : public CorrectionCandidateCallback { 181 public: 182 virtual bool ValidateCandidate(const TypoCorrection &candidate) { 183 return candidate.getCorrectionDeclAs<C>(); 184 } 185}; 186 187} 188 189#endif 190