Formatting the a part of the source with astyle
This commit is contained in:
parent
00db8fd8b1
commit
013a56c25c
@ -48,23 +48,19 @@ using boost::unique_future;
|
|||||||
using boost::unique_lock;
|
using boost::unique_lock;
|
||||||
using boost::unordered_map;
|
using boost::unordered_map;
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
extern const unsigned int MAX_ASYNC_THREADS;
|
extern const unsigned int MAX_ASYNC_THREADS;
|
||||||
extern const unsigned int MIN_ASYNC_THREADS;
|
extern const unsigned int MIN_ASYNC_THREADS;
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
{
|
|
||||||
|
|
||||||
struct CompletionDataAndResult
|
struct CompletionDataAndResult {
|
||||||
{
|
|
||||||
CompletionDataAndResult( const CompletionData *completion_data,
|
CompletionDataAndResult( const CompletionData *completion_data,
|
||||||
const Result &result )
|
const Result &result )
|
||||||
: completion_data_( completion_data ), result_( result ) {}
|
: completion_data_( completion_data ), result_( result ) {}
|
||||||
|
|
||||||
bool operator< ( const CompletionDataAndResult &other ) const
|
bool operator< ( const CompletionDataAndResult &other ) const {
|
||||||
{
|
|
||||||
return result_ < other.result_;
|
return result_ < other.result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,14 +76,12 @@ ClangCompleter::ClangCompleter()
|
|||||||
: candidate_repository_( CandidateRepository::Instance() ),
|
: candidate_repository_( CandidateRepository::Instance() ),
|
||||||
threading_enabled_( false ),
|
threading_enabled_( false ),
|
||||||
time_to_die_( false ),
|
time_to_die_( false ),
|
||||||
clang_data_ready_( false )
|
clang_data_ready_( false ) {
|
||||||
{
|
|
||||||
clang_index_ = clang_createIndex( 0, 0 );
|
clang_index_ = clang_createIndex( 0, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ClangCompleter::~ClangCompleter()
|
ClangCompleter::~ClangCompleter() {
|
||||||
{
|
|
||||||
// We need to clear this before calling clang_disposeIndex because the
|
// We need to clear this before calling clang_disposeIndex because the
|
||||||
// translation units need to be destroyed before the index is destroyed.
|
// translation units need to be destroyed before the index is destroyed.
|
||||||
filename_to_translation_unit_.clear();
|
filename_to_translation_unit_.clear();
|
||||||
@ -109,23 +103,21 @@ ClangCompleter::~ClangCompleter()
|
|||||||
// We need this mostly so that we can not use it in tests. Apparently the
|
// We need this mostly so that we can not use it in tests. Apparently the
|
||||||
// GoogleTest framework goes apeshit on us (on some platforms, in some
|
// GoogleTest framework goes apeshit on us (on some platforms, in some
|
||||||
// occasions) if we enable threads by default.
|
// occasions) if we enable threads by default.
|
||||||
void ClangCompleter::EnableThreading()
|
void ClangCompleter::EnableThreading() {
|
||||||
{
|
|
||||||
threading_enabled_ = true;
|
threading_enabled_ = true;
|
||||||
InitThreads();
|
InitThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector< Diagnostic > ClangCompleter::DiagnosticsForFile(
|
std::vector< Diagnostic > ClangCompleter::DiagnosticsForFile(
|
||||||
const std::string &filename )
|
const std::string &filename ) {
|
||||||
{
|
|
||||||
shared_ptr< TranslationUnit > unit;
|
shared_ptr< TranslationUnit > unit;
|
||||||
{
|
{
|
||||||
lock_guard< mutex > lock( filename_to_translation_unit_mutex_ );
|
lock_guard< mutex > lock( filename_to_translation_unit_mutex_ );
|
||||||
unit = FindWithDefault(
|
unit = FindWithDefault(
|
||||||
filename_to_translation_unit_,
|
filename_to_translation_unit_,
|
||||||
filename,
|
filename,
|
||||||
shared_ptr< TranslationUnit >() );
|
shared_ptr< TranslationUnit >() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !unit )
|
if ( !unit )
|
||||||
@ -135,15 +127,14 @@ std::vector< Diagnostic > ClangCompleter::DiagnosticsForFile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ClangCompleter::UpdatingTranslationUnit( const std::string &filename )
|
bool ClangCompleter::UpdatingTranslationUnit( const std::string &filename ) {
|
||||||
{
|
|
||||||
shared_ptr< TranslationUnit > unit;
|
shared_ptr< TranslationUnit > unit;
|
||||||
{
|
{
|
||||||
lock_guard< mutex > lock( filename_to_translation_unit_mutex_ );
|
lock_guard< mutex > lock( filename_to_translation_unit_mutex_ );
|
||||||
unit = FindWithDefault(
|
unit = FindWithDefault(
|
||||||
filename_to_translation_unit_,
|
filename_to_translation_unit_,
|
||||||
filename,
|
filename,
|
||||||
shared_ptr< TranslationUnit >() );
|
shared_ptr< TranslationUnit >() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !unit )
|
if ( !unit )
|
||||||
@ -154,30 +145,27 @@ bool ClangCompleter::UpdatingTranslationUnit( const std::string &filename )
|
|||||||
|
|
||||||
|
|
||||||
void ClangCompleter::UpdateTranslationUnit(
|
void ClangCompleter::UpdateTranslationUnit(
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags )
|
const std::vector< std::string > &flags ) {
|
||||||
{
|
|
||||||
bool translation_unit_created;
|
bool translation_unit_created;
|
||||||
shared_ptr< TranslationUnit > unit = GetTranslationUnitForFile(
|
shared_ptr< TranslationUnit > unit = GetTranslationUnitForFile(
|
||||||
filename,
|
filename,
|
||||||
unsaved_files,
|
unsaved_files,
|
||||||
flags,
|
flags,
|
||||||
translation_unit_created );
|
translation_unit_created );
|
||||||
|
|
||||||
if ( !unit )
|
if ( !unit )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
// There's no point in reparsing a TU that was just created, it was just
|
// There's no point in reparsing a TU that was just created, it was just
|
||||||
// parsed in the TU constructor
|
// parsed in the TU constructor
|
||||||
if ( !translation_unit_created )
|
if ( !translation_unit_created )
|
||||||
unit->Reparse( unsaved_files );
|
unit->Reparse( unsaved_files );
|
||||||
}
|
}
|
||||||
|
|
||||||
catch ( ClangParseError& )
|
catch ( ClangParseError & ) {
|
||||||
{
|
|
||||||
lock_guard< mutex > lock( filename_to_translation_unit_mutex_ );
|
lock_guard< mutex > lock( filename_to_translation_unit_mutex_ );
|
||||||
|
|
||||||
// If unit->Reparse fails, then the underlying TranslationUnit object is not
|
// If unit->Reparse fails, then the underlying TranslationUnit object is not
|
||||||
@ -189,10 +177,9 @@ void ClangCompleter::UpdateTranslationUnit(
|
|||||||
|
|
||||||
|
|
||||||
Future< void > ClangCompleter::UpdateTranslationUnitAsync(
|
Future< void > ClangCompleter::UpdateTranslationUnitAsync(
|
||||||
std::string filename,
|
std::string filename,
|
||||||
std::vector< UnsavedFile > unsaved_files,
|
std::vector< UnsavedFile > unsaved_files,
|
||||||
std::vector< std::string > flags )
|
std::vector< std::string > flags ) {
|
||||||
{
|
|
||||||
function< void() > functor =
|
function< void() > functor =
|
||||||
bind( &ClangCompleter::UpdateTranslationUnit,
|
bind( &ClangCompleter::UpdateTranslationUnit,
|
||||||
boost::ref( *this ),
|
boost::ref( *this ),
|
||||||
@ -214,15 +201,15 @@ Future< void > ClangCompleter::UpdateTranslationUnitAsync(
|
|||||||
|
|
||||||
std::vector< CompletionData >
|
std::vector< CompletionData >
|
||||||
ClangCompleter::CandidatesForLocationInFile(
|
ClangCompleter::CandidatesForLocationInFile(
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
int line,
|
int line,
|
||||||
int column,
|
int column,
|
||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags )
|
const std::vector< std::string > &flags ) {
|
||||||
{
|
|
||||||
shared_ptr< TranslationUnit > unit = GetTranslationUnitForFile( filename,
|
shared_ptr< TranslationUnit > unit = GetTranslationUnitForFile( filename,
|
||||||
unsaved_files,
|
unsaved_files,
|
||||||
flags );
|
flags );
|
||||||
|
|
||||||
if ( !unit )
|
if ( !unit )
|
||||||
return std::vector< CompletionData >();
|
return std::vector< CompletionData >();
|
||||||
|
|
||||||
@ -234,13 +221,12 @@ ClangCompleter::CandidatesForLocationInFile(
|
|||||||
|
|
||||||
Future< AsyncCompletions >
|
Future< AsyncCompletions >
|
||||||
ClangCompleter::CandidatesForQueryAndLocationInFileAsync(
|
ClangCompleter::CandidatesForQueryAndLocationInFileAsync(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
int line,
|
int line,
|
||||||
int column,
|
int column,
|
||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags )
|
const std::vector< std::string > &flags ) {
|
||||||
{
|
|
||||||
// TODO: throw exception when threading is not enabled and this is called
|
// TODO: throw exception when threading is not enabled and this is called
|
||||||
if ( !threading_enabled_ )
|
if ( !threading_enabled_ )
|
||||||
return Future< AsyncCompletions >();
|
return Future< AsyncCompletions >();
|
||||||
@ -248,8 +234,8 @@ ClangCompleter::CandidatesForQueryAndLocationInFileAsync(
|
|||||||
bool skip_clang_result_cache = ShouldSkipClangResultCache( query,
|
bool skip_clang_result_cache = ShouldSkipClangResultCache( query,
|
||||||
line,
|
line,
|
||||||
column );
|
column );
|
||||||
if ( skip_clang_result_cache )
|
|
||||||
{
|
if ( skip_clang_result_cache ) {
|
||||||
// The clang thread is busy, return nothing
|
// The clang thread is busy, return nothing
|
||||||
if ( UpdatingTranslationUnit( filename ) )
|
if ( UpdatingTranslationUnit( filename ) )
|
||||||
return Future< AsyncCompletions >();
|
return Future< AsyncCompletions >();
|
||||||
@ -271,8 +257,7 @@ ClangCompleter::CandidatesForQueryAndLocationInFileAsync(
|
|||||||
unique_future< AsyncCompletions > future;
|
unique_future< AsyncCompletions > future;
|
||||||
CreateSortingTask( query, future );
|
CreateSortingTask( query, future );
|
||||||
|
|
||||||
if ( skip_clang_result_cache )
|
if ( skip_clang_result_cache ) {
|
||||||
{
|
|
||||||
CreateClangTask( filename, line, column, unsaved_files, flags );
|
CreateClangTask( filename, line, column, unsaved_files, flags );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,8 +267,7 @@ ClangCompleter::CandidatesForQueryAndLocationInFileAsync(
|
|||||||
|
|
||||||
bool ClangCompleter::ShouldSkipClangResultCache( const std::string &query,
|
bool ClangCompleter::ShouldSkipClangResultCache( const std::string &query,
|
||||||
int line,
|
int line,
|
||||||
int column )
|
int column ) {
|
||||||
{
|
|
||||||
// We need query.empty() in addition to the second check because if we don't
|
// We need query.empty() in addition to the second check because if we don't
|
||||||
// have it, then we have a problem in the following situation:
|
// have it, then we have a problem in the following situation:
|
||||||
// The user has a variable 'foo' of type 'A' and a variable 'bar' of type 'B'.
|
// The user has a variable 'foo' of type 'A' and a variable 'bar' of type 'B'.
|
||||||
@ -292,20 +276,19 @@ bool ClangCompleter::ShouldSkipClangResultCache( const std::string &query,
|
|||||||
// query.empty() check we would return the results from the cache here (it's
|
// query.empty() check we would return the results from the cache here (it's
|
||||||
// the same line and column!) which would be incorrect.
|
// the same line and column!) which would be incorrect.
|
||||||
return query.empty() || latest_clang_results_
|
return query.empty() || latest_clang_results_
|
||||||
.NewPositionDifferentFromStoredPosition( line, column );
|
.NewPositionDifferentFromStoredPosition( line, column );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Copy-ctor for unique_future is private in C++03 mode so we need to take it as
|
// Copy-ctor for unique_future is private in C++03 mode so we need to take it as
|
||||||
// an out param
|
// an out param
|
||||||
void ClangCompleter::CreateSortingTask(
|
void ClangCompleter::CreateSortingTask(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
unique_future< AsyncCompletions > &future )
|
unique_future< AsyncCompletions > &future ) {
|
||||||
{
|
|
||||||
// Careful! The code in this function may burn your eyes.
|
// Careful! The code in this function may burn your eyes.
|
||||||
|
|
||||||
function< CompletionDatas( const CompletionDatas& ) >
|
function< CompletionDatas( const CompletionDatas & ) >
|
||||||
sort_candidates_for_query_functor =
|
sort_candidates_for_query_functor =
|
||||||
bind( &ClangCompleter::SortCandidatesForQuery,
|
bind( &ClangCompleter::SortCandidatesForQuery,
|
||||||
boost::ref( *this ),
|
boost::ref( *this ),
|
||||||
query,
|
query,
|
||||||
@ -327,39 +310,38 @@ void ClangCompleter::CreateSortingTask(
|
|||||||
|
|
||||||
|
|
||||||
void ClangCompleter::CreateClangTask(
|
void ClangCompleter::CreateClangTask(
|
||||||
std::string filename,
|
std::string filename,
|
||||||
int line,
|
int line,
|
||||||
int column,
|
int column,
|
||||||
std::vector< UnsavedFile > unsaved_files,
|
std::vector< UnsavedFile > unsaved_files,
|
||||||
std::vector< std::string > flags )
|
std::vector< std::string > flags ) {
|
||||||
{
|
latest_clang_results_.ResetWithNewLineAndColumn( line, column );
|
||||||
latest_clang_results_.ResetWithNewLineAndColumn( line, column );
|
|
||||||
|
|
||||||
function< CompletionDatas() > candidates_for_location_functor =
|
function< CompletionDatas() > candidates_for_location_functor =
|
||||||
bind( &ClangCompleter::CandidatesForLocationInFile,
|
bind( &ClangCompleter::CandidatesForLocationInFile,
|
||||||
boost::ref( *this ),
|
boost::ref( *this ),
|
||||||
boost::move( filename ),
|
boost::move( filename ),
|
||||||
line,
|
line,
|
||||||
column,
|
column,
|
||||||
boost::move( unsaved_files ),
|
boost::move( unsaved_files ),
|
||||||
boost::move( flags ) );
|
boost::move( flags ) );
|
||||||
|
|
||||||
shared_ptr< ClangPackagedTask > clang_packaged_task =
|
shared_ptr< ClangPackagedTask > clang_packaged_task =
|
||||||
make_shared< ClangPackagedTask >();
|
make_shared< ClangPackagedTask >();
|
||||||
|
|
||||||
clang_packaged_task->completions_task_ = packaged_task< AsyncCompletions >(
|
clang_packaged_task->completions_task_ =
|
||||||
bind( ReturnValueAsShared< std::vector< CompletionData > >,
|
packaged_task< AsyncCompletions >(
|
||||||
candidates_for_location_functor ) );
|
bind( ReturnValueAsShared< std::vector< CompletionData > >,
|
||||||
|
candidates_for_location_functor ) );
|
||||||
|
|
||||||
clang_task_.Set( clang_packaged_task );
|
clang_task_.Set( clang_packaged_task );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
boost::shared_ptr< TranslationUnit > ClangCompleter::GetTranslationUnitForFile(
|
boost::shared_ptr< TranslationUnit > ClangCompleter::GetTranslationUnitForFile(
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags )
|
const std::vector< std::string > &flags ) {
|
||||||
{
|
|
||||||
bool dont_care;
|
bool dont_care;
|
||||||
return GetTranslationUnitForFile( filename, unsaved_files, flags, dont_care );
|
return GetTranslationUnitForFile( filename, unsaved_files, flags, dont_care );
|
||||||
}
|
}
|
||||||
@ -371,18 +353,16 @@ boost::shared_ptr< TranslationUnit > ClangCompleter::GetTranslationUnitForFile(
|
|||||||
// the future a mutex will be needed to make sure that two threads don't try to
|
// the future a mutex will be needed to make sure that two threads don't try to
|
||||||
// create the same translation unit.
|
// create the same translation unit.
|
||||||
shared_ptr< TranslationUnit > ClangCompleter::GetTranslationUnitForFile(
|
shared_ptr< TranslationUnit > ClangCompleter::GetTranslationUnitForFile(
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags,
|
const std::vector< std::string > &flags,
|
||||||
bool &translation_unit_created )
|
bool &translation_unit_created ) {
|
||||||
{
|
|
||||||
{
|
{
|
||||||
lock_guard< mutex > lock( filename_to_translation_unit_mutex_ );
|
lock_guard< mutex > lock( filename_to_translation_unit_mutex_ );
|
||||||
TranslationUnitForFilename::iterator it =
|
TranslationUnitForFilename::iterator it =
|
||||||
filename_to_translation_unit_.find( filename );
|
filename_to_translation_unit_.find( filename );
|
||||||
|
|
||||||
if ( it != filename_to_translation_unit_.end() )
|
if ( it != filename_to_translation_unit_.end() ) {
|
||||||
{
|
|
||||||
translation_unit_created = false;
|
translation_unit_created = false;
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
@ -390,14 +370,12 @@ shared_ptr< TranslationUnit > ClangCompleter::GetTranslationUnitForFile(
|
|||||||
|
|
||||||
shared_ptr< TranslationUnit > unit;
|
shared_ptr< TranslationUnit > unit;
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
unit = make_shared< TranslationUnit >(
|
unit = make_shared< TranslationUnit >(
|
||||||
filename, unsaved_files, flags, clang_index_ );
|
filename, unsaved_files, flags, clang_index_ );
|
||||||
}
|
}
|
||||||
|
|
||||||
catch ( ClangParseError& )
|
catch ( ClangParseError & ) {
|
||||||
{
|
|
||||||
return unit;
|
return unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,25 +390,24 @@ shared_ptr< TranslationUnit > ClangCompleter::GetTranslationUnitForFile(
|
|||||||
|
|
||||||
|
|
||||||
std::vector< CompletionData > ClangCompleter::SortCandidatesForQuery(
|
std::vector< CompletionData > ClangCompleter::SortCandidatesForQuery(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
const std::vector< CompletionData > &completion_datas )
|
const std::vector< CompletionData > &completion_datas ) {
|
||||||
{
|
|
||||||
Bitset query_bitset = LetterBitsetFromString( query );
|
Bitset query_bitset = LetterBitsetFromString( query );
|
||||||
|
|
||||||
std::vector< const Candidate* > repository_candidates =
|
std::vector< const Candidate * > repository_candidates =
|
||||||
candidate_repository_.GetCandidatesForStrings( completion_datas );
|
candidate_repository_.GetCandidatesForStrings( completion_datas );
|
||||||
|
|
||||||
std::vector< CompletionDataAndResult > data_and_results;
|
std::vector< CompletionDataAndResult > data_and_results;
|
||||||
|
|
||||||
for ( uint i = 0; i < repository_candidates.size(); ++i )
|
for ( uint i = 0; i < repository_candidates.size(); ++i ) {
|
||||||
{
|
const Candidate *candidate = repository_candidates[ i ];
|
||||||
const Candidate* candidate = repository_candidates[ i ];
|
|
||||||
if ( !candidate->MatchesQueryBitset( query_bitset ) )
|
if ( !candidate->MatchesQueryBitset( query_bitset ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Result result = candidate->QueryMatchResult( query );
|
Result result = candidate->QueryMatchResult( query );
|
||||||
if ( result.IsSubsequence() )
|
|
||||||
{
|
if ( result.IsSubsequence() ) {
|
||||||
CompletionDataAndResult data_and_result( &completion_datas[ i ], result );
|
CompletionDataAndResult data_and_result( &completion_datas[ i ], result );
|
||||||
data_and_results.push_back( data_and_result );
|
data_and_results.push_back( data_and_result );
|
||||||
}
|
}
|
||||||
@ -441,8 +418,7 @@ std::vector< CompletionData > ClangCompleter::SortCandidatesForQuery(
|
|||||||
std::vector< CompletionData > sorted_completion_datas;
|
std::vector< CompletionData > sorted_completion_datas;
|
||||||
sorted_completion_datas.reserve( data_and_results.size() );
|
sorted_completion_datas.reserve( data_and_results.size() );
|
||||||
|
|
||||||
foreach ( const CompletionDataAndResult& data_and_result, data_and_results )
|
foreach ( const CompletionDataAndResult & data_and_result, data_and_results ) {
|
||||||
{
|
|
||||||
sorted_completion_datas.push_back( *data_and_result.completion_data_ );
|
sorted_completion_datas.push_back( *data_and_result.completion_data_ );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,14 +426,12 @@ std::vector< CompletionData > ClangCompleter::SortCandidatesForQuery(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ClangCompleter::InitThreads()
|
void ClangCompleter::InitThreads() {
|
||||||
{
|
|
||||||
int threads_to_create =
|
int threads_to_create =
|
||||||
std::max( MIN_ASYNC_THREADS,
|
std::max( MIN_ASYNC_THREADS,
|
||||||
std::min( MAX_ASYNC_THREADS, thread::hardware_concurrency() ) );
|
std::min( MAX_ASYNC_THREADS, thread::hardware_concurrency() ) );
|
||||||
|
|
||||||
for ( int i = 0; i < threads_to_create; ++i )
|
for ( int i = 0; i < threads_to_create; ++i ) {
|
||||||
{
|
|
||||||
sorting_threads_.create_thread( bind( &ClangCompleter::SortingThreadMain,
|
sorting_threads_.create_thread( bind( &ClangCompleter::SortingThreadMain,
|
||||||
boost::ref( *this ) ) );
|
boost::ref( *this ) ) );
|
||||||
}
|
}
|
||||||
@ -467,15 +441,13 @@ void ClangCompleter::InitThreads()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ClangCompleter::ClangThreadMain()
|
void ClangCompleter::ClangThreadMain() {
|
||||||
{
|
while ( true ) {
|
||||||
while ( true )
|
try {
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
shared_ptr< ClangPackagedTask > task = clang_task_.Get();
|
shared_ptr< ClangPackagedTask > task = clang_task_.Get();
|
||||||
|
|
||||||
bool has_completions_task = task->completions_task_.valid();
|
bool has_completions_task = task->completions_task_.valid();
|
||||||
|
|
||||||
if ( has_completions_task )
|
if ( has_completions_task )
|
||||||
task->completions_task_();
|
task->completions_task_();
|
||||||
else
|
else
|
||||||
@ -496,28 +468,25 @@ void ClangCompleter::ClangThreadMain()
|
|||||||
clang_data_ready_condition_variable_.notify_all();
|
clang_data_ready_condition_variable_.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
catch ( thread_interrupted& )
|
catch ( thread_interrupted & ) {
|
||||||
{
|
|
||||||
shared_lock< shared_mutex > lock( time_to_die_mutex_ );
|
shared_lock< shared_mutex > lock( time_to_die_mutex_ );
|
||||||
|
|
||||||
if ( time_to_die_ )
|
if ( time_to_die_ )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// else do nothing and re-enter the loop
|
// else do nothing and re-enter the loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ClangCompleter::SortingThreadMain()
|
void ClangCompleter::SortingThreadMain() {
|
||||||
{
|
while ( true ) {
|
||||||
while ( true )
|
try {
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
{
|
{
|
||||||
unique_lock< mutex > lock( clang_data_ready_mutex_ );
|
unique_lock< mutex > lock( clang_data_ready_mutex_ );
|
||||||
|
|
||||||
while ( !clang_data_ready_ )
|
while ( !clang_data_ready_ ) {
|
||||||
{
|
|
||||||
clang_data_ready_condition_variable_.wait( lock );
|
clang_data_ready_condition_variable_.wait( lock );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -528,11 +497,12 @@ void ClangCompleter::SortingThreadMain()
|
|||||||
( *task )();
|
( *task )();
|
||||||
}
|
}
|
||||||
|
|
||||||
catch ( thread_interrupted& )
|
catch ( thread_interrupted & ) {
|
||||||
{
|
|
||||||
shared_lock< shared_mutex > lock( time_to_die_mutex_ );
|
shared_lock< shared_mutex > lock( time_to_die_mutex_ );
|
||||||
|
|
||||||
if ( time_to_die_ )
|
if ( time_to_die_ )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// else do nothing and re-enter the loop
|
// else do nothing and re-enter the loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,7 @@
|
|||||||
typedef void *CXIndex;
|
typedef void *CXIndex;
|
||||||
typedef struct CXTranslationUnitImpl *CXTranslationUnit;
|
typedef struct CXTranslationUnitImpl *CXTranslationUnit;
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
class CandidateRepository;
|
class CandidateRepository;
|
||||||
class TranslationUnit;
|
class TranslationUnit;
|
||||||
@ -44,17 +43,16 @@ typedef std::vector< CompletionData > CompletionDatas;
|
|||||||
|
|
||||||
typedef boost::shared_ptr< CompletionDatas > AsyncCompletions;
|
typedef boost::shared_ptr< CompletionDatas > AsyncCompletions;
|
||||||
|
|
||||||
typedef boost::unordered_map< std::string,
|
typedef boost::unordered_map < std::string,
|
||||||
boost::shared_ptr<
|
boost::shared_ptr <
|
||||||
std::vector< std::string > > > FlagsForFile;
|
std::vector< std::string > > > FlagsForFile;
|
||||||
|
|
||||||
typedef boost::unordered_map< std::string,
|
typedef boost::unordered_map < std::string,
|
||||||
boost::shared_ptr< TranslationUnit > > TranslationUnitForFilename;
|
boost::shared_ptr< TranslationUnit > > TranslationUnitForFilename;
|
||||||
|
|
||||||
|
|
||||||
// TODO: document that all filename parameters must be absolute paths
|
// TODO: document that all filename parameters must be absolute paths
|
||||||
class ClangCompleter : boost::noncopyable
|
class ClangCompleter : boost::noncopyable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
ClangCompleter();
|
ClangCompleter();
|
||||||
~ClangCompleter();
|
~ClangCompleter();
|
||||||
@ -67,49 +65,48 @@ public:
|
|||||||
|
|
||||||
// Public because of unit tests (gtest is not very thread-friendly)
|
// Public because of unit tests (gtest is not very thread-friendly)
|
||||||
void UpdateTranslationUnit(
|
void UpdateTranslationUnit(
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags );
|
const std::vector< std::string > &flags );
|
||||||
|
|
||||||
// NOTE: params are taken by value on purpose! With a C++11 compiler we can
|
// NOTE: params are taken by value on purpose! With a C++11 compiler we can
|
||||||
// avoid internal copies if params are taken by value (move ctors FTW)
|
// avoid internal copies if params are taken by value (move ctors FTW)
|
||||||
Future< void > UpdateTranslationUnitAsync(
|
Future< void > UpdateTranslationUnitAsync(
|
||||||
std::string filename,
|
std::string filename,
|
||||||
std::vector< UnsavedFile > unsaved_files,
|
std::vector< UnsavedFile > unsaved_files,
|
||||||
std::vector< std::string > flags );
|
std::vector< std::string > flags );
|
||||||
|
|
||||||
// Public because of unit tests (gtest is not very thread-friendly)
|
// Public because of unit tests (gtest is not very thread-friendly)
|
||||||
std::vector< CompletionData > CandidatesForLocationInFile(
|
std::vector< CompletionData > CandidatesForLocationInFile(
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
int line,
|
int line,
|
||||||
int column,
|
int column,
|
||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags );
|
const std::vector< std::string > &flags );
|
||||||
|
|
||||||
Future< AsyncCompletions > CandidatesForQueryAndLocationInFileAsync(
|
Future< AsyncCompletions > CandidatesForQueryAndLocationInFileAsync(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
int line,
|
int line,
|
||||||
int column,
|
int column,
|
||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags );
|
const std::vector< std::string > &flags );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// This is basically a union. Only one of the two tasks is set to something
|
// This is basically a union. Only one of the two tasks is set to something
|
||||||
// valid, the other task is invalid. Which one is valid depends on the caller.
|
// valid, the other task is invalid. Which one is valid depends on the caller.
|
||||||
struct ClangPackagedTask
|
struct ClangPackagedTask {
|
||||||
{
|
|
||||||
boost::packaged_task< AsyncCompletions > completions_task_;
|
boost::packaged_task< AsyncCompletions > completions_task_;
|
||||||
boost::packaged_task< void > parsing_task_;
|
boost::packaged_task< void > parsing_task_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ConcurrentLatestValue<
|
typedef ConcurrentLatestValue <
|
||||||
boost::shared_ptr<
|
boost::shared_ptr <
|
||||||
boost::packaged_task< AsyncCompletions > > > LatestSortingTask;
|
boost::packaged_task< AsyncCompletions > > > LatestSortingTask;
|
||||||
|
|
||||||
typedef ConcurrentLatestValue<
|
typedef ConcurrentLatestValue <
|
||||||
boost::shared_ptr< ClangPackagedTask > > LatestClangTask;
|
boost::shared_ptr< ClangPackagedTask > > LatestClangTask;
|
||||||
|
|
||||||
bool ShouldSkipClangResultCache( const std::string &query,
|
bool ShouldSkipClangResultCache( const std::string &query,
|
||||||
int line,
|
int line,
|
||||||
@ -121,26 +118,26 @@ private:
|
|||||||
// NOTE: params are taken by value on purpose! With a C++11 compiler we can
|
// NOTE: params are taken by value on purpose! With a C++11 compiler we can
|
||||||
// avoid internal copies if params are taken by value (move ctors FTW)
|
// avoid internal copies if params are taken by value (move ctors FTW)
|
||||||
void CreateClangTask(
|
void CreateClangTask(
|
||||||
std::string filename,
|
std::string filename,
|
||||||
int line,
|
int line,
|
||||||
int column,
|
int column,
|
||||||
std::vector< UnsavedFile > unsaved_files,
|
std::vector< UnsavedFile > unsaved_files,
|
||||||
std::vector< std::string > flags );
|
std::vector< std::string > flags );
|
||||||
|
|
||||||
boost::shared_ptr< TranslationUnit > GetTranslationUnitForFile(
|
boost::shared_ptr< TranslationUnit > GetTranslationUnitForFile(
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags );
|
const std::vector< std::string > &flags );
|
||||||
|
|
||||||
boost::shared_ptr< TranslationUnit > GetTranslationUnitForFile(
|
boost::shared_ptr< TranslationUnit > GetTranslationUnitForFile(
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags,
|
const std::vector< std::string > &flags,
|
||||||
bool &translation_unit_created );
|
bool &translation_unit_created );
|
||||||
|
|
||||||
std::vector< CompletionData > SortCandidatesForQuery(
|
std::vector< CompletionData > SortCandidatesForQuery(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
const std::vector< CompletionData > &completion_datas );
|
const std::vector< CompletionData > &completion_datas );
|
||||||
|
|
||||||
void InitThreads();
|
void InitThreads();
|
||||||
|
|
||||||
|
@ -22,19 +22,17 @@ using boost::shared_mutex;
|
|||||||
using boost::shared_lock;
|
using boost::shared_lock;
|
||||||
using boost::unique_lock;
|
using boost::unique_lock;
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
bool ClangResultsCache::NewPositionDifferentFromStoredPosition( int new_line,
|
bool ClangResultsCache::NewPositionDifferentFromStoredPosition( int new_line,
|
||||||
int new_colum )
|
int new_colum )
|
||||||
const
|
const {
|
||||||
{
|
|
||||||
shared_lock< shared_mutex > reader_lock( access_mutex_ );
|
shared_lock< shared_mutex > reader_lock( access_mutex_ );
|
||||||
return line_ != new_line || column_ != new_colum;
|
return line_ != new_line || column_ != new_colum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangResultsCache::ResetWithNewLineAndColumn( int new_line, int new_colum )
|
void ClangResultsCache::ResetWithNewLineAndColumn( int new_line,
|
||||||
{
|
int new_colum ) {
|
||||||
unique_lock< shared_mutex > reader_lock( access_mutex_ );
|
unique_lock< shared_mutex > reader_lock( access_mutex_ );
|
||||||
|
|
||||||
line_ = new_line;
|
line_ = new_line;
|
||||||
|
@ -27,24 +27,22 @@
|
|||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
struct CompletionData;
|
struct CompletionData;
|
||||||
|
|
||||||
class ClangResultsCache : boost::noncopyable
|
class ClangResultsCache : boost::noncopyable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ClangResultsCache() : line_( -1 ), column_( -1 ) {}
|
ClangResultsCache() : line_( -1 ), column_( -1 ) {}
|
||||||
|
|
||||||
bool NewPositionDifferentFromStoredPosition( int new_line, int new_colum )
|
bool NewPositionDifferentFromStoredPosition( int new_line, int new_colum )
|
||||||
const;
|
const;
|
||||||
|
|
||||||
void ResetWithNewLineAndColumn( int new_line, int new_colum );
|
void ResetWithNewLineAndColumn( int new_line, int new_colum );
|
||||||
|
|
||||||
void SetCompletionDatas( const std::vector< CompletionData > new_completions )
|
void SetCompletionDatas(
|
||||||
{
|
const std::vector< CompletionData > new_completions ) {
|
||||||
completion_datas_ = new_completions;
|
completion_datas_ = new_completions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,8 +52,7 @@ public:
|
|||||||
# pragma clang diagnostic ignored "-Wc++98-compat"
|
# pragma clang diagnostic ignored "-Wc++98-compat"
|
||||||
# endif //#ifdef __clang__
|
# endif //#ifdef __clang__
|
||||||
|
|
||||||
void SetCompletionDatas( std::vector< CompletionData >&& new_completions )
|
void SetCompletionDatas( std::vector< CompletionData > && new_completions ) {
|
||||||
{
|
|
||||||
completion_datas_ = new_completions;
|
completion_datas_ = new_completions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,9 +63,8 @@ public:
|
|||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
T OperateOnCompletionDatas(
|
T OperateOnCompletionDatas(
|
||||||
boost::function< T( const std::vector< CompletionData >& ) > operation )
|
boost::function< T( const std::vector< CompletionData >& ) > operation )
|
||||||
const
|
const {
|
||||||
{
|
|
||||||
boost::shared_lock< boost::shared_mutex > reader_lock( access_mutex_ );
|
boost::shared_lock< boost::shared_mutex > reader_lock( access_mutex_ );
|
||||||
return operation( completion_datas_ );
|
return operation( completion_datas_ );
|
||||||
}
|
}
|
||||||
|
@ -26,12 +26,11 @@
|
|||||||
#include <boost/unordered_map.hpp>
|
#include <boost/unordered_map.hpp>
|
||||||
using boost::unordered_map;
|
using boost::unordered_map;
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
std::string CXStringToString( CXString text )
|
std::string CXStringToString( CXString text ) {
|
||||||
{
|
|
||||||
std::string final_string;
|
std::string final_string;
|
||||||
|
|
||||||
if ( !text.data )
|
if ( !text.data )
|
||||||
return final_string;
|
return final_string;
|
||||||
|
|
||||||
@ -40,30 +39,31 @@ std::string CXStringToString( CXString text )
|
|||||||
return final_string;
|
return final_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
{
|
|
||||||
|
|
||||||
// NOTE: The passed in pointer should never be NULL!
|
// NOTE: The passed in pointer should never be NULL!
|
||||||
std::string FullDiagnosticText( CXDiagnostic cxdiagnostic )
|
std::string FullDiagnosticText( CXDiagnostic cxdiagnostic ) {
|
||||||
{
|
std::string full_text = CXStringToString(
|
||||||
std::string full_text = CXStringToString( clang_formatDiagnostic(
|
clang_formatDiagnostic(
|
||||||
cxdiagnostic,
|
cxdiagnostic,
|
||||||
clang_defaultDiagnosticDisplayOptions() ) );
|
clang_defaultDiagnosticDisplayOptions() ) );
|
||||||
|
|
||||||
// Note: clang docs say that a CXDiagnosticSet retrieved with
|
// Note: clang docs say that a CXDiagnosticSet retrieved with
|
||||||
// clang_getChildDiagnostics do NOT need to be released with
|
// clang_getChildDiagnostics do NOT need to be released with
|
||||||
// clang_diposeDiagnosticSet
|
// clang_diposeDiagnosticSet
|
||||||
CXDiagnosticSet diag_set = clang_getChildDiagnostics( cxdiagnostic );
|
CXDiagnosticSet diag_set = clang_getChildDiagnostics( cxdiagnostic );
|
||||||
|
|
||||||
if ( !diag_set )
|
if ( !diag_set )
|
||||||
return full_text;
|
return full_text;
|
||||||
|
|
||||||
uint num_child_diagnostics = clang_getNumDiagnosticsInSet( diag_set );
|
uint num_child_diagnostics = clang_getNumDiagnosticsInSet( diag_set );
|
||||||
|
|
||||||
if ( !num_child_diagnostics )
|
if ( !num_child_diagnostics )
|
||||||
return full_text;
|
return full_text;
|
||||||
|
|
||||||
for ( uint i = 0; i < num_child_diagnostics; ++i )
|
for ( uint i = 0; i < num_child_diagnostics; ++i ) {
|
||||||
{
|
|
||||||
CXDiagnostic diagnostic = clang_getDiagnosticInSet( diag_set, i );
|
CXDiagnostic diagnostic = clang_getDiagnosticInSet( diag_set, i );
|
||||||
|
|
||||||
if ( !diagnostic )
|
if ( !diagnostic )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -74,10 +74,8 @@ std::string FullDiagnosticText( CXDiagnostic cxdiagnostic )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char DiagnosticSeverityToType( CXDiagnosticSeverity severity )
|
char DiagnosticSeverityToType( CXDiagnosticSeverity severity ) {
|
||||||
{
|
switch ( severity ) {
|
||||||
switch ( severity )
|
|
||||||
{
|
|
||||||
case CXDiagnostic_Ignored:
|
case CXDiagnostic_Ignored:
|
||||||
case CXDiagnostic_Note:
|
case CXDiagnostic_Note:
|
||||||
return 'I';
|
return 'I';
|
||||||
@ -98,23 +96,22 @@ char DiagnosticSeverityToType( CXDiagnosticSeverity severity )
|
|||||||
// Returns true when the provided completion string is available to the user;
|
// Returns true when the provided completion string is available to the user;
|
||||||
// unavailable completion strings refer to entities that are private/protected,
|
// unavailable completion strings refer to entities that are private/protected,
|
||||||
// deprecated etc.
|
// deprecated etc.
|
||||||
bool CompletionStringAvailable( CXCompletionString completion_string )
|
bool CompletionStringAvailable( CXCompletionString completion_string ) {
|
||||||
{
|
|
||||||
if ( !completion_string )
|
if ( !completion_string )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return clang_getCompletionAvailability( completion_string ) ==
|
return clang_getCompletionAvailability( completion_string ) ==
|
||||||
CXAvailability_Available;
|
CXAvailability_Available;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
|
|
||||||
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
|
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
|
||||||
const std::vector< UnsavedFile > &unsaved_files )
|
const std::vector< UnsavedFile > &unsaved_files ) {
|
||||||
{
|
|
||||||
std::vector< CXUnsavedFile > clang_unsaved_files( unsaved_files.size() );
|
std::vector< CXUnsavedFile > clang_unsaved_files( unsaved_files.size() );
|
||||||
for ( uint i = 0; i < unsaved_files.size(); ++i )
|
|
||||||
{
|
for ( uint i = 0; i < unsaved_files.size(); ++i ) {
|
||||||
X_VERIFY( unsaved_files[ i ].filename_ );
|
X_VERIFY( unsaved_files[ i ].filename_ );
|
||||||
X_VERIFY( unsaved_files[ i ].contents_ );
|
X_VERIFY( unsaved_files[ i ].contents_ );
|
||||||
X_VERIFY( unsaved_files[ i ].length_ );
|
X_VERIFY( unsaved_files[ i ].length_ );
|
||||||
@ -128,17 +125,16 @@ std::vector< CXUnsavedFile > ToCXUnsavedFiles(
|
|||||||
|
|
||||||
|
|
||||||
std::vector< CompletionData > ToCompletionDataVector(
|
std::vector< CompletionData > ToCompletionDataVector(
|
||||||
CXCodeCompleteResults *results )
|
CXCodeCompleteResults *results ) {
|
||||||
{
|
|
||||||
std::vector< CompletionData > completions;
|
std::vector< CompletionData > completions;
|
||||||
|
|
||||||
if ( !results || !results->Results )
|
if ( !results || !results->Results )
|
||||||
return completions;
|
return completions;
|
||||||
|
|
||||||
completions.reserve( results->NumResults );
|
completions.reserve( results->NumResults );
|
||||||
unordered_map< std::string, uint > seen_data;
|
unordered_map< std::string, uint > seen_data;
|
||||||
|
|
||||||
for ( uint i = 0; i < results->NumResults; ++i )
|
for ( uint i = 0; i < results->NumResults; ++i ) {
|
||||||
{
|
|
||||||
CXCompletionResult completion_result = results->Results[ i ];
|
CXCompletionResult completion_result = results->Results[ i ];
|
||||||
|
|
||||||
if ( !CompletionStringAvailable( completion_result.CompletionString ) )
|
if ( !CompletionStringAvailable( completion_result.CompletionString ) )
|
||||||
@ -149,21 +145,19 @@ std::vector< CompletionData > ToCompletionDataVector(
|
|||||||
data.original_string_,
|
data.original_string_,
|
||||||
completions.size() );
|
completions.size() );
|
||||||
|
|
||||||
if ( index == completions.size() )
|
if ( index == completions.size() ) {
|
||||||
{
|
|
||||||
completions.push_back( boost::move( data ) );
|
completions.push_back( boost::move( data ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
// If we have already seen this completion, then this is an overload of a
|
// If we have already seen this completion, then this is an overload of a
|
||||||
// function we have seen. We add the signature of the overload to the
|
// function we have seen. We add the signature of the overload to the
|
||||||
// detailed information.
|
// detailed information.
|
||||||
completions[ index ].detailed_info_
|
completions[ index ].detailed_info_
|
||||||
.append( data.return_type_ )
|
.append( data.return_type_ )
|
||||||
.append( " " )
|
.append( " " )
|
||||||
.append( data.everything_except_return_type_ )
|
.append( data.everything_except_return_type_ )
|
||||||
.append( "\n" );
|
.append( "\n" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,14 +165,14 @@ std::vector< CompletionData > ToCompletionDataVector(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Diagnostic CXDiagnosticToDiagnostic( CXDiagnostic cxdiagnostic )
|
Diagnostic CXDiagnosticToDiagnostic( CXDiagnostic cxdiagnostic ) {
|
||||||
{
|
|
||||||
Diagnostic diagnostic;
|
Diagnostic diagnostic;
|
||||||
|
|
||||||
if ( !cxdiagnostic )
|
if ( !cxdiagnostic )
|
||||||
return diagnostic;
|
return diagnostic;
|
||||||
|
|
||||||
diagnostic.kind_ = DiagnosticSeverityToType(
|
diagnostic.kind_ = DiagnosticSeverityToType(
|
||||||
clang_getDiagnosticSeverity( cxdiagnostic ) );
|
clang_getDiagnosticSeverity( cxdiagnostic ) );
|
||||||
|
|
||||||
// If this is an "ignored" diagnostic, there's no point in continuing since we
|
// If this is an "ignored" diagnostic, there's no point in continuing since we
|
||||||
// won't display those to the user
|
// won't display those to the user
|
||||||
@ -196,7 +190,7 @@ Diagnostic CXDiagnosticToDiagnostic( CXDiagnostic cxdiagnostic )
|
|||||||
|
|
||||||
diagnostic.filename_ = CXStringToString( clang_getFileName( file ) );
|
diagnostic.filename_ = CXStringToString( clang_getFileName( file ) );
|
||||||
diagnostic.text_ = CXStringToString(
|
diagnostic.text_ = CXStringToString(
|
||||||
clang_getDiagnosticSpelling( cxdiagnostic ) );
|
clang_getDiagnosticSpelling( cxdiagnostic ) );
|
||||||
diagnostic.long_formatted_text_ = FullDiagnosticText( cxdiagnostic );
|
diagnostic.long_formatted_text_ = FullDiagnosticText( cxdiagnostic );
|
||||||
|
|
||||||
clang_disposeDiagnostic( cxdiagnostic );
|
clang_disposeDiagnostic( cxdiagnostic );
|
||||||
|
@ -25,16 +25,15 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <clang-c/Index.h>
|
#include <clang-c/Index.h>
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
std::string CXStringToString( CXString text );
|
std::string CXStringToString( CXString text );
|
||||||
|
|
||||||
std::vector< CompletionData > ToCompletionDataVector(
|
std::vector< CompletionData > ToCompletionDataVector(
|
||||||
CXCodeCompleteResults *results );
|
CXCodeCompleteResults *results );
|
||||||
|
|
||||||
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
|
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
|
||||||
const std::vector< UnsavedFile > &unsaved_files );
|
const std::vector< UnsavedFile > &unsaved_files );
|
||||||
|
|
||||||
Diagnostic CXDiagnosticToDiagnostic( CXDiagnostic cxdiagnostic );
|
Diagnostic CXDiagnosticToDiagnostic( CXDiagnostic cxdiagnostic );
|
||||||
|
|
||||||
|
@ -19,46 +19,43 @@
|
|||||||
#include "ClangUtils.h"
|
#include "ClangUtils.h"
|
||||||
#include "standard.h"
|
#include "standard.h"
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
CompilationDatabase::CompilationDatabase(
|
CompilationDatabase::CompilationDatabase(
|
||||||
const std::string& path_to_directory )
|
const std::string &path_to_directory )
|
||||||
: is_loaded_( false )
|
: is_loaded_( false ) {
|
||||||
{
|
|
||||||
CXCompilationDatabase_Error status;
|
CXCompilationDatabase_Error status;
|
||||||
compilation_database_ = clang_CompilationDatabase_fromDirectory(
|
compilation_database_ = clang_CompilationDatabase_fromDirectory(
|
||||||
path_to_directory.c_str(),
|
path_to_directory.c_str(),
|
||||||
&status );
|
&status );
|
||||||
is_loaded_ = status == CXCompilationDatabase_NoError;
|
is_loaded_ = status == CXCompilationDatabase_NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CompilationDatabase::~CompilationDatabase()
|
CompilationDatabase::~CompilationDatabase() {
|
||||||
{
|
|
||||||
clang_CompilationDatabase_dispose( compilation_database_ );
|
clang_CompilationDatabase_dispose( compilation_database_ );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CompilationDatabase::DatabaseSuccessfullyLoaded()
|
bool CompilationDatabase::DatabaseSuccessfullyLoaded() {
|
||||||
{
|
|
||||||
return is_loaded_;
|
return is_loaded_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector< std::string > CompilationDatabase::FlagsForFile(
|
std::vector< std::string > CompilationDatabase::FlagsForFile(
|
||||||
const std::string &path_to_file )
|
const std::string &path_to_file ) {
|
||||||
{
|
|
||||||
std::vector< std::string > flags;
|
std::vector< std::string > flags;
|
||||||
|
|
||||||
if ( !is_loaded_ )
|
if ( !is_loaded_ )
|
||||||
return flags;
|
return flags;
|
||||||
|
|
||||||
CXCompileCommands commands =
|
CXCompileCommands commands =
|
||||||
clang_CompilationDatabase_getCompileCommands(
|
clang_CompilationDatabase_getCompileCommands(
|
||||||
compilation_database_,
|
compilation_database_,
|
||||||
path_to_file.c_str() );
|
path_to_file.c_str() );
|
||||||
|
|
||||||
uint num_commands = clang_CompileCommands_getSize( commands );
|
uint num_commands = clang_CompileCommands_getSize( commands );
|
||||||
|
|
||||||
if ( num_commands < 1 ) {
|
if ( num_commands < 1 ) {
|
||||||
clang_CompileCommands_dispose( commands );
|
clang_CompileCommands_dispose( commands );
|
||||||
return flags;
|
return flags;
|
||||||
@ -66,15 +63,15 @@ std::vector< std::string > CompilationDatabase::FlagsForFile(
|
|||||||
|
|
||||||
// We always pick the first command offered
|
// We always pick the first command offered
|
||||||
CXCompileCommand command = clang_CompileCommands_getCommand(
|
CXCompileCommand command = clang_CompileCommands_getCommand(
|
||||||
commands,
|
commands,
|
||||||
0);
|
0 );
|
||||||
|
|
||||||
uint num_flags = clang_CompileCommand_getNumArgs( command );
|
uint num_flags = clang_CompileCommand_getNumArgs( command );
|
||||||
flags.reserve( num_flags );
|
flags.reserve( num_flags );
|
||||||
for ( uint i = 0; i < num_flags; ++i )
|
|
||||||
{
|
for ( uint i = 0; i < num_flags; ++i ) {
|
||||||
flags.push_back( CXStringToString(
|
flags.push_back( CXStringToString(
|
||||||
clang_CompileCommand_getArg( command, i ) ) );
|
clang_CompileCommand_getArg( command, i ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
clang_CompileCommands_dispose( commands );
|
clang_CompileCommands_dispose( commands );
|
||||||
@ -83,18 +80,19 @@ std::vector< std::string > CompilationDatabase::FlagsForFile(
|
|||||||
|
|
||||||
|
|
||||||
std::string CompilationDatabase::CompileCommandWorkingDirectoryForFile(
|
std::string CompilationDatabase::CompileCommandWorkingDirectoryForFile(
|
||||||
const std::string &path_to_file )
|
const std::string &path_to_file ) {
|
||||||
{
|
|
||||||
std::string path_to_directory;
|
std::string path_to_directory;
|
||||||
|
|
||||||
if ( !is_loaded_ )
|
if ( !is_loaded_ )
|
||||||
return path_to_directory;
|
return path_to_directory;
|
||||||
|
|
||||||
CXCompileCommands commands =
|
CXCompileCommands commands =
|
||||||
clang_CompilationDatabase_getCompileCommands(
|
clang_CompilationDatabase_getCompileCommands(
|
||||||
compilation_database_,
|
compilation_database_,
|
||||||
path_to_file.c_str() );
|
path_to_file.c_str() );
|
||||||
|
|
||||||
uint num_commands = clang_CompileCommands_getSize( commands );
|
uint num_commands = clang_CompileCommands_getSize( commands );
|
||||||
|
|
||||||
if ( num_commands < 1 ) {
|
if ( num_commands < 1 ) {
|
||||||
clang_CompileCommands_dispose( commands );
|
clang_CompileCommands_dispose( commands );
|
||||||
return path_to_directory;
|
return path_to_directory;
|
||||||
@ -102,11 +100,11 @@ std::string CompilationDatabase::CompileCommandWorkingDirectoryForFile(
|
|||||||
|
|
||||||
// We always pick the first command offered
|
// We always pick the first command offered
|
||||||
CXCompileCommand command = clang_CompileCommands_getCommand(
|
CXCompileCommand command = clang_CompileCommands_getCommand(
|
||||||
commands,
|
commands,
|
||||||
0);
|
0 );
|
||||||
|
|
||||||
path_to_directory = CXStringToString( clang_CompileCommand_getDirectory(
|
path_to_directory = CXStringToString( clang_CompileCommand_getDirectory(
|
||||||
command ) );
|
command ) );
|
||||||
|
|
||||||
return path_to_directory;
|
return path_to_directory;
|
||||||
}
|
}
|
||||||
|
@ -23,13 +23,11 @@
|
|||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
#include <clang-c/CXCompilationDatabase.h>
|
#include <clang-c/CXCompilationDatabase.h>
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
class CompilationDatabase : boost::noncopyable
|
class CompilationDatabase : boost::noncopyable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
CompilationDatabase( const std::string& path_to_directory );
|
CompilationDatabase( const std::string &path_to_directory );
|
||||||
~CompilationDatabase();
|
~CompilationDatabase();
|
||||||
|
|
||||||
bool DatabaseSuccessfullyLoaded();
|
bool DatabaseSuccessfullyLoaded();
|
||||||
@ -37,7 +35,7 @@ public:
|
|||||||
std::vector< std::string > FlagsForFile( const std::string &path_to_file );
|
std::vector< std::string > FlagsForFile( const std::string &path_to_file );
|
||||||
|
|
||||||
std::string CompileCommandWorkingDirectoryForFile(
|
std::string CompileCommandWorkingDirectoryForFile(
|
||||||
const std::string &path_to_file );
|
const std::string &path_to_file );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool is_loaded_;
|
bool is_loaded_;
|
||||||
|
@ -21,15 +21,12 @@
|
|||||||
#include <boost/algorithm/string/erase.hpp>
|
#include <boost/algorithm/string/erase.hpp>
|
||||||
#include <boost/move/move.hpp>
|
#include <boost/move/move.hpp>
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
{
|
|
||||||
|
|
||||||
char CursorKindToVimKind( CXCursorKind kind )
|
char CursorKindToVimKind( CXCursorKind kind ) {
|
||||||
{
|
|
||||||
// TODO: actually it appears that Vim will show returned kinds even when they
|
// TODO: actually it appears that Vim will show returned kinds even when they
|
||||||
// do not match the "approved" list, so let's use that
|
// do not match the "approved" list, so let's use that
|
||||||
switch ( kind )
|
switch ( kind ) {
|
||||||
{
|
|
||||||
case CXCursor_UnexposedDecl:
|
case CXCursor_UnexposedDecl:
|
||||||
case CXCursor_StructDecl:
|
case CXCursor_StructDecl:
|
||||||
case CXCursor_UnionDecl:
|
case CXCursor_UnionDecl:
|
||||||
@ -58,8 +55,7 @@ char CursorKindToVimKind( CXCursorKind kind )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool IsMainCompletionTextInfo( CXCompletionChunkKind kind )
|
bool IsMainCompletionTextInfo( CXCompletionChunkKind kind ) {
|
||||||
{
|
|
||||||
return
|
return
|
||||||
kind == CXCompletionChunk_Optional ||
|
kind == CXCompletionChunk_Optional ||
|
||||||
kind == CXCompletionChunk_TypedText ||
|
kind == CXCompletionChunk_TypedText ||
|
||||||
@ -83,19 +79,19 @@ bool IsMainCompletionTextInfo( CXCompletionChunkKind kind )
|
|||||||
|
|
||||||
|
|
||||||
std::string ChunkToString( CXCompletionString completion_string,
|
std::string ChunkToString( CXCompletionString completion_string,
|
||||||
uint chunk_num )
|
uint chunk_num ) {
|
||||||
{
|
|
||||||
if ( !completion_string )
|
if ( !completion_string )
|
||||||
return std::string();
|
return std::string();
|
||||||
|
|
||||||
return YouCompleteMe::CXStringToString(
|
return YouCompleteMe::CXStringToString(
|
||||||
clang_getCompletionChunkText( completion_string, chunk_num ) );
|
clang_getCompletionChunkText( completion_string, chunk_num ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string OptionalChunkToString( CXCompletionString completion_string,
|
std::string OptionalChunkToString( CXCompletionString completion_string,
|
||||||
uint chunk_num )
|
uint chunk_num ) {
|
||||||
{
|
|
||||||
std::string final_string;
|
std::string final_string;
|
||||||
|
|
||||||
if ( !completion_string )
|
if ( !completion_string )
|
||||||
return final_string;
|
return final_string;
|
||||||
|
|
||||||
@ -106,21 +102,18 @@ std::string OptionalChunkToString( CXCompletionString completion_string,
|
|||||||
return final_string;
|
return final_string;
|
||||||
|
|
||||||
uint optional_num_chunks = clang_getNumCompletionChunks(
|
uint optional_num_chunks = clang_getNumCompletionChunks(
|
||||||
optional_completion_string );
|
optional_completion_string );
|
||||||
|
|
||||||
for ( uint j = 0; j < optional_num_chunks; ++j )
|
for ( uint j = 0; j < optional_num_chunks; ++j ) {
|
||||||
{
|
|
||||||
CXCompletionChunkKind kind = clang_getCompletionChunkKind(
|
CXCompletionChunkKind kind = clang_getCompletionChunkKind(
|
||||||
optional_completion_string, j );
|
optional_completion_string, j );
|
||||||
|
|
||||||
if ( kind == CXCompletionChunk_Optional )
|
if ( kind == CXCompletionChunk_Optional ) {
|
||||||
{
|
|
||||||
final_string.append( OptionalChunkToString( optional_completion_string,
|
final_string.append( OptionalChunkToString( optional_completion_string,
|
||||||
j ) );
|
j ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
final_string.append( ChunkToString( optional_completion_string, j ) );
|
final_string.append( ChunkToString( optional_completion_string, j ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,8 +127,7 @@ std::string OptionalChunkToString( CXCompletionString completion_string,
|
|||||||
// the parameter BUT if this code is compiled in C++11 mode a move constructor
|
// 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
|
// can be called on the passed-in value. This is not possible if we accept the
|
||||||
// param by const ref.
|
// param by const ref.
|
||||||
std::string RemoveTwoConsecutiveUnderscores( std::string text )
|
std::string RemoveTwoConsecutiveUnderscores( std::string text ) {
|
||||||
{
|
|
||||||
boost::erase_all( text, "__" );
|
boost::erase_all( text, "__" );
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
@ -143,11 +135,9 @@ std::string RemoveTwoConsecutiveUnderscores( std::string text )
|
|||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
CompletionData::CompletionData( const CXCompletionResult &completion_result )
|
CompletionData::CompletionData( const CXCompletionResult &completion_result ) {
|
||||||
{
|
|
||||||
CXCompletionString completion_string = completion_result.CompletionString;
|
CXCompletionString completion_string = completion_result.CompletionString;
|
||||||
|
|
||||||
if ( !completion_string )
|
if ( !completion_string )
|
||||||
@ -157,8 +147,7 @@ CompletionData::CompletionData( const CXCompletionResult &completion_result )
|
|||||||
bool saw_left_paren = false;
|
bool saw_left_paren = false;
|
||||||
bool saw_function_params = false;
|
bool saw_function_params = false;
|
||||||
|
|
||||||
for ( uint j = 0; j < num_chunks; ++j )
|
for ( uint j = 0; j < num_chunks; ++j ) {
|
||||||
{
|
|
||||||
ExtractDataFromChunk( completion_string,
|
ExtractDataFromChunk( completion_string,
|
||||||
j,
|
j,
|
||||||
saw_left_paren,
|
saw_left_paren,
|
||||||
@ -175,54 +164,47 @@ CompletionData::CompletionData( const CXCompletionResult &completion_result )
|
|||||||
// compiler-reserved.
|
// compiler-reserved.
|
||||||
everything_except_return_type_ =
|
everything_except_return_type_ =
|
||||||
RemoveTwoConsecutiveUnderscores(
|
RemoveTwoConsecutiveUnderscores(
|
||||||
boost::move( everything_except_return_type_ ) );
|
boost::move( everything_except_return_type_ ) );
|
||||||
|
|
||||||
detailed_info_.append( return_type_ )
|
detailed_info_.append( return_type_ )
|
||||||
.append( " " )
|
.append( " " )
|
||||||
.append( everything_except_return_type_ )
|
.append( everything_except_return_type_ )
|
||||||
.append( "\n" );
|
.append( "\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CompletionData::ExtractDataFromChunk( CXCompletionString completion_string,
|
void CompletionData::ExtractDataFromChunk( CXCompletionString completion_string,
|
||||||
uint chunk_num,
|
uint chunk_num,
|
||||||
bool &saw_left_paren,
|
bool &saw_left_paren,
|
||||||
bool &saw_function_params )
|
bool &saw_function_params ) {
|
||||||
{
|
|
||||||
CXCompletionChunkKind kind = clang_getCompletionChunkKind(
|
CXCompletionChunkKind kind = clang_getCompletionChunkKind(
|
||||||
completion_string, chunk_num );
|
completion_string, chunk_num );
|
||||||
|
|
||||||
if ( IsMainCompletionTextInfo( kind ) )
|
if ( IsMainCompletionTextInfo( kind ) ) {
|
||||||
{
|
if ( kind == CXCompletionChunk_LeftParen ) {
|
||||||
if ( kind == CXCompletionChunk_LeftParen )
|
|
||||||
{
|
|
||||||
saw_left_paren = true;
|
saw_left_paren = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( saw_left_paren &&
|
else if ( saw_left_paren &&
|
||||||
!saw_function_params &&
|
!saw_function_params &&
|
||||||
kind != CXCompletionChunk_RightParen &&
|
kind != CXCompletionChunk_RightParen &&
|
||||||
kind != CXCompletionChunk_Informative )
|
kind != CXCompletionChunk_Informative ) {
|
||||||
{
|
|
||||||
saw_function_params = true;
|
saw_function_params = true;
|
||||||
everything_except_return_type_.append( " " );
|
everything_except_return_type_.append( " " );
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( saw_function_params && kind == CXCompletionChunk_RightParen )
|
else if ( saw_function_params && kind == CXCompletionChunk_RightParen ) {
|
||||||
{
|
|
||||||
everything_except_return_type_.append( " " );
|
everything_except_return_type_.append( " " );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( kind == CXCompletionChunk_Optional )
|
if ( kind == CXCompletionChunk_Optional ) {
|
||||||
{
|
|
||||||
everything_except_return_type_.append(
|
everything_except_return_type_.append(
|
||||||
OptionalChunkToString( completion_string, chunk_num ) );
|
OptionalChunkToString( completion_string, chunk_num ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
everything_except_return_type_.append(
|
everything_except_return_type_.append(
|
||||||
ChunkToString( completion_string, chunk_num ) );
|
ChunkToString( completion_string, chunk_num ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,8 +22,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <clang-c/Index.h>
|
#include <clang-c/Index.h>
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
// This class holds pieces of information about a single completion coming from
|
// This class holds pieces of information about a single completion coming from
|
||||||
// clang. These pieces are shown in Vim's UI in different ways.
|
// clang. These pieces are shown in Vim's UI in different ways.
|
||||||
@ -37,16 +36,14 @@ namespace YouCompleteMe
|
|||||||
//
|
//
|
||||||
// The user can also enable a "preview" window that will show extra information
|
// The user can also enable a "preview" window that will show extra information
|
||||||
// about a completion at the top of the buffer.
|
// about a completion at the top of the buffer.
|
||||||
struct CompletionData
|
struct CompletionData {
|
||||||
{
|
|
||||||
CompletionData() {}
|
CompletionData() {}
|
||||||
CompletionData( const CXCompletionResult &completion_result );
|
CompletionData( const CXCompletionResult &completion_result );
|
||||||
|
|
||||||
// What should actually be inserted into the buffer. For a function like
|
// 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_":
|
// "int foo(int x)", this is just "foo". Same for a data member like "foo_":
|
||||||
// we insert just "foo_".
|
// we insert just "foo_".
|
||||||
std::string TextToInsertInBuffer()
|
std::string TextToInsertInBuffer() {
|
||||||
{
|
|
||||||
return original_string_;
|
return original_string_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,29 +52,25 @@ struct CompletionData
|
|||||||
// the completion is, say, a data member. So for a function like "int foo(int
|
// the completion is, say, a data member. So for a function like "int foo(int
|
||||||
// x)", this would be "foo(int x)". For a data member like "count_", it would
|
// x)", this would be "foo(int x)". For a data member like "count_", it would
|
||||||
// be just "count_".
|
// be just "count_".
|
||||||
std::string MainCompletionText()
|
std::string MainCompletionText() {
|
||||||
{
|
|
||||||
return everything_except_return_type_;
|
return everything_except_return_type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is extra info shown in the pop-up completion menu, after the
|
// This is extra info shown in the pop-up completion menu, after the
|
||||||
// completion text and the kind. Currently we put the return type of the
|
// completion text and the kind. Currently we put the return type of the
|
||||||
// function here, if any.
|
// function here, if any.
|
||||||
std::string ExtraMenuInfo()
|
std::string ExtraMenuInfo() {
|
||||||
{
|
|
||||||
return return_type_;
|
return return_type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is used to show extra information in vim's preview window. This is the
|
// This is used to show extra information in vim's preview window. This is the
|
||||||
// window that vim usually shows at the top of the buffer. This should be used
|
// window that vim usually shows at the top of the buffer. This should be used
|
||||||
// for extra information about the completion.
|
// for extra information about the completion.
|
||||||
std::string DetailedInfoForPreviewWindow()
|
std::string DetailedInfoForPreviewWindow() {
|
||||||
{
|
|
||||||
return detailed_info_;
|
return detailed_info_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator== ( const CompletionData &other ) const
|
bool operator== ( const CompletionData &other ) const {
|
||||||
{
|
|
||||||
return
|
return
|
||||||
kind_ == other.kind_ &&
|
kind_ == other.kind_ &&
|
||||||
everything_except_return_type_ == other.everything_except_return_type_ &&
|
everything_except_return_type_ == other.everything_except_return_type_ &&
|
||||||
|
@ -21,13 +21,10 @@
|
|||||||
#include "standard.h"
|
#include "standard.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
struct Diagnostic
|
struct Diagnostic {
|
||||||
{
|
bool operator== ( const Diagnostic &other ) const {
|
||||||
bool operator== ( const Diagnostic &other ) const
|
|
||||||
{
|
|
||||||
return
|
return
|
||||||
line_number_ == other.line_number_ &&
|
line_number_ == other.line_number_ &&
|
||||||
column_number_ == other.column_number_ &&
|
column_number_ == other.column_number_ &&
|
||||||
|
@ -28,36 +28,33 @@ using boost::unique_lock;
|
|||||||
using boost::mutex;
|
using boost::mutex;
|
||||||
using boost::try_to_lock_t;
|
using boost::try_to_lock_t;
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
TranslationUnit::TranslationUnit(
|
TranslationUnit::TranslationUnit(
|
||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags,
|
const std::vector< std::string > &flags,
|
||||||
CXIndex clang_index )
|
CXIndex clang_index )
|
||||||
: filename_( filename ),
|
: filename_( filename ),
|
||||||
clang_translation_unit_( NULL )
|
clang_translation_unit_( NULL ) {
|
||||||
{
|
std::vector< const char * > pointer_flags;
|
||||||
std::vector< const char* > pointer_flags;
|
|
||||||
pointer_flags.reserve( flags.size() );
|
pointer_flags.reserve( flags.size() );
|
||||||
|
|
||||||
foreach ( const std::string &flag, flags )
|
foreach ( const std::string & flag, flags ) {
|
||||||
{
|
|
||||||
pointer_flags.push_back( flag.c_str() );
|
pointer_flags.push_back( flag.c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector< CXUnsavedFile > cxunsaved_files = ToCXUnsavedFiles(
|
std::vector< CXUnsavedFile > cxunsaved_files =
|
||||||
unsaved_files );
|
ToCXUnsavedFiles( unsaved_files );
|
||||||
|
|
||||||
clang_translation_unit_ = clang_parseTranslationUnit(
|
clang_translation_unit_ = clang_parseTranslationUnit(
|
||||||
clang_index,
|
clang_index,
|
||||||
filename.c_str(),
|
filename.c_str(),
|
||||||
&pointer_flags[ 0 ],
|
&pointer_flags[ 0 ],
|
||||||
pointer_flags.size(),
|
pointer_flags.size(),
|
||||||
&cxunsaved_files[ 0 ],
|
&cxunsaved_files[ 0 ],
|
||||||
cxunsaved_files.size(),
|
cxunsaved_files.size(),
|
||||||
clang_defaultEditingTranslationUnitOptions() );
|
clang_defaultEditingTranslationUnitOptions() );
|
||||||
|
|
||||||
if ( !clang_translation_unit_ )
|
if ( !clang_translation_unit_ )
|
||||||
boost_throw( ClangParseError() );
|
boost_throw( ClangParseError() );
|
||||||
@ -68,15 +65,13 @@ TranslationUnit::TranslationUnit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TranslationUnit::~TranslationUnit()
|
TranslationUnit::~TranslationUnit() {
|
||||||
{
|
|
||||||
if ( clang_translation_unit_ )
|
if ( clang_translation_unit_ )
|
||||||
clang_disposeTranslationUnit( clang_translation_unit_ );
|
clang_disposeTranslationUnit( clang_translation_unit_ );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector< Diagnostic > TranslationUnit::LatestDiagnostics()
|
std::vector< Diagnostic > TranslationUnit::LatestDiagnostics() {
|
||||||
{
|
|
||||||
std::vector< Diagnostic > diagnostics;
|
std::vector< Diagnostic > diagnostics;
|
||||||
unique_lock< mutex > lock( diagnostics_mutex_ );
|
unique_lock< mutex > lock( diagnostics_mutex_ );
|
||||||
|
|
||||||
@ -95,34 +90,32 @@ std::vector< Diagnostic > TranslationUnit::LatestDiagnostics()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool TranslationUnit::IsCurrentlyUpdating() const
|
bool TranslationUnit::IsCurrentlyUpdating() const {
|
||||||
{
|
|
||||||
unique_lock< mutex > lock( clang_access_mutex_, try_to_lock_t() );
|
unique_lock< mutex > lock( clang_access_mutex_, try_to_lock_t() );
|
||||||
return !lock.owns_lock();
|
return !lock.owns_lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TranslationUnit::Reparse( const std::vector< UnsavedFile > &unsaved_files )
|
void TranslationUnit::Reparse(
|
||||||
{
|
const std::vector< UnsavedFile > &unsaved_files ) {
|
||||||
std::vector< CXUnsavedFile > cxunsaved_files = ToCXUnsavedFiles(
|
std::vector< CXUnsavedFile > cxunsaved_files =
|
||||||
unsaved_files );
|
ToCXUnsavedFiles( unsaved_files );
|
||||||
|
|
||||||
Reparse( cxunsaved_files );
|
Reparse( cxunsaved_files );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector< CompletionData > TranslationUnit::CandidatesForLocation(
|
std::vector< CompletionData > TranslationUnit::CandidatesForLocation(
|
||||||
int line,
|
int line,
|
||||||
int column,
|
int column,
|
||||||
const std::vector< UnsavedFile > &unsaved_files )
|
const std::vector< UnsavedFile > &unsaved_files ) {
|
||||||
{
|
|
||||||
unique_lock< mutex > lock( clang_access_mutex_ );
|
unique_lock< mutex > lock( clang_access_mutex_ );
|
||||||
|
|
||||||
if ( !clang_translation_unit_ )
|
if ( !clang_translation_unit_ )
|
||||||
return std::vector< CompletionData >();
|
return std::vector< CompletionData >();
|
||||||
|
|
||||||
std::vector< CXUnsavedFile > cxunsaved_files = ToCXUnsavedFiles(
|
std::vector< CXUnsavedFile > cxunsaved_files =
|
||||||
unsaved_files );
|
ToCXUnsavedFiles( unsaved_files );
|
||||||
|
|
||||||
// codeCompleteAt reparses the TU if the underlying source file has changed on
|
// codeCompleteAt reparses the TU if the underlying source file has changed on
|
||||||
// disk since the last time the TU was updated and there are no unsaved files.
|
// disk since the last time the TU was updated and there are no unsaved files.
|
||||||
@ -153,21 +146,19 @@ std::vector< CompletionData > TranslationUnit::CandidatesForLocation(
|
|||||||
// non-const pointer to clang. This function (and clang too) will not modify the
|
// non-const pointer to clang. This function (and clang too) will not modify the
|
||||||
// param though.
|
// param though.
|
||||||
void TranslationUnit::Reparse(
|
void TranslationUnit::Reparse(
|
||||||
std::vector< CXUnsavedFile > &unsaved_files )
|
std::vector< CXUnsavedFile > &unsaved_files ) {
|
||||||
{
|
|
||||||
unique_lock< mutex > lock( clang_access_mutex_ );
|
unique_lock< mutex > lock( clang_access_mutex_ );
|
||||||
|
|
||||||
if ( !clang_translation_unit_ )
|
if ( !clang_translation_unit_ )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int failure = clang_reparseTranslationUnit(
|
int failure = clang_reparseTranslationUnit(
|
||||||
clang_translation_unit_,
|
clang_translation_unit_,
|
||||||
unsaved_files.size(),
|
unsaved_files.size(),
|
||||||
&unsaved_files[ 0 ],
|
&unsaved_files[ 0 ],
|
||||||
clang_defaultEditingTranslationUnitOptions() );
|
clang_defaultEditingTranslationUnitOptions() );
|
||||||
|
|
||||||
if ( failure )
|
if ( failure ) {
|
||||||
{
|
|
||||||
clang_disposeTranslationUnit( clang_translation_unit_ );
|
clang_disposeTranslationUnit( clang_translation_unit_ );
|
||||||
clang_translation_unit_ = NULL;
|
clang_translation_unit_ = NULL;
|
||||||
boost_throw( ClangParseError() );
|
boost_throw( ClangParseError() );
|
||||||
@ -178,17 +169,16 @@ void TranslationUnit::Reparse(
|
|||||||
|
|
||||||
|
|
||||||
// Should only be called while holding the clang_access_mutex_
|
// Should only be called while holding the clang_access_mutex_
|
||||||
void TranslationUnit::UpdateLatestDiagnostics()
|
void TranslationUnit::UpdateLatestDiagnostics() {
|
||||||
{
|
|
||||||
unique_lock< mutex > lock( diagnostics_mutex_ );
|
unique_lock< mutex > lock( diagnostics_mutex_ );
|
||||||
|
|
||||||
latest_diagnostics_.clear();
|
latest_diagnostics_.clear();
|
||||||
uint num_diagnostics = clang_getNumDiagnostics( clang_translation_unit_ );
|
uint num_diagnostics = clang_getNumDiagnostics( clang_translation_unit_ );
|
||||||
latest_diagnostics_.reserve( num_diagnostics );
|
latest_diagnostics_.reserve( num_diagnostics );
|
||||||
|
|
||||||
for ( uint i = 0; i < num_diagnostics; ++i )
|
for ( uint i = 0; i < num_diagnostics; ++i ) {
|
||||||
{
|
Diagnostic diagnostic =
|
||||||
Diagnostic diagnostic = CXDiagnosticToDiagnostic(
|
CXDiagnosticToDiagnostic(
|
||||||
clang_getDiagnostic( clang_translation_unit_, i ) );
|
clang_getDiagnostic( clang_translation_unit_, i ) );
|
||||||
|
|
||||||
if ( diagnostic.kind_ != 'I' )
|
if ( diagnostic.kind_ != 'I' )
|
||||||
|
@ -33,14 +33,12 @@ typedef void *CXIndex;
|
|||||||
typedef struct CXTranslationUnitImpl *CXTranslationUnit;
|
typedef struct CXTranslationUnitImpl *CXTranslationUnit;
|
||||||
struct CXUnsavedFile;
|
struct CXUnsavedFile;
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
struct CompletionData;
|
struct CompletionData;
|
||||||
typedef boost::shared_ptr< std::vector< CompletionData > > AsyncCompletions;
|
typedef boost::shared_ptr< std::vector< CompletionData > > AsyncCompletions;
|
||||||
|
|
||||||
class TranslationUnit : boost::noncopyable
|
class TranslationUnit : boost::noncopyable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TranslationUnit(
|
TranslationUnit(
|
||||||
@ -58,9 +56,9 @@ public:
|
|||||||
void Reparse( const std::vector< UnsavedFile > &unsaved_files );
|
void Reparse( const std::vector< UnsavedFile > &unsaved_files );
|
||||||
|
|
||||||
std::vector< CompletionData > CandidatesForLocation(
|
std::vector< CompletionData > CandidatesForLocation(
|
||||||
int line,
|
int line,
|
||||||
int column,
|
int column,
|
||||||
const std::vector< UnsavedFile > &unsaved_files );
|
const std::vector< UnsavedFile > &unsaved_files );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -20,8 +20,7 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
struct UnsavedFile
|
struct UnsavedFile {
|
||||||
{
|
|
||||||
UnsavedFile() : filename_( NULL ), contents_( NULL ), length_( 0 ) {}
|
UnsavedFile() : filename_( NULL ), contents_( NULL ), length_( 0 ) {}
|
||||||
|
|
||||||
const char *filename_;
|
const char *filename_;
|
||||||
@ -32,8 +31,7 @@ struct UnsavedFile
|
|||||||
// methods. I have no clue why, but it won't compile without it.
|
// methods. I have no clue why, but it won't compile without it.
|
||||||
// TODO: report this problem on the Boost bug tracker, the default equality
|
// TODO: report this problem on the Boost bug tracker, the default equality
|
||||||
// operator should be more than adequate here
|
// operator should be more than adequate here
|
||||||
bool operator== ( const UnsavedFile &other ) const
|
bool operator== ( const UnsavedFile &other ) const {
|
||||||
{
|
|
||||||
return
|
return
|
||||||
filename_ == other.filename_ &&
|
filename_ == other.filename_ &&
|
||||||
contents_ == other.contents_ &&
|
contents_ == other.contents_ &&
|
||||||
|
Loading…
Reference in New Issue
Block a user