1
0

Candidate.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Copyright (C) 2011, 2012 Google Inc.
  2. //
  3. // This file is part of YouCompleteMe.
  4. //
  5. // YouCompleteMe is free software: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation, either version 3 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // YouCompleteMe is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
  17. #include "standard.h"
  18. #include "Candidate.h"
  19. #include "Result.h"
  20. #include <cctype>
  21. #include <boost/algorithm/string.hpp>
  22. using boost::algorithm::all;
  23. using boost::algorithm::is_lower;
  24. namespace YouCompleteMe {
  25. namespace {
  26. LetterNode *FirstUppercaseNode( const std::list< LetterNode *> &list ) {
  27. LetterNode *node = NULL;
  28. foreach( LetterNode * current_node, list ) {
  29. if ( current_node->LetterIsUppercase() ) {
  30. node = current_node;
  31. break;
  32. }
  33. }
  34. return node;
  35. }
  36. } // unnamed namespace
  37. std::string GetWordBoundaryChars( const std::string &text ) {
  38. std::string result;
  39. for ( uint i = 0; i < text.size(); ++i ) {
  40. bool is_first_char_but_not_underscore = i == 0 && text[ i ] != '_';
  41. bool is_good_uppercase = i > 0 &&
  42. IsUppercase( text[ i ] ) &&
  43. !IsUppercase( text[ i - 1 ] );
  44. bool is_alpha_after_underscore = i > 0 &&
  45. text[ i - 1 ] == '_' &&
  46. isalpha( text[ i ] );
  47. if ( is_first_char_but_not_underscore ||
  48. is_good_uppercase ||
  49. is_alpha_after_underscore ) {
  50. result.push_back( tolower( text[ i ] ) );
  51. }
  52. }
  53. return result;
  54. }
  55. Bitset LetterBitsetFromString( const std::string &text ) {
  56. Bitset letter_bitset;
  57. foreach ( char letter, text ) {
  58. letter_bitset.set( IndexForChar( letter ) );
  59. }
  60. return letter_bitset;
  61. }
  62. Candidate::Candidate( const std::string &text )
  63. :
  64. text_( text ),
  65. word_boundary_chars_( GetWordBoundaryChars( text ) ),
  66. text_is_lowercase_( all( text, is_lower() ) ),
  67. letters_present_( LetterBitsetFromString( text ) ),
  68. root_node_( new LetterNode( text ) ) {
  69. }
  70. Result Candidate::QueryMatchResult( const std::string &query,
  71. bool case_sensitive ) const {
  72. LetterNode *node = root_node_.get();
  73. int index_sum = 0;
  74. foreach ( char letter, query ) {
  75. const std::list< LetterNode *> *list = node->NodeListForLetter( letter );
  76. if ( !list )
  77. return Result( false );
  78. if ( case_sensitive ) {
  79. // When the query letter is uppercase, then we force an uppercase match
  80. // but when the query letter is lowercase, then it can match both an
  81. // uppercase and a lowercase letter. This is by design and it's much
  82. // better than forcing lowercase letter matches.
  83. node = IsUppercase( letter ) ?
  84. FirstUppercaseNode( *list ) :
  85. list->front();
  86. if ( !node )
  87. return Result( false );
  88. } else {
  89. node = list->front();
  90. }
  91. index_sum += node->Index();
  92. }
  93. return Result( true, &text_, text_is_lowercase_, index_sum,
  94. word_boundary_chars_, query );
  95. }
  96. } // namespace YouCompleteMe