GoTo commands for clang completer work again

This commit is contained in:
Strahinja Val Markovic 2013-09-27 14:59:00 -07:00
parent fe0c0a1607
commit 4a95c2fc7c
6 changed files with 86 additions and 21 deletions

View File

@ -61,4 +61,21 @@ TEST( ClangCompleterTest, CandidatesForQueryAndLocationInFileAsync ) {
EXPECT_TRUE( !completions_future.GetResults()->empty() ); EXPECT_TRUE( !completions_future.GetResults()->empty() );
} }
TEST( ClangCompleterTest, GetDefinitionLocation ) {
ClangCompleter completer;
std::string filename = PathToTestFile( "basic.cpp" ).string();
// Clang operates on the reasonable assumption that line and column numbers
// are 1-based.
Location actual_location =
completer.GetDefinitionLocation(
filename,
9,
3,
std::vector< UnsavedFile >(),
std::vector< std::string >() );
EXPECT_EQ( Location( filename, 1, 8 ), actual_location );
}
} // namespace YouCompleteMe } // namespace YouCompleteMe

View File

@ -2,7 +2,7 @@ struct Foo {
int x; int x;
int y; int y;
char c; char c;
} };
int main() int main()
{ {

View File

@ -63,7 +63,7 @@ class CommandRequest( BaseRequest ):
else: else:
vimsupport.JumpToLocation( self._response[ 'filepath' ], vimsupport.JumpToLocation( self._response[ 'filepath' ],
self._response[ 'line_num' ] + 1, self._response[ 'line_num' ] + 1,
self._response[ 'column_num' ] ) self._response[ 'column_num' ] + 1)

View File

@ -24,7 +24,7 @@ from ycm.server import responses
from ycm import extra_conf_store from ycm import extra_conf_store
from ycm.utils import ToUtf8IfNeeded from ycm.utils import ToUtf8IfNeeded
from ycm.completers.completer import Completer from ycm.completers.completer import Completer
from ycm.completers.cpp.flags import Flags from ycm.completers.cpp.flags import Flags, PrepareFlagsForClang
CLANG_FILETYPES = set( [ 'c', 'cpp', 'objc', 'objcpp' ] ) CLANG_FILETYPES = set( [ 'c', 'cpp', 'objc', 'objcpp' ] )
MIN_LINES_IN_FILE_TO_PARSE = 5 MIN_LINES_IN_FILE_TO_PARSE = 5
@ -96,7 +96,7 @@ class ClangCompleter( Completer ):
return responses.BuildDisplayMessageResponse( return responses.BuildDisplayMessageResponse(
PARSING_FILE_MESSAGE ) PARSING_FILE_MESSAGE )
flags = self.flags.FlagsForFile( filename ) flags = self._FlagsForRequest( request_data )
if not flags: if not flags:
self.completions_future = None self.completions_future = None
self._logger.info( NO_COMPILE_FLAGS_MESSAGE ) self._logger.info( NO_COMPILE_FLAGS_MESSAGE )
@ -160,14 +160,12 @@ class ClangCompleter( Completer ):
filename = request_data[ 'filepath' ] filename = request_data[ 'filepath' ]
if not filename: if not filename:
self._logger.warning( INVALID_FILE_MESSAGE ) self._logger.warning( INVALID_FILE_MESSAGE )
return responses.BuildDisplayMessageResponse( raise ValueError( INVALID_FILE_MESSAGE )
INVALID_FILE_MESSAGE )
flags = self.flags.FlagsForFile( filename ) flags = self._FlagsForRequest( request_data )
if not flags: if not flags:
self._logger.info( NO_COMPILE_FLAGS_MESSAGE ) self._logger.info( NO_COMPILE_FLAGS_MESSAGE )
return responses.BuildDisplayMessageResponse( raise ValueError( NO_COMPILE_FLAGS_MESSAGE )
NO_COMPILE_FLAGS_MESSAGE )
files = self.GetUnsavedFilesVector( request_data ) files = self.GetUnsavedFilesVector( request_data )
line = request_data[ 'line_num' ] + 1 line = request_data[ 'line_num' ] + 1
@ -186,8 +184,8 @@ class ClangCompleter( Completer ):
raise RuntimeError( 'Can\'t jump to definition.' ) raise RuntimeError( 'Can\'t jump to definition.' )
return responses.BuildGoToResponse( location.filename_, return responses.BuildGoToResponse( location.filename_,
location.line_number_, location.line_number_ - 1,
location.column_number_ ) location.column_number_ - 1)
def _GoToDeclaration( self, request_data ): def _GoToDeclaration( self, request_data ):
@ -196,8 +194,8 @@ class ClangCompleter( Completer ):
raise RuntimeError( 'Can\'t jump to declaration.' ) raise RuntimeError( 'Can\'t jump to declaration.' )
return responses.BuildGoToResponse( location.filename_, return responses.BuildGoToResponse( location.filename_,
location.line_number_, location.line_number_ - 1,
location.column_number_ ) location.column_number_ - 1)
def _GoToDefinitionElseDeclaration( self, request_data ): def _GoToDefinitionElseDeclaration( self, request_data ):
@ -208,8 +206,8 @@ class ClangCompleter( Completer ):
raise RuntimeError( 'Can\'t jump to definition or declaration.' ) raise RuntimeError( 'Can\'t jump to definition or declaration.' )
return responses.BuildGoToResponse( location.filename_, return responses.BuildGoToResponse( location.filename_,
location.line_number_, location.line_number_ - 1,
location.column_number_ ) location.column_number_ - 1)
@ -234,7 +232,7 @@ class ClangCompleter( Completer ):
self.extra_parse_desired = True self.extra_parse_desired = True
return return
flags = self.flags.FlagsForFile( filename ) flags = self._FlagsForRequest( request_data )
if not flags: if not flags:
self.parse_future = None self.parse_future = None
self._logger.info( NO_COMPILE_FLAGS_MESSAGE ) self._logger.info( NO_COMPILE_FLAGS_MESSAGE )
@ -319,13 +317,20 @@ class ClangCompleter( Completer ):
filename = request_data[ 'filepath' ] filename = request_data[ 'filepath' ]
if not filename: if not filename:
return '' return ''
flags = self.flags.FlagsForFile( filename ) or [] flags = self._FlagsForRequest( request_data ) or []
source = extra_conf_store.ModuleFileForSourceFile( filename ) source = extra_conf_store.ModuleFileForSourceFile( filename )
return responses.BuildDisplayMessageResponse( return responses.BuildDisplayMessageResponse(
'Flags for {0} loaded from {1}:\n{2}'.format( filename, 'Flags for {0} loaded from {1}:\n{2}'.format( filename,
source, source,
list( flags ) ) ) list( flags ) ) )
def _FlagsForRequest( self, request_data ):
filename = request_data[ 'filepath' ]
if 'compilation_flags' in request_data:
return PrepareFlagsForClang( request_data[ 'compilation_flags' ],
filename )
return self.flags.FlagsForFile( filename )
# TODO: Make this work again # TODO: Make this work again
# def DiagnosticToDict( diagnostic ): # def DiagnosticToDict( diagnostic ):
# # see :h getqflist for a description of the dictionary fields # # see :h getqflist for a description of the dictionary fields

View File

@ -20,6 +20,7 @@
import ycm_core import ycm_core
import os import os
from ycm import extra_conf_store from ycm import extra_conf_store
from ycm.utils import ToUtf8IfNeeded
NO_EXTRA_CONF_FILENAME_MESSAGE = ( 'No {0} file detected, so no compile flags ' NO_EXTRA_CONF_FILENAME_MESSAGE = ( 'No {0} file detected, so no compile flags '
'are available. Thus no semantic support for C/C++/ObjC/ObjC++. Go READ THE ' 'are available. Thus no semantic support for C/C++/ObjC/ObjC++. Go READ THE '
@ -54,7 +55,7 @@ class Flags( object ):
flags = list( results[ 'flags' ] ) flags = list( results[ 'flags' ] )
if add_special_clang_flags: if add_special_clang_flags:
flags += self.special_clang_flags flags += self.special_clang_flags
sanitized_flags = _PrepareFlagsForClang( flags, filename ) sanitized_flags = PrepareFlagsForClang( flags, filename )
if results[ 'do_cache' ]: if results[ 'do_cache' ]:
self.flags_for_file[ filename ] = sanitized_flags self.flags_for_file[ filename ] = sanitized_flags
@ -90,7 +91,7 @@ class Flags( object ):
self.flags_for_file.clear() self.flags_for_file.clear()
def _PrepareFlagsForClang( flags, filename ): def PrepareFlagsForClang( flags, filename ):
flags = _RemoveUnusedFlags( flags, filename ) flags = _RemoveUnusedFlags( flags, filename )
flags = _SanitizeFlags( flags ) flags = _SanitizeFlags( flags )
return flags return flags
@ -116,7 +117,7 @@ def _SanitizeFlags( flags ):
vector = ycm_core.StringVec() vector = ycm_core.StringVec()
for flag in sanitized_flags: for flag in sanitized_flags:
vector.append( flag ) vector.append( ToUtf8IfNeeded( flag ) )
return vector return vector

View File

@ -137,7 +137,6 @@ foo()
'column_num': 0, 'column_num': 0,
'filetypes': ['python'], 'filetypes': ['python'],
'filepath': '/foo.py', 'filepath': '/foo.py',
'line_value': contents,
'file_data': { 'file_data': {
'/foo.py': { '/foo.py': {
'contents': contents, 'contents': contents,
@ -155,6 +154,49 @@ foo()
app.post_json( '/run_completer_command', goto_data ).json ) app.post_json( '/run_completer_command', goto_data ).json )
@with_setup( Setup )
def RunCompleterCommand_GoTo_Clang_ZeroBasedLineAndColumn_test():
app = TestApp( ycmd.app )
contents = """
struct Foo {
int x;
int y;
char c;
};
int main()
{
Foo foo;
return 0;
}
"""
filename = '/foo.cpp'
goto_data = {
'compilation_flags': ['-x', 'c++'],
'completer_target': 'filetype_default',
'command_arguments': ['GoToDefinition'],
'line_num': 9,
'column_num': 2,
'filetypes': ['cpp'],
'filepath': filename,
'file_data': {
filename: {
'contents': contents,
'filetypes': ['cpp']
}
}
}
# 0-based line and column!
eq_( {
'filepath': '/foo.cpp',
'line_num': 1,
'column_num': 7
},
app.post_json( '/run_completer_command', goto_data ).json )
@with_setup( Setup ) @with_setup( Setup )
def FiletypeCompletionAvailable_Works_test(): def FiletypeCompletionAvailable_Works_test():
app = TestApp( ycmd.app ) app = TestApp( ycmd.app )