cb0a5c7a36
When using a compilation database (compile_commands.json) in very large projects, significant delays would occur when changing files -- particularly those that happened to be far down the db. Rather than iterating over the whole list every time, we now build up a lookup table based on the tail of the filename (and tail of the directory for widening searches) and iterate over the much smaller list of compile commands for files with the given name. Test metrics (from compile_database_perf/test.sh) show a 90% performance improvement -- from 25 seconds to 2.5 seconds per run.
211 lines
9.9 KiB
Text
211 lines
9.9 KiB
Text
Before:
|
|
Save g:ale_c_parse_makefile
|
|
|
|
call ale#test#SetDirectory('/testplugin/test')
|
|
|
|
let g:ale_c_parse_makefile = 1
|
|
|
|
After:
|
|
Restore
|
|
|
|
call ale#test#RestoreDirectory()
|
|
|
|
Execute(The CFlags parser should be able to parse include directives):
|
|
call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
|
|
|
|
AssertEqual
|
|
\ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')),
|
|
\ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -c file.c'])
|
|
|
|
Execute(The CFlags parser should be able to parse macro directives):
|
|
call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
|
|
|
|
AssertEqual
|
|
\ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
|
\ . ' -DTEST=1',
|
|
\ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -DTEST=1 -c file.c'])
|
|
|
|
Execute(The CFlags parser should be able to parse macro directives with spaces):
|
|
call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
|
|
|
|
AssertEqual
|
|
\ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
|
\ . ' -DTEST=$(( 2 * 4 ))',
|
|
\ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -DTEST=$(( 2 * 4 )) -c file.c'])
|
|
|
|
Execute(The CFlags parser should be able to parse shell directives with spaces):
|
|
call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
|
|
|
|
AssertEqual
|
|
\ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
|
\ . ' -DTEST=`date +%s`',
|
|
\ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -DTEST=`date +%s` -c file.c'])
|
|
|
|
Execute(ParseCFlags should be able to parse flags with relative paths):
|
|
AssertEqual
|
|
\ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
|
|
\ . ' -DTEST=`date +%s`',
|
|
\ ale#c#ParseCFlags(
|
|
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
|
\ 'gcc -Isubdir '
|
|
\ . '-I'. ale#path#Simplify('kernel/include')
|
|
\ . ' -DTEST=`date +%s` -c file.c'
|
|
\ )
|
|
|
|
Execute(ParseCFlags should be able to parse -Dgoal):
|
|
AssertEqual
|
|
\ '-Dgoal=9'
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
|
|
\ . ' -DTEST=`date +%s`',
|
|
\ ale#c#ParseCFlags(
|
|
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
|
\ 'gcc -Dgoal=9 -Isubdir '
|
|
\ . '-I'. ale#path#Simplify('kernel/include')
|
|
\ . ' -DTEST=`date +%s` -c file.c'
|
|
\ )
|
|
|
|
Execute(ParseCFlags should ignore -T and other arguments):
|
|
AssertEqual
|
|
\ '-Dgoal=9'
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
|
|
\ . ' -DTEST=`date +%s`',
|
|
\ ale#c#ParseCFlags(
|
|
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
|
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir --sysroot=subdir '
|
|
\ . '-I'. ale#path#Simplify('kernel/include')
|
|
\ . ' -DTEST=`date +%s` -c file.c'
|
|
\ )
|
|
|
|
Execute(ParseCFlags should handle paths with spaces in double quotes):
|
|
AssertEqual
|
|
\ '-Dgoal=9'
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
|
|
\ . ' -DTEST=`date +%s`',
|
|
\ ale#c#ParseCFlags(
|
|
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
|
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
|
|
\ . '-I"dir with spaces"' . ' -I'. ale#path#Simplify('kernel/include')
|
|
\ . ' -DTEST=`date +%s` -c file.c'
|
|
\ )
|
|
|
|
Execute(ParseCFlags should handle paths with spaces in single quotes):
|
|
AssertEqual
|
|
\ '-Dgoal=9'
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
|
|
\ . ' -DTEST=`date +%s`',
|
|
\ ale#c#ParseCFlags(
|
|
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
|
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
|
|
\ . '-I''dir with spaces''' . ' -I'. ale#path#Simplify('kernel/include')
|
|
\ . ' -DTEST=`date +%s` -c file.c'
|
|
\ )
|
|
|
|
Execute(ParseCFlags should handle paths with minuses):
|
|
AssertEqual
|
|
\ '-Dgoal=9'
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
|
|
\ . ' -DTEST=`date +%s`',
|
|
\ ale#c#ParseCFlags(
|
|
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
|
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
|
|
\ . '-I''dir with spaces''' . ' -Idir-with-dash'
|
|
\ . ' -I'. ale#path#Simplify('kernel/include')
|
|
\ . ' -DTEST=`date +%s` -c file.c'
|
|
\ )
|
|
|
|
Execute(ParseCFlags should handle -D with minuses):
|
|
AssertEqual
|
|
\ '-Dgoal=9'
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
|
\ . ' -Dmacro-with-dash'
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
|
|
\ . ' -DTEST=`date +%s`',
|
|
\ ale#c#ParseCFlags(
|
|
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
|
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
|
|
\ . '-Dmacro-with-dash '
|
|
\ . '-I''dir with spaces''' . ' -Idir-with-dash'
|
|
\ . ' -I'. ale#path#Simplify('kernel/include')
|
|
\ . ' -DTEST=`date +%s` -c file.c'
|
|
\ )
|
|
|
|
Execute(ParseCFlags should handle flags at the end of the line):
|
|
AssertEqual
|
|
\ '-Dgoal=9'
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
|
\ . ' -Dmacro-with-dash'
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')),
|
|
\ ale#c#ParseCFlags(
|
|
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
|
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
|
|
\ . '-Dmacro-with-dash '
|
|
\ . '-I''dir with spaces''' . ' -Idir-with-dash'
|
|
\ . ' -I'. ale#path#Simplify('kernel/include')
|
|
\ )
|
|
|
|
Execute(FlagsFromCompileCommands should tolerate empty values):
|
|
AssertEqual '', ale#c#FlagsFromCompileCommands(bufnr(''), '')
|
|
|
|
Execute(ParseCompileCommandsFlags should tolerate empty values):
|
|
AssertEqual '', ale#c#ParseCompileCommandsFlags(bufnr(''), '', {}, {})
|
|
|
|
Execute(ParseCompileCommandsFlags should parse some basic flags):
|
|
noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'))
|
|
|
|
AssertEqual
|
|
\ '-I' . ale#path#Simplify('/usr/include/xmms2'),
|
|
\ ale#c#ParseCompileCommandsFlags(bufnr(''), ale#path#Simplify('/foo/bar/xmms2-mpris'), { "xmms2-mpris.c": [
|
|
\ {
|
|
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
|
|
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2')
|
|
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
|
|
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
|
\ 'file': ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
|
\ },
|
|
\ ] }, {})
|
|
|
|
Execute(ParseCompileCommandsFlags should fall back to files in the same directory):
|
|
noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'))
|
|
|
|
AssertEqual
|
|
\ '-I' . ale#path#Simplify('/usr/include/xmms2'),
|
|
\ ale#c#ParseCompileCommandsFlags(bufnr(''), ale#path#Simplify('/foo/bar/xmms2-mpris'), {}, { "src": [
|
|
\ {
|
|
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
|
|
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2')
|
|
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
|
|
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
|
\ 'file': ale#path#Simplify((has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c'),
|
|
\ },
|
|
\ ] })
|
|
|
|
Execute(ParseCFlags should not merge flags):
|
|
AssertEqual
|
|
\ '-Dgoal=9'
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
|
|
\ . ' ' . ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')),
|
|
\ ale#c#ParseCFlags(
|
|
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
|
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
|
|
\ . 'subdir/somedep1.o ' . 'subdir/somedep2.o '
|
|
\ . '-I''dir with spaces''' . ' -Idir-with-dash '
|
|
\ . 'subdir/somedep3.o ' . 'subdir/somedep4.o '
|
|
\ . ' -I'. ale#path#Simplify('kernel/include') . ' '
|
|
\ . 'subdir/somedep5.o ' . 'subdir/somedep6.o '
|
|
\ )
|