TypoCorrection.h revision 2f4d88f4418afafbd0b22ce0f79cdead6f3a6f99
19fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com//===--- TypoCorrection.h - Class for typo correction results ---*- C++ -*-===// 29fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com// 39fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com// The LLVM Compiler Infrastructure 49fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com// 59fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com// This file is distributed under the University of Illinois Open Source 69fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com// License. See LICENSE.TXT for details. 79fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com// 89fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com//===----------------------------------------------------------------------===// 99fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com// 109fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com// This file defines the TypoCorrection class, which stores the results of 119fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com// Sema's typo correction (Sema::CorrectTypo). 129fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com// 139fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com//===----------------------------------------------------------------------===// 144b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org 159fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com#ifndef LLVM_CLANG_SEMA_TYPOCORRECTION_H 16773f8e24214991332eaf903e72c13dca7d78d40dcommit-bot@chromium.org#define LLVM_CLANG_SEMA_TYPOCORRECTION_H 17773f8e24214991332eaf903e72c13dca7d78d40dcommit-bot@chromium.org 18773f8e24214991332eaf903e72c13dca7d78d40dcommit-bot@chromium.org#include "clang/AST/DeclCXX.h" 19773f8e24214991332eaf903e72c13dca7d78d40dcommit-bot@chromium.org#include "llvm/ADT/SmallVector.h" 20773f8e24214991332eaf903e72c13dca7d78d40dcommit-bot@chromium.org 21773f8e24214991332eaf903e72c13dca7d78d40dcommit-bot@chromium.orgnamespace clang { 22773f8e24214991332eaf903e72c13dca7d78d40dcommit-bot@chromium.org 23773f8e24214991332eaf903e72c13dca7d78d40dcommit-bot@chromium.org/// @brief Simple class containing the result of Sema::CorrectTypo 249fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.comclass TypoCorrection { 259fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.compublic: 269fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com TypoCorrection(const DeclarationName &Name, NamedDecl *NameDecl, 279fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com NestedNameSpecifier *NNS=0, unsigned distance=0) 289fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com : CorrectionName(Name), 299fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com CorrectionNameSpec(NNS), 306fcd28ba1de83b72f4c8343ccec27d26c127de32reed@google.com EditDistance(distance) { 319fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com if (NameDecl) 329fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com CorrectionDecls.push_back(NameDecl); 336fcd28ba1de83b72f4c8343ccec27d26c127de32reed@google.com } 349fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com 359fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS=0, 369fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com unsigned distance=0) 379fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com : CorrectionName(Name->getDeclName()), 389fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com CorrectionNameSpec(NNS), 399fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com EditDistance(distance) { 409fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com if (Name) 419fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com CorrectionDecls.push_back(Name); 426fcd28ba1de83b72f4c8343ccec27d26c127de32reed@google.com } 439fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com 449fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS=0, 459fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com unsigned distance=0) 469fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com : CorrectionName(Name), 479fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com CorrectionNameSpec(NNS), 484b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org EditDistance(distance) {} 4949f085dddff10473b6ebf832a974288300224e60bsalomon 504b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org TypoCorrection() 514b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org : CorrectionNameSpec(0), EditDistance(0) {} 524b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org 534b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org /// \brief Gets the DeclarationName of the typo correction 544b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org DeclarationName getCorrection() const { return CorrectionName; } 554b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org IdentifierInfo* getCorrectionAsIdentifierInfo() const { 564b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org return CorrectionName.getAsIdentifierInfo(); 574b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org } 584b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org 594b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org /// \brief Gets the NestedNameSpecifier needed to use the typo correction 609fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com NestedNameSpecifier* getCorrectionSpecifier() const { 614b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org return CorrectionNameSpec; 629fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com } 639fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com void setCorrectionSpecifier(NestedNameSpecifier* NNS) { 649fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com CorrectionNameSpec = NNS; 659fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com } 669fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com 679fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com /// \brief Gets the "edit distance" of the typo correction from the typo 689fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com unsigned getEditDistance() const { return EditDistance; } 699fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com 709fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com /// \brief Gets the pointer to the declaration of the typo correction 719fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com NamedDecl* getCorrectionDecl() const { 726fcd28ba1de83b72f4c8343ccec27d26c127de32reed@google.com return hasCorrectionDecl() ? *(CorrectionDecls.begin()) : 0; 739fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com } 749fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com template <class DeclClass> 759fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com DeclClass *getCorrectionDeclAs() const { 76ec66e6264de5110802c3d9927380d913242c9d5frobertphillips return dyn_cast_or_null<DeclClass>(getCorrectionDecl()); 77ec66e6264de5110802c3d9927380d913242c9d5frobertphillips } 78ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 79ec66e6264de5110802c3d9927380d913242c9d5frobertphillips /// \brief Clears the list of NamedDecls before adding the new one. 809fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com void setCorrectionDecl(NamedDecl *CDecl) { 819fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com CorrectionDecls.clear(); 826fcd28ba1de83b72f4c8343ccec27d26c127de32reed@google.com addCorrectionDecl(CDecl); 839fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com } 846fcd28ba1de83b72f4c8343ccec27d26c127de32reed@google.com 859fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com /// \brief Add the given NamedDecl to the list of NamedDecls that are the 869fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com /// declarations associated with the DeclarationName of this TypoCorrection 879fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com void addCorrectionDecl(NamedDecl *CDecl); 889fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com 899fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com std::string getAsString(const LangOptions &LO) const; 909fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com std::string getQuoted(const LangOptions &LO) const { 919fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com return "'" + getAsString(LO) + "'"; 92ec66e6264de5110802c3d9927380d913242c9d5frobertphillips } 93ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 94ec66e6264de5110802c3d9927380d913242c9d5frobertphillips /// \brief Returns whether this TypoCorrection has a non-empty DeclarationName 95ec66e6264de5110802c3d9927380d913242c9d5frobertphillips operator bool() const { return bool(CorrectionName); } 96ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 97ec66e6264de5110802c3d9927380d913242c9d5frobertphillips /// \brief Mark this TypoCorrection as being a keyword. 98ec66e6264de5110802c3d9927380d913242c9d5frobertphillips /// Since addCorrectionDeclsand setCorrectionDecl don't allow NULL to be 99ec66e6264de5110802c3d9927380d913242c9d5frobertphillips /// added to the list of the correction's NamedDecl pointers, NULL is added 100ec66e6264de5110802c3d9927380d913242c9d5frobertphillips /// as the only element in the list to mark this TypoCorrection as a keyword. 101ec66e6264de5110802c3d9927380d913242c9d5frobertphillips void makeKeyword() { 1029fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com CorrectionDecls.clear(); 1039fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com CorrectionDecls.push_back(0); 104a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org } 10549f085dddff10473b6ebf832a974288300224e60bsalomon 106a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org // Check if this TypoCorrection is a keyword by checking if the first 107a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org // item in CorrectionDecls is NULL. 108a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org bool isKeyword() const { 109a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org return !CorrectionDecls.empty() && 110a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org CorrectionDecls.front() == 0; 111a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org } 112a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org 113a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org // Check if this TypoCorrection is the given keyword. 114a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org template<std::size_t StrLen> 115a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org bool isKeyword(const char (&Str)[StrLen]) const { 116a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org return isKeyword() && getCorrectionAsIdentifierInfo()->isStr(Str); 117a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org } 118a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org 119beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com // Returns true if the correction either is a keyword or has a known decl. 120beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com bool isResolved() const { return !CorrectionDecls.empty(); } 121beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com 122beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com bool isOverloaded() const { 123beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com return CorrectionDecls.size() > 1; 124beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com } 125beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com 126beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com typedef llvm::SmallVector<NamedDecl*, 1>::iterator decl_iterator; 127beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com decl_iterator begin() { 128beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin(); 129beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com } 130db35dab49e0e6bf16ccad5052bf6e6826daad27dskia.committer@gmail.com decl_iterator end() { return CorrectionDecls.end(); } 131db35dab49e0e6bf16ccad5052bf6e6826daad27dskia.committer@gmail.com 1322b290cec9825da11d8e09074727cfaac5eca6453commit-bot@chromium.orgprivate: 133beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com bool hasCorrectionDecl() const { 134a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org return (!isKeyword() && !CorrectionDecls.empty()); 135beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com } 136beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com 137beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com // Results. 138beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com DeclarationName CorrectionName; 139a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org NestedNameSpecifier *CorrectionNameSpec; 140beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com llvm::SmallVector<NamedDecl*, 1> CorrectionDecls; 141beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com unsigned EditDistance; 142beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com}; 143beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com 1449fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com/// @brief Base class for callback objects used by Sema::CorrectTypo to check 1459fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com/// the validity of a potential typo correction. 1468515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.comclass CorrectionCandidateCallback { 1479fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com public: 1489fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com CorrectionCandidateCallback() 1499fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com : WantTypeSpecifiers(true), WantExpressionKeywords(true), 150a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org WantCXXNamedCasts(true), WantRemainingKeywords(true), 1519fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com WantObjCSuper(false), 1529fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com IsObjCIvarLookup(false) {} 1539fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com 1549fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com virtual ~CorrectionCandidateCallback() {} 1559fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com 1569fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com virtual bool ValidateCandidate(const TypoCorrection &candidate) { 1579fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com return true; 1589fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com } 1599fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com 1609fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com // Flags for context-dependent keywords. 1619fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com // TODO: Expand these to apply to non-keywords or possibly remove them. 1629fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com bool WantTypeSpecifiers; 1639fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com bool WantExpressionKeywords; 1649fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com bool WantCXXNamedCasts; 1659fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com bool WantRemainingKeywords; 1669fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com bool WantObjCSuper; 1679fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com // Temporary hack for the one case where a CorrectTypoContext enum is used 1689fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com // when looking up results. 169db35dab49e0e6bf16ccad5052bf6e6826daad27dskia.committer@gmail.com bool IsObjCIvarLookup; 170db35dab49e0e6bf16ccad5052bf6e6826daad27dskia.committer@gmail.com}; 171a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org 172a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org/// @brief Simple template class for restricting typo correction candidates 1732b290cec9825da11d8e09074727cfaac5eca6453commit-bot@chromium.org/// to ones having a single Decl* of the given type. 174db35dab49e0e6bf16ccad5052bf6e6826daad27dskia.committer@gmail.comtemplate <class C> 175db35dab49e0e6bf16ccad5052bf6e6826daad27dskia.committer@gmail.comclass DeclFilterCCC : public CorrectionCandidateCallback { 176a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org public: 177a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org virtual bool ValidateCandidate(const TypoCorrection &candidate) { 1782b290cec9825da11d8e09074727cfaac5eca6453commit-bot@chromium.org return candidate.getCorrectionDeclAs<C>(); 1799fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com } 1809fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com}; 1819fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com 1829fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com} 1839fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com 1849fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com#endif 1859fd7f8d2906365637dc25f98ffdede87d631ef71rileya@google.com