GoTo commands for clang completer work again
This commit is contained in:
parent
fe0c0a1607
commit
4a95c2fc7c
@ -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
|
||||||
|
2
cpp/ycm/tests/testdata/basic.cpp
vendored
2
cpp/ycm/tests/testdata/basic.cpp
vendored
@ -2,7 +2,7 @@ struct Foo {
|
|||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
char c;
|
char c;
|
||||||
}
|
};
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user