TypoCorrection.h revision 5b7254c2c31d385eba95fc4d31e87587ec31fd63
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 // 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 126private: 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// @brief Base class for callback objects used by Sema::CorrectTypo to check the 139// validity of a potential typo correction. 140class CorrectionCandidateCallback { 141 public: 142 CorrectionCandidateCallback() 143 : WantTypeSpecifiers(true), WantExpressionKeywords(true), 144 WantCXXNamedCasts(true), WantRemainingKeywords(true), 145 WantObjCSuper(false), 146 IsObjCIvarLookup(false) {} 147 148 virtual ~CorrectionCandidateCallback() {} 149 150 virtual bool ValidateCandidate(const TypoCorrection &candidate) { 151 return true; 152 } 153 154 // Flags for context-dependent keywords. 155 // TODO: Expand these to apply to non-keywords or possibly remove them. 156 bool WantTypeSpecifiers; 157 bool WantExpressionKeywords; 158 bool WantCXXNamedCasts; 159 bool WantRemainingKeywords; 160 bool WantObjCSuper; 161 // Temporary hack for the one case where a CorrectTypoContext enum is used 162 // when looking up results. 163 bool IsObjCIvarLookup; 164}; 165 166} 167 168#endif 169