diff --git a/cpp/ycm/ClangUtils.cpp b/cpp/ycm/ClangUtils.cpp index 16f384c6..859383a2 100644 --- a/cpp/ycm/ClangUtils.cpp +++ b/cpp/ycm/ClangUtils.cpp @@ -45,27 +45,6 @@ std::vector< CXUnsavedFile > ToCXUnsavedFiles( } -std::string CXStringToString( CXString text ) -{ - std::string final_string; - if ( !text.data ) - return final_string; - - final_string = std::string( clang_getCString( text ) ); - clang_disposeString( text ); - return final_string; -} - - -std::string ChunkToString( CXCompletionString completion_string, int chunk_num ) -{ - if ( !completion_string ) - return std::string(); - return CXStringToString( - clang_getCompletionChunkText( completion_string, chunk_num ) ); -} - - // Returns true when the provided completion string is available to the user; // unavailable completion strings refer to entities that are private/protected, // deprecated etc. @@ -78,63 +57,6 @@ bool CompletionStringAvailable( CXCompletionString completion_string ) } -bool IsMainCompletionTextInfo( CXCompletionChunkKind kind ) -{ - 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; - -} - - -char CursorKindToVimKind( CXCursorKind kind ) -{ - // TODO: actually it appears that Vim will show returned kinds even when they - // do not match the "approved" list, so let's use that - switch ( kind ) - { - case CXCursor_UnexposedDecl: - case CXCursor_StructDecl: - case CXCursor_UnionDecl: - case CXCursor_ClassDecl: - case CXCursor_EnumDecl: - case CXCursor_TypedefDecl: - return 't'; - - case CXCursor_FieldDecl: - return 'm'; - - case CXCursor_FunctionDecl: - case CXCursor_CXXMethod: - case CXCursor_FunctionTemplate: - return 'f'; - - case CXCursor_VarDecl: - return 'v'; - - case CXCursor_MacroDefinition: - return 'd'; - - default: - return 'u'; // for 'unknown', 'unsupported'... whatever you like - } -} - char DiagnosticSeverityToType( CXDiagnosticSeverity severity ) { @@ -157,61 +79,6 @@ char DiagnosticSeverityToType( CXDiagnosticSeverity severity ) } -// TODO: this should be a constructor -CompletionData CompletionResultToCompletionData( - const CXCompletionResult &completion_result ) -{ - CompletionData data; - CXCompletionString completion_string = completion_result.CompletionString; - - if ( !completion_string ) - return data; - - uint num_chunks = clang_getNumCompletionChunks( completion_string ); - bool saw_left_paren = false; - bool saw_function_params = false; - - for ( uint j = 0; j < num_chunks; ++j ) - { - CXCompletionChunkKind kind = clang_getCompletionChunkKind( - completion_string, j ); - - if ( IsMainCompletionTextInfo( kind ) ) - { - if ( kind == CXCompletionChunk_LeftParen ) - { - saw_left_paren = true; - } - - else if ( saw_left_paren && - !saw_function_params && - kind != CXCompletionChunk_RightParen ) - { - saw_function_params = true; - data.everything_except_return_type_.append( " " ); - } - - else if ( saw_function_params && kind == CXCompletionChunk_RightParen ) - { - data.everything_except_return_type_.append( " " ); - } - - data.everything_except_return_type_.append( - ChunkToString( completion_string, j ) ); - } - - if ( kind == CXCompletionChunk_ResultType ) - data.return_type_ = ChunkToString( completion_string, j ); - - if ( kind == CXCompletionChunk_TypedText ) - data.original_string_ = ChunkToString( completion_string, j ); - } - - data.kind_ = CursorKindToVimKind( completion_result.CursorKind ); - return data; -} - - std::vector< CompletionData > ToCompletionDataVector( CXCodeCompleteResults *results ) { @@ -229,14 +96,14 @@ std::vector< CompletionData > ToCompletionDataVector( if ( !CompletionStringAvailable( completion_result.CompletionString ) ) continue; - CompletionData data = CompletionResultToCompletionData( completion_result ); + CompletionData data( completion_result ); uint index = GetValueElseInsert( seen_data, data.original_string_, completions.size() ); if ( index == completions.size() ) { - completions.push_back( data ); + completions.push_back( boost::move( data ) ); } else diff --git a/cpp/ycm/CompletionData.cpp b/cpp/ycm/CompletionData.cpp new file mode 100644 index 00000000..b255855b --- /dev/null +++ b/cpp/ycm/CompletionData.cpp @@ -0,0 +1,205 @@ +// Copyright (C) 2011, 2012 Strahinja Val Markovic +// +// 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 . + +#include "CompletionData.h" +#include "standard.h" + +namespace +{ + +char CursorKindToVimKind( CXCursorKind kind ) +{ + // TODO: actually it appears that Vim will show returned kinds even when they + // do not match the "approved" list, so let's use that + switch ( kind ) + { + case CXCursor_UnexposedDecl: + case CXCursor_StructDecl: + case CXCursor_UnionDecl: + case CXCursor_ClassDecl: + case CXCursor_EnumDecl: + case CXCursor_TypedefDecl: + return 't'; + + case CXCursor_FieldDecl: + return 'm'; + + case CXCursor_FunctionDecl: + case CXCursor_CXXMethod: + case CXCursor_FunctionTemplate: + return 'f'; + + case CXCursor_VarDecl: + return 'v'; + + case CXCursor_MacroDefinition: + return 'd'; + + default: + return 'u'; // for 'unknown', 'unsupported'... whatever you like + } +} + + +bool IsMainCompletionTextInfo( CXCompletionChunkKind kind ) +{ + 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; + +} + + +std::string ChunkToString( CXCompletionString completion_string, int chunk_num ) +{ + if ( !completion_string ) + return std::string(); + return YouCompleteMe::CXStringToString( + clang_getCompletionChunkText( completion_string, chunk_num ) ); +} + + +std::string OptionalChunkToString( CXCompletionString completion_string, + int chunk_num ) +{ + std::string final_string; + 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( + optional_completion_string ); + + for ( uint j = 0; j < optional_num_chunks; ++j ) + { + CXCompletionChunkKind kind = clang_getCompletionChunkKind( + optional_completion_string, j ); + + if ( kind == CXCompletionChunk_Optional ) + { + final_string.append( OptionalChunkToString( optional_completion_string, + j ) ); + } + + else + { + final_string.append( ChunkToString( optional_completion_string, j ) ); + } + } + + return final_string; +} + +} // unnamed namespace + + +namespace YouCompleteMe +{ + +std::string CXStringToString( CXString text ) +{ + std::string final_string; + if ( !text.data ) + return final_string; + + final_string = std::string( clang_getCString( text ) ); + clang_disposeString( text ); + return final_string; +} + + +CompletionData::CompletionData( const CXCompletionResult &completion_result ) +{ + 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; + + for ( uint j = 0; j < num_chunks; ++j ) + { + CXCompletionChunkKind kind = clang_getCompletionChunkKind( + completion_string, j ); + + if ( IsMainCompletionTextInfo( kind ) ) + { + if ( kind == CXCompletionChunk_LeftParen ) + { + saw_left_paren = true; + } + + else if ( saw_left_paren && + !saw_function_params && + kind != CXCompletionChunk_RightParen && + kind != CXCompletionChunk_Informative ) + { + saw_function_params = true; + everything_except_return_type_.append( " " ); + } + + else if ( saw_function_params && kind == CXCompletionChunk_RightParen ) + { + everything_except_return_type_.append( " " ); + } + + if ( kind == CXCompletionChunk_Optional ) + { + everything_except_return_type_.append( + OptionalChunkToString( completion_string, j ) ); + } + + else + { + everything_except_return_type_.append( + ChunkToString( completion_string, j ) ); + } + } + + if ( kind == CXCompletionChunk_ResultType ) + return_type_ = ChunkToString( completion_string, j ); + + if ( kind == CXCompletionChunk_TypedText ) + original_string_ = ChunkToString( completion_string, j ); + } + + kind_ = CursorKindToVimKind( completion_result.CursorKind ); +} + +} // namespace YouCompleteMe diff --git a/cpp/ycm/CompletionData.h b/cpp/ycm/CompletionData.h index 7aa572d9..c4edfe15 100644 --- a/cpp/ycm/CompletionData.h +++ b/cpp/ycm/CompletionData.h @@ -19,10 +19,13 @@ #define COMPLETIONDATA_H_2JCTF1NU #include +#include namespace YouCompleteMe { +std::string CXStringToString( CXString text ); + // This class holds pieces of information about a single completion coming from // clang. These pieces are shown in Vim's UI in different ways. // @@ -37,6 +40,9 @@ namespace YouCompleteMe // about a completion at the top of the buffer. struct CompletionData { + CompletionData() {} + CompletionData( const CXCompletionResult &completion_result ); + // What should actually be inserted into the buffer. For a function like // "int foo(int x)", this is just "foo". Same for a data member like "foo_": // we insert just "foo_". diff --git a/cpp/ycm/standard.h b/cpp/ycm/standard.h index 6948332c..09f5be75 100644 --- a/cpp/ycm/standard.h +++ b/cpp/ycm/standard.h @@ -21,10 +21,4 @@ // it as BOOST_FOREACH. #define foreach BOOST_FOREACH - -namespace YouCompleteMe -{ - typedef unsigned int uint; - -} // namespace YouCompleteMe