2012-08-06 00:01:42 -04:00
|
|
|
// Copyright (C) 2011, 2012 Strahinja Val Markovic <val@markovic.io>
|
|
|
|
//
|
|
|
|
// This file is part of YouCompleteMe.
|
|
|
|
//
|
|
|
|
// YouCompleteMe is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// YouCompleteMe is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
#include "CompletionData.h"
|
2012-09-06 15:09:32 -04:00
|
|
|
#include "ClangUtils.h"
|
2012-08-06 00:01:42 -04:00
|
|
|
|
2012-08-06 00:34:29 -04:00
|
|
|
#include <boost/algorithm/string/erase.hpp>
|
2012-08-06 23:02:46 -04:00
|
|
|
#include <boost/move/move.hpp>
|
2012-08-06 00:34:29 -04:00
|
|
|
|
2013-01-19 23:03:32 -05:00
|
|
|
namespace {
|
2012-08-06 00:01:42 -04:00
|
|
|
|
2013-01-19 23:03:32 -05:00
|
|
|
char CursorKindToVimKind( CXCursorKind kind ) {
|
|
|
|
switch ( kind ) {
|
2012-08-06 00:01:42 -04:00
|
|
|
case CXCursor_StructDecl:
|
2013-02-23 20:34:10 -05:00
|
|
|
return 's';
|
|
|
|
|
2012-08-06 00:01:42 -04:00
|
|
|
case CXCursor_ClassDecl:
|
2013-02-23 20:34:10 -05:00
|
|
|
case CXCursor_ClassTemplate:
|
|
|
|
return 'c';
|
|
|
|
|
2012-08-06 00:01:42 -04:00
|
|
|
case CXCursor_EnumDecl:
|
2013-02-23 20:34:10 -05:00
|
|
|
return 'e';
|
|
|
|
|
|
|
|
case CXCursor_UnexposedDecl:
|
|
|
|
case CXCursor_UnionDecl:
|
2012-08-06 00:01:42 -04:00
|
|
|
case CXCursor_TypedefDecl:
|
|
|
|
return 't';
|
|
|
|
|
|
|
|
case CXCursor_FieldDecl:
|
|
|
|
return 'm';
|
|
|
|
|
|
|
|
case CXCursor_FunctionDecl:
|
|
|
|
case CXCursor_CXXMethod:
|
|
|
|
case CXCursor_FunctionTemplate:
|
2013-02-23 20:34:10 -05:00
|
|
|
case CXCursor_ConversionFunction:
|
|
|
|
case CXCursor_Constructor:
|
|
|
|
case CXCursor_Destructor:
|
2012-08-06 00:01:42 -04:00
|
|
|
return 'f';
|
|
|
|
|
|
|
|
case CXCursor_VarDecl:
|
|
|
|
return 'v';
|
|
|
|
|
|
|
|
case CXCursor_MacroDefinition:
|
|
|
|
return 'd';
|
|
|
|
|
2013-02-23 20:34:10 -05:00
|
|
|
case CXCursor_ParmDecl:
|
|
|
|
return 'p';
|
|
|
|
|
|
|
|
case CXCursor_Namespace:
|
|
|
|
case CXCursor_NamespaceAlias:
|
|
|
|
return 'n';
|
|
|
|
|
2012-08-06 00:01:42 -04:00
|
|
|
default:
|
|
|
|
return 'u'; // for 'unknown', 'unsupported'... whatever you like
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-01-19 23:03:32 -05:00
|
|
|
bool IsMainCompletionTextInfo( CXCompletionChunkKind kind ) {
|
2012-08-06 00:01:42 -04:00
|
|
|
return
|
|
|
|
kind == CXCompletionChunk_Optional ||
|
|
|
|
kind == CXCompletionChunk_TypedText ||
|
|
|
|
kind == CXCompletionChunk_Placeholder ||
|
|
|
|
kind == CXCompletionChunk_LeftParen ||
|
|
|
|
kind == CXCompletionChunk_RightParen ||
|
|
|
|
kind == CXCompletionChunk_RightBracket ||
|
|
|
|
kind == CXCompletionChunk_LeftBracket ||
|
|
|
|
kind == CXCompletionChunk_LeftBrace ||
|
|
|
|
kind == CXCompletionChunk_RightBrace ||
|
|
|
|
kind == CXCompletionChunk_RightAngle ||
|
|
|
|
kind == CXCompletionChunk_LeftAngle ||
|
|
|
|
kind == CXCompletionChunk_Comma ||
|
|
|
|
kind == CXCompletionChunk_Colon ||
|
|
|
|
kind == CXCompletionChunk_SemiColon ||
|
|
|
|
kind == CXCompletionChunk_Equal ||
|
|
|
|
kind == CXCompletionChunk_Informative ||
|
|
|
|
kind == CXCompletionChunk_HorizontalSpace;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-08-06 00:43:38 -04:00
|
|
|
std::string ChunkToString( CXCompletionString completion_string,
|
2013-01-19 23:03:32 -05:00
|
|
|
uint chunk_num ) {
|
2012-08-06 00:01:42 -04:00
|
|
|
if ( !completion_string )
|
|
|
|
return std::string();
|
2013-01-19 23:03:32 -05:00
|
|
|
|
2012-08-06 00:01:42 -04:00
|
|
|
return YouCompleteMe::CXStringToString(
|
2013-01-19 23:03:32 -05:00
|
|
|
clang_getCompletionChunkText( completion_string, chunk_num ) );
|
2012-08-06 00:01:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string OptionalChunkToString( CXCompletionString completion_string,
|
2013-01-19 23:03:32 -05:00
|
|
|
uint chunk_num ) {
|
2012-08-06 00:01:42 -04:00
|
|
|
std::string final_string;
|
2013-01-19 23:03:32 -05:00
|
|
|
|
2012-08-06 00:01:42 -04:00
|
|
|
if ( !completion_string )
|
|
|
|
return final_string;
|
|
|
|
|
|
|
|
CXCompletionString optional_completion_string =
|
|
|
|
clang_getCompletionChunkCompletionString( completion_string, chunk_num );
|
|
|
|
|
|
|
|
if ( !optional_completion_string )
|
|
|
|
return final_string;
|
|
|
|
|
|
|
|
uint optional_num_chunks = clang_getNumCompletionChunks(
|
2013-01-19 23:03:32 -05:00
|
|
|
optional_completion_string );
|
2012-08-06 00:01:42 -04:00
|
|
|
|
2013-01-19 23:03:32 -05:00
|
|
|
for ( uint j = 0; j < optional_num_chunks; ++j ) {
|
2012-08-06 00:01:42 -04:00
|
|
|
CXCompletionChunkKind kind = clang_getCompletionChunkKind(
|
2013-01-19 23:03:32 -05:00
|
|
|
optional_completion_string, j );
|
2012-08-06 00:01:42 -04:00
|
|
|
|
2013-01-19 23:03:32 -05:00
|
|
|
if ( kind == CXCompletionChunk_Optional ) {
|
2012-08-06 00:01:42 -04:00
|
|
|
final_string.append( OptionalChunkToString( optional_completion_string,
|
|
|
|
j ) );
|
|
|
|
}
|
|
|
|
|
2013-01-19 23:03:32 -05:00
|
|
|
else {
|
2012-08-06 00:01:42 -04:00
|
|
|
final_string.append( ChunkToString( optional_completion_string, j ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return final_string;
|
|
|
|
}
|
|
|
|
|
2012-08-06 00:34:29 -04:00
|
|
|
|
|
|
|
// NOTE: this function accepts the text param by value on purpose; it internally
|
|
|
|
// needs a copy before processing the text so the copy might as well be made on
|
|
|
|
// the parameter BUT if this code is compiled in C++11 mode a move constructor
|
|
|
|
// can be called on the passed-in value. This is not possible if we accept the
|
|
|
|
// param by const ref.
|
2013-01-19 23:03:32 -05:00
|
|
|
std::string RemoveTwoConsecutiveUnderscores( std::string text ) {
|
2012-08-06 00:34:29 -04:00
|
|
|
boost::erase_all( text, "__" );
|
|
|
|
return text;
|
|
|
|
}
|
|
|
|
|
2012-08-06 00:01:42 -04:00
|
|
|
} // unnamed namespace
|
|
|
|
|
|
|
|
|
2013-01-19 23:03:32 -05:00
|
|
|
namespace YouCompleteMe {
|
2012-08-06 00:01:42 -04:00
|
|
|
|
2013-01-19 23:03:32 -05:00
|
|
|
CompletionData::CompletionData( const CXCompletionResult &completion_result ) {
|
2012-08-06 00:01:42 -04:00
|
|
|
CXCompletionString completion_string = completion_result.CompletionString;
|
|
|
|
|
|
|
|
if ( !completion_string )
|
|
|
|
return;
|
|
|
|
|
|
|
|
uint num_chunks = clang_getNumCompletionChunks( completion_string );
|
|
|
|
bool saw_left_paren = false;
|
|
|
|
bool saw_function_params = false;
|
|
|
|
|
2013-01-19 23:03:32 -05:00
|
|
|
for ( uint j = 0; j < num_chunks; ++j ) {
|
2012-08-06 00:43:38 -04:00
|
|
|
ExtractDataFromChunk( completion_string,
|
|
|
|
j,
|
|
|
|
saw_left_paren,
|
|
|
|
saw_function_params );
|
2012-08-06 00:01:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
kind_ = CursorKindToVimKind( completion_result.CursorKind );
|
2012-08-06 00:13:01 -04:00
|
|
|
|
2012-08-06 00:34:29 -04:00
|
|
|
// We remove any two consecutive underscores from the function definition
|
|
|
|
// since identifiers with them are ugly, compiler-reserved names. Functions
|
|
|
|
// from the standard library use parameter names like "__pos" and we want to
|
|
|
|
// show them as just "pos". This will never interfere with client code since
|
|
|
|
// ANY C++ identifier with two consecutive underscores in it is
|
|
|
|
// compiler-reserved.
|
|
|
|
everything_except_return_type_ =
|
2012-08-06 23:02:46 -04:00
|
|
|
RemoveTwoConsecutiveUnderscores(
|
2013-01-19 23:03:32 -05:00
|
|
|
boost::move( everything_except_return_type_ ) );
|
2012-08-06 00:34:29 -04:00
|
|
|
|
2012-08-06 00:13:01 -04:00
|
|
|
detailed_info_.append( return_type_ )
|
2013-01-19 23:03:32 -05:00
|
|
|
.append( " " )
|
|
|
|
.append( everything_except_return_type_ )
|
|
|
|
.append( "\n" );
|
2012-08-06 00:01:42 -04:00
|
|
|
}
|
|
|
|
|
2012-08-06 00:43:38 -04:00
|
|
|
|
|
|
|
void CompletionData::ExtractDataFromChunk( CXCompletionString completion_string,
|
|
|
|
uint chunk_num,
|
|
|
|
bool &saw_left_paren,
|
2013-01-19 23:03:32 -05:00
|
|
|
bool &saw_function_params ) {
|
2012-08-06 00:43:38 -04:00
|
|
|
CXCompletionChunkKind kind = clang_getCompletionChunkKind(
|
2013-01-19 23:03:32 -05:00
|
|
|
completion_string, chunk_num );
|
2012-08-06 00:43:38 -04:00
|
|
|
|
2013-01-19 23:03:32 -05:00
|
|
|
if ( IsMainCompletionTextInfo( kind ) ) {
|
|
|
|
if ( kind == CXCompletionChunk_LeftParen ) {
|
2012-08-06 00:43:38 -04:00
|
|
|
saw_left_paren = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
else if ( saw_left_paren &&
|
|
|
|
!saw_function_params &&
|
|
|
|
kind != CXCompletionChunk_RightParen &&
|
2013-01-19 23:03:32 -05:00
|
|
|
kind != CXCompletionChunk_Informative ) {
|
2012-08-06 00:43:38 -04:00
|
|
|
saw_function_params = true;
|
|
|
|
everything_except_return_type_.append( " " );
|
|
|
|
}
|
|
|
|
|
2013-01-19 23:03:32 -05:00
|
|
|
else if ( saw_function_params && kind == CXCompletionChunk_RightParen ) {
|
2012-08-06 00:43:38 -04:00
|
|
|
everything_except_return_type_.append( " " );
|
|
|
|
}
|
|
|
|
|
2013-01-19 23:03:32 -05:00
|
|
|
if ( kind == CXCompletionChunk_Optional ) {
|
2012-08-06 00:43:38 -04:00
|
|
|
everything_except_return_type_.append(
|
2013-01-19 23:03:32 -05:00
|
|
|
OptionalChunkToString( completion_string, chunk_num ) );
|
2012-08-06 00:43:38 -04:00
|
|
|
}
|
|
|
|
|
2013-01-19 23:03:32 -05:00
|
|
|
else {
|
2012-08-06 00:43:38 -04:00
|
|
|
everything_except_return_type_.append(
|
2013-01-19 23:03:32 -05:00
|
|
|
ChunkToString( completion_string, chunk_num ) );
|
2012-08-06 00:43:38 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( kind == CXCompletionChunk_ResultType )
|
|
|
|
return_type_ = ChunkToString( completion_string, chunk_num );
|
|
|
|
|
|
|
|
if ( kind == CXCompletionChunk_TypedText )
|
|
|
|
original_string_ = ChunkToString( completion_string, chunk_num );
|
|
|
|
}
|
|
|
|
|
2012-08-06 00:01:42 -04:00
|
|
|
} // namespace YouCompleteMe
|