Diagnostic ranges now exposed to server clients

Still haven't used them in the Vim client though, but will soon.
This commit is contained in:
Strahinja Val Markovic 2014-01-04 21:46:04 -08:00
parent e5abbdb540
commit 3ed8d9883c
5 changed files with 48 additions and 35 deletions

View File

@ -109,8 +109,7 @@ BOOST_PYTHON_MODULE(ycm_core)
.def_readonly( "kind_", &CompletionData::kind_ ); .def_readonly( "kind_", &CompletionData::kind_ );
class_< std::vector< CompletionData >, class_< std::vector< CompletionData >,
boost::shared_ptr< std::vector< CompletionData > > >( boost::shared_ptr< std::vector< CompletionData > > >( "CompletionVec" )
"CompletionVec" )
.def( vector_indexing_suite< std::vector< CompletionData > >() ); .def( vector_indexing_suite< std::vector< CompletionData > >() );
class_< Location >( "Location" ) class_< Location >( "Location" )
@ -123,9 +122,7 @@ BOOST_PYTHON_MODULE(ycm_core)
.def_readonly( "start_", &Range::start_ ) .def_readonly( "start_", &Range::start_ )
.def_readonly( "end_", &Range::end_ ); .def_readonly( "end_", &Range::end_ );
class_< std::vector< Range >, class_< std::vector< Range > >( "RangeVec" )
boost::shared_ptr< std::vector< Range > > >(
"RangeVec" )
.def( vector_indexing_suite< std::vector< Range > >() ); .def( vector_indexing_suite< std::vector< Range > >() );
class_< Diagnostic >( "Diagnostic" ) class_< Diagnostic >( "Diagnostic" )

View File

@ -76,10 +76,11 @@ def _ConvertDiagnosticDataToVimData( diagnostic ):
# Note that, as usual, Vim is completely inconsistent about whether # Note that, as usual, Vim is completely inconsistent about whether
# line/column numbers are 1 or 0 based in its various APIs. Here, it wants # line/column numbers are 1 or 0 based in its various APIs. Here, it wants
# them to be 1-based. # them to be 1-based.
location = diagnostic[ 'location' ]
return { return {
'bufnr' : vimsupport.GetBufferNumberForFilename( diagnostic[ 'filepath' ] ), 'bufnr' : vimsupport.GetBufferNumberForFilename( location[ 'filepath' ] ),
'lnum' : diagnostic[ 'line_num' ] + 1, 'lnum' : location[ 'line_num' ] + 1,
'col' : diagnostic[ 'column_num' ] + 1, 'col' : location[ 'column_num' ] + 1,
'text' : diagnostic[ 'text' ], 'text' : diagnostic[ 'text' ],
'type' : diagnostic[ 'kind' ], 'type' : diagnostic[ 'kind' ],
'valid' : 1 'valid' : 1

View File

@ -200,7 +200,7 @@ class ClangCompleter( Completer ):
diagnostics = _FilterDiagnostics( diagnostics ) diagnostics = _FilterDiagnostics( diagnostics )
self._diagnostic_store = DiagnosticsToDiagStructure( diagnostics ) self._diagnostic_store = DiagnosticsToDiagStructure( diagnostics )
return [ ConvertToDiagnosticResponse( x ) for x in return [ responses.BuildDiagnosticData( x ) for x in
diagnostics[ : self._max_diagnostics_to_display ] ] diagnostics[ : self._max_diagnostics_to_display ] ]
@ -279,13 +279,6 @@ def InCFamilyFile( filetypes ):
return ClangAvailableForFiletypes( filetypes ) return ClangAvailableForFiletypes( filetypes )
def ConvertToDiagnosticResponse( diagnostic ):
return responses.BuildDiagnosticData( diagnostic.location_.filename_,
diagnostic.location_.line_number_ - 1,
diagnostic.location_.column_number_ - 1,
diagnostic.text_,
diagnostic.kind_ )
def _FilterDiagnostics( diagnostics ): def _FilterDiagnostics( diagnostics ):
# Clang has an annoying warning that shows up when we try to compile header # Clang has an annoying warning that shows up when we try to compile header
# files if the header has "#pragma once" inside it. The error is not # files if the header has "#pragma once" inside it. The error is not

View File

@ -101,17 +101,25 @@ def BuildCompletionData( insertion_text,
return completion_data return completion_data
def BuildDiagnosticData( filepath, def BuildDiagnosticData( diagnostic ):
line_num, def BuildRangeData( source_range ):
column_num, return {
text, 'start': BuildLocationData( source_range.start_ ),
kind ): 'end': BuildLocationData( source_range.end_ ),
}
def BuildLocationData( location ):
return {
'line_num': location.line_number_ - 1,
'column_num': location.column_number_ - 1,
'filepath': location.filename_,
}
return { return {
'filepath': filepath, 'ranges': [ BuildRangeData( x ) for x in diagnostic.ranges_ ],
'line_num': line_num, 'location': BuildLocationData( diagnostic.location_ ),
'column_num': column_num, 'text': diagnostic.text_,
'text': text, 'kind': diagnostic.kind_
'kind': kind
} }

View File

@ -35,12 +35,11 @@ bottle.debug( True )
def Diagnostics_ClangCompleter_ZeroBasedLineAndColumn_test(): def Diagnostics_ClangCompleter_ZeroBasedLineAndColumn_test():
app = TestApp( handlers.app ) app = TestApp( handlers.app )
contents = """ contents = """
struct Foo { void foo() {
int x // semicolon missing here! double baz = "foo";
int y; }
int c; // Padding to 5 lines
int d; // Padding to 5 lines
};
""" """
event_data = BuildRequest( compilation_flags = ['-x', 'c++'], event_data = BuildRequest( compilation_flags = ['-x', 'c++'],
@ -49,11 +48,26 @@ struct Foo {
filetype = 'cpp' ) filetype = 'cpp' )
results = app.post_json( '/event_notification', event_data ).json results = app.post_json( '/event_notification', event_data ).json
print results
assert_that( results, assert_that( results,
contains( contains(
has_entries( { 'text': contains_string( "expected ';'" ), has_entries( {
'line_num': 2, 'text': contains_string( 'cannot initialize' ),
'column_num': 7 } ) ) ) 'ranges': contains( has_entries( {
'start': has_entries( {
'line_num': 2,
'column_num': 15,
} ),
'end': has_entries( {
'line_num': 2,
'column_num': 20,
} ),
} ) ),
'location': has_entries( {
'line_num': 2,
'column_num': 9
} )
} ) ) )
@with_setup( Setup ) @with_setup( Setup )
def Diagnostics_ClangCompleter_PragmaOnceWarningIgnored_test(): def Diagnostics_ClangCompleter_PragmaOnceWarningIgnored_test():