Fix ranking bug with ALL_CAPS variables
GetWordBoundaryChars would return "allcaps" for "ALL_CAPS" instead of "ac". This would manifest as ranking (for instance) "STDIN_FILENO" ahead of "stdin" for query "std", which is terrible. This bug has been present in YCM for many months, but no one noticed the issue. Fixes #272.
This commit is contained in:
parent
a80739ad6f
commit
387102a99f
@ -28,21 +28,6 @@ namespace YouCompleteMe {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string GetWordBoundaryChars( const std::string &text ) {
|
||||
std::string result;
|
||||
|
||||
for ( uint i = 0; i < text.size(); ++i ) {
|
||||
if ( i == 0 ||
|
||||
IsUppercase( text[ i ] ) ||
|
||||
( i > 0 && text[ i - 1 ] == '_' && isalpha( text[ i ] ) )
|
||||
) {
|
||||
result.push_back( tolower( text[ i ] ) );
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
LetterNode *FirstUppercaseNode( const std::list< LetterNode *> &list ) {
|
||||
LetterNode *node = NULL;
|
||||
foreach( LetterNode * current_node, list ) {
|
||||
@ -67,6 +52,28 @@ LetterNode *FirstLowercaseNode( const std::list< LetterNode *> &list ) {
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
std::string GetWordBoundaryChars( const std::string &text ) {
|
||||
std::string result;
|
||||
|
||||
for ( uint i = 0; i < text.size(); ++i ) {
|
||||
bool is_first_char_but_not_underscore = i == 0 && text[ i ] != '_';
|
||||
bool is_good_uppercase = i > 0 &&
|
||||
IsUppercase( text[ i ] ) &&
|
||||
!IsUppercase( text[ i - 1 ] );
|
||||
bool is_alpha_after_underscore = i > 0 &&
|
||||
text[ i - 1 ] == '_' &&
|
||||
isalpha( text[ i ] );
|
||||
|
||||
if ( is_first_char_but_not_underscore ||
|
||||
is_good_uppercase ||
|
||||
is_alpha_after_underscore ) {
|
||||
result.push_back( tolower( text[ i ] ) );
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Bitset LetterBitsetFromString( const std::string &text ) {
|
||||
Bitset letter_bitset;
|
||||
|
@ -34,6 +34,9 @@ typedef std::bitset< NUM_LETTERS > Bitset;
|
||||
|
||||
Bitset LetterBitsetFromString( const std::string &text );
|
||||
|
||||
// Public for tests
|
||||
std::string GetWordBoundaryChars( const std::string &text );
|
||||
|
||||
class Candidate : boost::noncopyable {
|
||||
public:
|
||||
|
||||
|
@ -21,6 +21,78 @@
|
||||
|
||||
namespace YouCompleteMe {
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, SimpleOneWord ) {
|
||||
EXPECT_EQ( "s", GetWordBoundaryChars( "simple" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, UnderscoreInMiddle ) {
|
||||
EXPECT_EQ( "sf", GetWordBoundaryChars( "simple_foo" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, UnderscoreStart ) {
|
||||
EXPECT_EQ( "s", GetWordBoundaryChars( "_simple" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, ManyUnderscoreStart ) {
|
||||
EXPECT_EQ( "s", GetWordBoundaryChars( "___simple" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, UnderscoreStartAndInMiddle ) {
|
||||
EXPECT_EQ( "sf", GetWordBoundaryChars( "_simple_foo" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, ManyUnderscoreStartAndInMiddle ) {
|
||||
EXPECT_EQ( "sf", GetWordBoundaryChars( "___simple__foo" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, SimpleCapitalStart ) {
|
||||
EXPECT_EQ( "s", GetWordBoundaryChars( "Simple" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, SimpleCapitalTwoWord ) {
|
||||
EXPECT_EQ( "ss", GetWordBoundaryChars( "SimpleStuff" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, SimpleCapitalTwoWordUnderscoreMiddle ) {
|
||||
EXPECT_EQ( "ss", GetWordBoundaryChars( "Simple_Stuff" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, JavaCase ) {
|
||||
EXPECT_EQ( "ssf", GetWordBoundaryChars( "simpleStuffFoo" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, UppercaseSequence ) {
|
||||
EXPECT_EQ( "ss", GetWordBoundaryChars( "simpleSTUFF" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, UppercaseSequenceInMiddle ) {
|
||||
EXPECT_EQ( "ss", GetWordBoundaryChars( "simpleSTUFFfoo" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, UppercaseSequenceInMiddleUnderscore ) {
|
||||
EXPECT_EQ( "ssf", GetWordBoundaryChars( "simpleSTUFF_Foo" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, UppercaseSequenceInMiddleUnderscoreLowercase ) {
|
||||
EXPECT_EQ( "ssf", GetWordBoundaryChars( "simpleSTUFF_foo" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, AllCapsSimple ) {
|
||||
EXPECT_EQ( "s", GetWordBoundaryChars( "SIMPLE" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, AllCapsUnderscoreStart ) {
|
||||
EXPECT_EQ( "s", GetWordBoundaryChars( "_SIMPLE" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, AllCapsUnderscoreMiddle ) {
|
||||
EXPECT_EQ( "ss", GetWordBoundaryChars( "SIMPLE_STUFF" ) );
|
||||
}
|
||||
|
||||
TEST( GetWordBoundaryCharsTest, AllCapsUnderscoreMiddleAndStart ) {
|
||||
EXPECT_EQ( "ss", GetWordBoundaryChars( "_SIMPLE_STUFF" ) );
|
||||
}
|
||||
|
||||
TEST( CandidateTest, TextValid ) {
|
||||
std::string text = "foo";
|
||||
Candidate candidate( text );
|
||||
|
@ -207,6 +207,15 @@ TEST( IdentifierCompleterTest, SameLowercaseCandidateWins ) {
|
||||
"Foobar" ) );
|
||||
}
|
||||
|
||||
TEST( IdentifierCompleterTest, ShorterAndLowercaseWins ) {
|
||||
EXPECT_THAT( IdentifierCompleter(
|
||||
StringVector(
|
||||
"STDIN_FILENO",
|
||||
"stdin" ) ).CandidatesForQuery( "std" ),
|
||||
ElementsAre( "stdin",
|
||||
"STDIN_FILENO" ) );
|
||||
}
|
||||
|
||||
// TODO: tests for filepath and filetype candidate storing
|
||||
|
||||
} // namespace YouCompleteMe
|
||||
|
Loading…
x
Reference in New Issue
Block a user