├── .appveyor.yml ├── .clang-format ├── .gitattributes ├── .github └── issue_template.md ├── .gitignore ├── .gitmodules ├── .pep8 ├── .travis.yml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── clang_archive_hashes ├── LLVM-7.0.0-win64.exe.SHA256 ├── clang+llvm-7.0.0-amd64-unknown-freebsd11.tar.xz.SHA256 ├── clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz.SHA256 ├── clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 └── clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 ├── cmake ├── DefaultCMakeBuildType.cmake ├── DownloadAndExtract7zip.cmake ├── DownloadAndExtractClang.cmake └── FindClang.cmake ├── e2e_test_runner.py ├── e2e_tests ├── __init__.py ├── completion.py ├── index_delta │ ├── a_v0.cc │ └── a_v1.cc ├── outline.py ├── sanity.py ├── semantic_highlighting.cc ├── simple_cross_reference │ ├── a.cc │ ├── a.h │ ├── b.cc │ ├── c.cc │ ├── compile_commands2.json │ └── test.cc └── utils.py ├── index_tests ├── _empty_test.cc ├── class_forward_declaration.cc ├── constructors │ ├── constructor.cc │ ├── destructor.cc │ ├── implicit_constructor.cc │ ├── invalid_reference.cc │ ├── make_functions.cc │ └── make_functions.h ├── declaration_vs_definition │ ├── class.cc │ ├── class_member.cc │ ├── class_member_static.cc │ ├── func.cc │ ├── func_associated_function_params.cc │ └── method.cc ├── enums │ ├── enum_class_decl.cc │ ├── enum_decl.cc │ ├── enum_inherit.cc │ └── enum_usage.cc ├── foobar.cc ├── function_declaration.cc ├── function_declaration_definition.cc ├── function_definition.cc ├── inheritance │ ├── class_inherit.cc │ ├── class_inherit_templated_parent.cc │ ├── class_multiple_inherit.cc │ ├── function_override.cc │ ├── interface_pure_virtual.cc │ └── multiple_base_functions.cc ├── lambdas │ └── lambda.cc ├── macros │ ├── complex.cc │ └── foo.cc ├── method_declaration.cc ├── method_definition.cc ├── method_inline_declaration.cc ├── multi_file │ ├── funky_enum.cc │ ├── funky_enum.h │ ├── header.h │ ├── impl.cc │ ├── simple_header.h │ ├── simple_impl.cc │ ├── static.cc │ └── static.h ├── namespaces │ ├── anonymous_function.cc │ ├── function_declaration.cc │ ├── function_definition.cc │ ├── method_declaration.cc │ ├── method_definition.cc │ ├── method_inline_declaration.cc │ ├── namespace_alias.cc │ └── namespace_reference.cc ├── objective-c │ └── class.m ├── operators │ └── operator.cc ├── outline │ ├── outline.cc │ ├── outline2.cc │ ├── static_function_in_type.cc │ └── static_function_in_type.h ├── preprocessor │ ├── include_guard.cc │ └── skipped.cc ├── templates │ ├── func_specialized_template_param.cc │ ├── implicit_variable_instantiation.cc │ ├── member_ref_in_template.cc │ ├── namespace_template_class_template_func_usage_folded_into_one.cc │ ├── namespace_template_type_usage_folded_into_one.cc │ ├── specialization.cc │ ├── specialized_func_definition.cc │ ├── template_class_func_usage_folded_into_one.cc │ ├── template_class_template_func_usage_folded_into_one.cc │ ├── template_class_type_usage_folded_into_one.cc │ ├── template_class_var_usage_folded_into_one.cc │ ├── template_func_usage_folded_into_one.cc │ ├── template_type_usage_folded_into_one.cc │ └── template_var_usage_folded_into_one.cc ├── types │ ├── anonymous_struct.cc │ └── typedefs.cc ├── unions │ ├── union_decl.cc │ └── union_usage.cc ├── usage │ ├── func_called_from_constructor.cc │ ├── func_called_from_macro_argument.cc │ ├── func_called_from_template.cc │ ├── func_called_implicit_ctor.cc │ ├── func_usage_addr_func.cc │ ├── func_usage_addr_method.cc │ ├── func_usage_call_func.cc │ ├── func_usage_call_method.cc │ ├── func_usage_class_inline_var_def.cc │ ├── func_usage_forward_decl_func.cc │ ├── func_usage_forward_decl_method.cc │ ├── func_usage_template_func.cc │ ├── type_usage_as_template_parameter.cc │ ├── type_usage_as_template_parameter_complex.cc │ ├── type_usage_as_template_parameter_simple.cc │ ├── type_usage_declare_extern.cc │ ├── type_usage_declare_field.cc │ ├── type_usage_declare_local.cc │ ├── type_usage_declare_param.cc │ ├── type_usage_declare_param_prototype.cc │ ├── type_usage_declare_param_unnamed.cc │ ├── type_usage_declare_qualifiers.cc │ ├── type_usage_declare_static.cc │ ├── type_usage_on_return_type.cc │ ├── type_usage_typedef_and_using.cc │ ├── type_usage_typedef_and_using_template.cc │ ├── type_usage_various.cc │ ├── usage_inside_of_call.cc │ ├── usage_inside_of_call_simple.cc │ ├── var_usage_call_function.cc │ ├── var_usage_class_member.cc │ ├── var_usage_class_member_static.cc │ ├── var_usage_cstyle_cast.cc │ ├── var_usage_extern.cc │ ├── var_usage_func_parameter.cc │ ├── var_usage_local.cc │ ├── var_usage_shadowed_local.cc │ ├── var_usage_shadowed_parameter.cc │ └── var_usage_static.cc └── vars │ ├── class_member.cc │ ├── class_static_member.cc │ ├── class_static_member_decl_only.cc │ ├── deduce_auto_type.cc │ ├── function_local.cc │ ├── function_param.cc │ ├── function_param_unnamed.cc │ ├── function_shadow_local.cc │ ├── function_shadow_param.cc │ ├── global_variable.cc │ ├── global_variable_decl_only.cc │ └── type_instance_on_using_type.cc ├── publish.py ├── src ├── atomic_object.h ├── c_cpp_properties.cc ├── c_cpp_properties.h ├── cache_manager.cc ├── cache_manager.h ├── clang_complete.cc ├── clang_complete.h ├── clang_cursor.cc ├── clang_cursor.h ├── clang_format.cc ├── clang_format.h ├── clang_index.cc ├── clang_index.h ├── clang_indexer.cc ├── clang_system_include_extractor.cc ├── clang_system_include_extractor.h ├── clang_translation_unit.cc ├── clang_translation_unit.h ├── clang_utils.cc ├── clang_utils.h ├── code_complete_cache.cc ├── code_complete_cache.h ├── command_line.cc ├── compiler.cc ├── compiler.h ├── config.h ├── diagnostics_engine.cc ├── diagnostics_engine.h ├── file_consumer.cc ├── file_consumer.h ├── file_contents.cc ├── file_contents.h ├── file_types.cc ├── file_types.h ├── fuzzy_match.cc ├── fuzzy_match.h ├── hash_utils.h ├── iindexer.cc ├── iindexer.h ├── import_manager.cc ├── import_manager.h ├── import_pipeline.cc ├── import_pipeline.h ├── include_complete.cc ├── include_complete.h ├── indexer.h ├── language.h ├── lex_utils.cc ├── lex_utils.h ├── lru_cache.h ├── lsp.cc ├── lsp.h ├── lsp_code_action.h ├── lsp_completion.h ├── lsp_diagnostic.cc ├── lsp_diagnostic.h ├── match.cc ├── match.h ├── maybe.h ├── message_handler.cc ├── message_handler.h ├── messages │ ├── cquery_base.cc │ ├── cquery_call_hierarchy.cc │ ├── cquery_callers.cc │ ├── cquery_did_view.cc │ ├── cquery_file_info.cc │ ├── cquery_freshen_index.cc │ ├── cquery_index_file.cc │ ├── cquery_inheritance_hierarchy.cc │ ├── cquery_vars.cc │ ├── cquery_wait.cc │ ├── exit.cc │ ├── initialize.cc │ ├── shutdown.cc │ ├── text_document_code_action.cc │ ├── text_document_code_lens.cc │ ├── text_document_completion.cc │ ├── text_document_definition.cc │ ├── text_document_did_change.cc │ ├── text_document_did_close.cc │ ├── text_document_did_open.cc │ ├── text_document_did_save.cc │ ├── text_document_document_highlight.cc │ ├── text_document_document_link.cc │ ├── text_document_document_symbol.cc │ ├── text_document_formatting.cc │ ├── text_document_hover.cc │ ├── text_document_implementation.cc │ ├── text_document_range_formatting.cc │ ├── text_document_references.cc │ ├── text_document_rename.cc │ ├── text_document_signature_help.cc │ ├── text_document_type_definition.cc │ ├── workspace_did_change_configuration.cc │ ├── workspace_did_change_watched_files.cc │ ├── workspace_execute_command.cc │ └── workspace_symbol.cc ├── method.cc ├── method.h ├── options.cc ├── options.h ├── platform.cc ├── platform.h ├── platform_posix.cc ├── platform_win.cc ├── position.cc ├── position.h ├── project.cc ├── project.h ├── query.cc ├── query.h ├── query_utils.cc ├── query_utils.h ├── queue_manager.cc ├── queue_manager.h ├── recorder.cc ├── recorder.h ├── semantic_highlight_symbol_cache.cc ├── semantic_highlight_symbol_cache.h ├── serializer.cc ├── serializer.h ├── serializers │ ├── json.h │ └── msgpack.h ├── standard_includes.cc ├── standard_includes.h ├── symbol.h ├── task.cc ├── task.h ├── test.cc ├── test.h ├── third_party_impl.cc ├── threaded_queue.cc ├── threaded_queue.h ├── timer.cc ├── timer.h ├── timestamp_manager.cc ├── timestamp_manager.h ├── type_printer.cc ├── type_printer.h ├── utils.cc ├── utils.h ├── work_thread.cc ├── work_thread.h ├── working_files.cc └── working_files.h ├── third_party ├── macro_map.h ├── optional.h ├── optional.hpp ├── siphash.cc ├── siphash.h ├── string_view.h ├── string_view.hpp └── tinydir.h └── waf /.appveyor.yml: -------------------------------------------------------------------------------- 1 | version: "{build}" 2 | image: Visual Studio 2017 3 | platform: x64 4 | configuration: Debug 5 | 6 | install: 7 | - git submodule update --init 8 | 9 | environment: 10 | CLICOLOR_FORCE: 1 11 | CHERE_INVOKING: 1 # Tell Bash to inherit the current working directory 12 | matrix: 13 | - MSYSTEM: MINGW64 14 | - MSYSTEM: MSVC 15 | 16 | matrix: 17 | fast_finish: true # Immediately finish build if one of the jobs fails. 18 | 19 | for: 20 | - 21 | matrix: 22 | only: 23 | - MSYSTEM: MINGW64 24 | build_script: 25 | ps: "C:\\msys64\\usr\\bin\\bash -lc @\"\n 26 | cmake -G'MSYS Makefiles' -DCMAKE_INSTALL_PREFIX=install .\n 27 | make -j$(nproc) install 2>&1\n 28 | cp /mingw64/bin/libgcc_s_seh-1.dll install/bin\n 29 | cp /mingw64/bin/libstdc++-6.dll install/bin\n 30 | cp /mingw64/bin/libwinpthread-1.dll install/bin\n\"@" 31 | - 32 | matrix: 33 | only: 34 | - MSYSTEM: MSVC 35 | before_build: 36 | - cmake -DCI=ON -DCMAKE_INSTALL_PREFIX=install -DCMAKE_GENERATOR_PLATFORM=x64 . 37 | build: 38 | project: cquery.sln 39 | after_build: 40 | - cmake --build . --target install 41 | 42 | test_script: 43 | - .\install\bin\cquery.exe --ci --log-all-to-stderr --test-unit 44 | - .\install\bin\cquery.exe --ci --log-all-to-stderr --test-index 45 | 46 | cache: 47 | - C:\projects\cquery\build\LLVM-6.0.0-win64\ 48 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Chromium 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # By default, use platform specific endings. 2 | *.h text eol=auto 3 | *.cpp text eol=auto 4 | *.cc text eol=auto 5 | 6 | # Tests must always be crlf 7 | index_tests/** text eol=crlf 8 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .cquery_cached_index 2 | .DS_Store 3 | .lock-waf* 4 | .vs 5 | .vscode/ 6 | .vscode/.ropeproject 7 | .waf* 8 | *.cquery 9 | *.sln 10 | *.swp 11 | *.vcxproj 12 | *.vcxproj.filters 13 | *.vcxproj.user 14 | **/*.pyc 15 | build* 16 | cquery_diagnostics.log 17 | cquery_log.txt 18 | Debug 19 | e2e_cache 20 | foo* 21 | libcxx 22 | vscode-extension.vsix 23 | waf-* 24 | waf2* 25 | waf3* 26 | x64 27 | .ycm_extra_conf.py 28 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third_party/rapidjson"] 2 | path = third_party/rapidjson 3 | url = https://github.com/miloyip/rapidjson 4 | [submodule "third_party/doctest"] 5 | path = third_party/doctest 6 | url = https://github.com/onqtam/doctest 7 | [submodule "third_party/sparsepp"] 8 | path = third_party/sparsepp 9 | url = https://github.com/greg7mdp/sparsepp 10 | [submodule "third_party/loguru"] 11 | path = third_party/loguru 12 | url = https://github.com/emilk/loguru 13 | [submodule "third_party/msgpack-c"] 14 | path = third_party/msgpack-c 15 | url = https://github.com/msgpack/msgpack-c 16 | [submodule "third_party/pugixml"] 17 | path = third_party/pugixml 18 | url = https://github.com/zeux/pugixml 19 | [submodule "third_party/reproc"] 20 | path = third_party/reproc 21 | url = https://github.com/DaanDeMeyer/reproc.git 22 | -------------------------------------------------------------------------------- /.pep8: -------------------------------------------------------------------------------- 1 | [pep8] 2 | indent-size=2 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | sudo: false 3 | # Use generic to avoid travis-ci overwriting CC and CXX 4 | # See: https://stackoverflow.com/questions/35110123/travis-ci-with-c14-and-linux 5 | language: generic 6 | 7 | # Default git clone --recursive clones unnecessary dependencies so we override 8 | # it with our own command in before_install 9 | git: 10 | submodules: false 11 | depth: 1 12 | 13 | addons: 14 | apt: 15 | sources: &sources 16 | - ubuntu-toolchain-r-test 17 | - llvm-toolchain-precise-3.6 18 | - llvm-toolchain-trusty-6.0 19 | 20 | cache: 21 | directories: 22 | - clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04/ 23 | - clang+llvm-6.0.0-x86_64-apple-darwin/ 24 | 25 | # When building with Clang GCC still has to be installed to provide libstdc++ 26 | # that Clang uses (Clang doesn't bundle libc++) 27 | matrix: 28 | fast_finish: true 29 | include: 30 | - os: linux 31 | env: CC=gcc-5 CXX=g++-5 32 | addons: 33 | apt: 34 | sources: *sources 35 | packages: 36 | - g++-5 37 | 38 | - os: linux 39 | env: CC=gcc-7 CXX=g++-7 40 | addons: 41 | apt: 42 | sources: *sources 43 | packages: 44 | - g++-7 45 | 46 | - os: linux 47 | env: CC=clang-3.6 CXX=clang++-3.6 48 | addons: 49 | apt: 50 | sources: *sources 51 | packages: 52 | - clang-3.6 53 | - g++-5 54 | 55 | - os: linux 56 | env: CC=clang-6.0 CXX=clang++-6.0 57 | addons: 58 | apt: 59 | sources: *sources 60 | packages: 61 | - clang-6.0 62 | - g++-5 63 | 64 | - os: osx 65 | osx_image: xcode9.2 66 | env: CC=clang CXX=clang++ 67 | 68 | before_install: 69 | - git submodule update --init 70 | - eval "${INSTALL}" 71 | 72 | script: 73 | - cmake -DCI=ON -DCMAKE_INSTALL_PREFIX=install -DCMAKE_BUILD_TYPE=Debug . 74 | - cmake --build . -- -j 3 75 | - cmake --build . --target install 76 | - ./install/bin/cquery --ci --log-all-to-stderr --test-unit 77 | - ./install/bin/cquery --ci --log-all-to-stderr --test-index 78 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017-2018 Jacob Dufault 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /clang_archive_hashes/LLVM-7.0.0-win64.exe.SHA256: -------------------------------------------------------------------------------- 1 | 74b197a3959b0408adf0824be01db8dddfa2f9a967f4085af3fad900ed5fdbf6 -------------------------------------------------------------------------------- /clang_archive_hashes/clang+llvm-7.0.0-amd64-unknown-freebsd11.tar.xz.SHA256: -------------------------------------------------------------------------------- 1 | 95ceb933ccf76e3ddaa536f41ab82c442bbac07cdea6f9fbf6e3b13cc1711255 -------------------------------------------------------------------------------- /clang_archive_hashes/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz.SHA256: -------------------------------------------------------------------------------- 1 | b3ad93c3d69dfd528df9c5bb1a434367babb8f3baea47fbb99bf49f1b03c94ca -------------------------------------------------------------------------------- /clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256: -------------------------------------------------------------------------------- 1 | 5c90e61b06d37270bc26edb305d7e498e2c7be22d99e0afd9f2274ef5458575a -------------------------------------------------------------------------------- /clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256: -------------------------------------------------------------------------------- 1 | 69b85c833cd28ea04ce34002464f10a6ad9656dd2bba0f7133536a9927c660d2 -------------------------------------------------------------------------------- /cmake/DefaultCMakeBuildType.cmake: -------------------------------------------------------------------------------- 1 | set(DEFAULT_CMAKE_BUILD_TYPE Release) 2 | 3 | # CMAKE_BUILD_TYPE is not available if a multi-configuration generator is used 4 | # (eg Visual Studio generators) 5 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 6 | message(STATUS "Setting build type to '${DEFAULT_CMAKE_BUILD_TYPE}' as none \ 7 | was specified.") 8 | set(CMAKE_BUILD_TYPE ${DEFAULT_CMAKE_BUILD_TYPE} 9 | CACHE STRING "Choose the type of build." FORCE) 10 | 11 | # Set the possible values of build type for cmake-gui 12 | set_property(CACHE CMAKE_BUILD_TYPE 13 | PROPERTY STRINGS Debug Release MinSizeRel RelWithDebInfo) 14 | endif() 15 | -------------------------------------------------------------------------------- /cmake/DownloadAndExtract7zip.cmake: -------------------------------------------------------------------------------- 1 | # Downloads and extracts the 7-Zip MSI installer from https://www.7-zip.org/. 2 | # 3 | # Returns the extracted 7-Zip directory in DOWNLOADED_7ZIP_DIR 4 | function(download_and_extract_7zip 7ZIP_DOWNLOAD_LOCATION) 5 | 6 | set(7ZIP_VERSION 1801) 7 | set(7ZIP_EXT .msi) 8 | set(7ZIP_NAME 7z${7ZIP_VERSION}-x64) 9 | set(7ZIP_FULL_NAME ${7ZIP_NAME}${7ZIP_EXT}) 10 | 11 | set(7ZIP_FILE ${7ZIP_DOWNLOAD_LOCATION}/${7ZIP_FULL_NAME}) 12 | set(7ZIP_EXTRACT_DIR ${7ZIP_DOWNLOAD_LOCATION}/${7ZIP_NAME}) 13 | set(7ZIP_URL https://www.7-zip.org/a/${7ZIP_FULL_NAME}) 14 | 15 | # Exit if 7-Zip is already downloaded and extracted 16 | find_program(7ZIP_EXECUTABLE 17 | NAMES 7z 18 | NO_DEFAULT_PATH 19 | PATHS ${7ZIP_EXTRACT_DIR}/Files/7-Zip 20 | ) 21 | 22 | if(7ZIP_EXECUTABLE) 23 | message(STATUS "7-Zip already downloaded") 24 | return() 25 | endif() 26 | 27 | message(STATUS "Downloading 7-Zip ${7ZIP_VERSION} (${7ZIP_URL}) ...") 28 | file(DOWNLOAD ${7ZIP_URL} ${7ZIP_FILE}) 29 | 30 | find_program(MSIEXEC_EXECUTABLE msiexec) 31 | if(NOT MSIEXEC_EXECUTABLE) 32 | message(FATAL_ERROR "Unable to find msiexec (required to extract 7-Zip msi \ 33 | installer). Install 7-Zip yourself and make sure it is available in the path") 34 | endif() 35 | 36 | message(STATUS "Extracting downloaded 7-Zip ...") 37 | 38 | # msiexec requires Windows path separators (\) 39 | file(TO_NATIVE_PATH ${7ZIP_FILE} 7ZIP_FILE) 40 | file(TO_NATIVE_PATH ${7ZIP_EXTRACT_DIR} 7ZIP_EXTRACT_DIR) 41 | 42 | # msiexec with /a option allows extraction of msi installers without requiring 43 | # admin privileges. We use this to extract the 7-Zip installer without 44 | # requiring any actions from the user 45 | execute_process( 46 | COMMAND ${MSIEXEC_EXECUTABLE} /a ${7ZIP_FILE} /qn 47 | TARGETDIR=${7ZIP_EXTRACT_DIR} 48 | WORKING_DIRECTORY ${7ZIP_DOWNLOAD_LOCATION} 49 | OUTPUT_QUIET 50 | ) 51 | 52 | # Convert back to CMake separators (/) before returning 53 | file(TO_CMAKE_PATH ${7ZIP_EXTRACT_DIR} 7ZIP_EXTRACT_DIR) 54 | 55 | # Actual 7-Zip directory is nested inside the extract directory. 56 | set(DOWNLOADED_7ZIP_DIR ${7ZIP_EXTRACT_DIR}/Files/7-Zip PARENT_SCOPE) 57 | 58 | endfunction() -------------------------------------------------------------------------------- /e2e_tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobdufault/cquery/9b80917cbf7d26b78ec62b409442ecf96f72daf9/e2e_tests/__init__.py -------------------------------------------------------------------------------- /e2e_tests/completion.py: -------------------------------------------------------------------------------- 1 | import e2e_test_runner 2 | from e2e_tests.utils import * 3 | 4 | def IGNORE_Test_Completion(): 5 | return (e2e_test_runner.TestBuilder() 6 | .SetupCommonInit() 7 | .IndexFile("foo.cc", 8 | """ 9 | struct Foo { 10 | int aaa; 11 | }; 12 | void foobar() { 13 | Foo f; 14 | f.a 15 | }""") 16 | .WaitForIdle() 17 | .SendDidOpen('foo.cc') 18 | .Send({ 19 | 'id': 1, 20 | 'method': 'textDocument/completion', 21 | 'params': { 22 | 'textDocument': { 23 | 'uri': BuildUri('foo.cc') 24 | }, 25 | 'position': { 26 | 'line': 7, 27 | 'character': 5 28 | } 29 | } 30 | }) 31 | .Expect({ 32 | 'id': 1, 33 | 'result': [{ 34 | }] 35 | })) 36 | -------------------------------------------------------------------------------- /e2e_tests/index_delta/a_v0.cc: -------------------------------------------------------------------------------- 1 | void called(); 2 | 3 | void caller() { 4 | 5 | } 6 | 7 | void missing() {} -------------------------------------------------------------------------------- /e2e_tests/index_delta/a_v1.cc: -------------------------------------------------------------------------------- 1 | void called(); 2 | 3 | void caller() { 4 | called(); 5 | } 6 | 7 | void added() {} -------------------------------------------------------------------------------- /e2e_tests/outline.py: -------------------------------------------------------------------------------- 1 | import e2e_test_runner 2 | from e2e_tests.utils import * 3 | 4 | def Test_Outline(): 5 | return (e2e_test_runner.TestBuilder() 6 | .SetupCommonInit() 7 | .IndexFile("foo.cc", 8 | """void foobar();""") 9 | .WaitForIdle() 10 | .Send({ 11 | 'id': 1, 12 | 'method': 'textDocument/documentSymbol', 13 | 'params': { 14 | 'textDocument': { 15 | 'uri': BuildUri('foo.cc') 16 | } 17 | } 18 | }) 19 | .Expect({ 20 | 'id': 1, 21 | 'result': [{ 22 | 'containerName': 'void foobar()', 23 | 'kind': 12, 24 | 'name': 'foobar', 25 | 'location': { 26 | 'range': { 27 | 'start': { 28 | 'line': 0, 29 | 'character': 5 30 | }, 31 | 'end': { 32 | 'line': 0, 33 | 'character': 11 34 | } 35 | }, 36 | 'uri': BuildUri('foo.cc') 37 | } 38 | }] 39 | })) 40 | -------------------------------------------------------------------------------- /e2e_tests/sanity.py: -------------------------------------------------------------------------------- 1 | import e2e_test_runner 2 | 3 | 4 | def Test_Sanity(): 5 | return (e2e_test_runner.TestBuilder() 6 | .SetupCommonInit()) 7 | -------------------------------------------------------------------------------- /e2e_tests/semantic_highlighting.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #pragma clang attribute push([[nodiscard]], apply_to=enum) 3 | enum class E { E0, E1 = 1, E2, E3 }; 4 | #pragma clang attribute pop 5 | 6 | #define M0(x) 7 | #define M1(x) M0(x)+M0(x) 8 | #define M2 __FILE__ 9 | #define M3 __LINE__ 10 | #define M4(x, y) x##y 11 | 12 | #if __has_feature(meow) && __clang__ 13 | // skipped range 14 | #endif 15 | 16 | extern int extern0, extern1, extern2; 17 | thread_local double thread0 = 42, thread1 = 1.911042e9, thread2 = 0xcafe; 18 | int global0 = 20130802, global1 = 0xdefc0, global2 __attribute__((vector_size(16))); 19 | static int static_global0, static_global1, static_global2; 20 | 21 | struct A { 22 | unsigned int mem0, mem1, mem2; 23 | static int static_mem0, static_mem1, static_mem2; 24 | A(); 25 | ~A(); 26 | A&& mem_func0() noexcept; 27 | virtual void mem_func1() {} 28 | void mem_func2() __attribute__((deprecated(""))) {} 29 | static int static_func0(); 30 | static void static_func1() {} 31 | static void static_func2() throw() {} 32 | }; 33 | 34 | struct S0; struct S1 {}; struct S2 : A, S1 {}; 35 | class C0; class C1 {}; class C2 {}; 36 | union U0; union U1 {}; union U2 {}; 37 | 38 | template 39 | int foo(F &&f, F1, int p = 0) { 40 | T0 t0 = 0xb612; 41 | T1 t1{46610}; 42 | T2 t2(44); 43 | t0 = t1 + t2 + long(&t0) + (long long)A::static_func0; 44 | t2 = t1 = t0; 45 | __builtin_trap(); 46 | return t0 ? t1 * t2 << I0 : I1; 47 | } 48 | 49 | namespace n0 { 50 | typedef int T0; 51 | typedef long double T1[sizeof(T0)]; 52 | using T2 = T1; 53 | namespace n1::n2::n3::n4::n5 { 54 | void foo(float p0, short p1 = 555) { 55 | auto a = A(); 56 | (new A)->~A(); 57 | new char[sizeof(p0)]; 58 | int local0 = 20140819; 59 | double local1 = 0x2015071f5, local2 = 20161010; 60 | static int static_mem0, static_mem1, static_mem2; 61 | extern __fp16 extern0, extern1, extern2; 62 | auto l0 = [&](int q0, int q1) { return q0 + q1; }; 63 | ::foo([p0, p1](int q0, int q1) { return p0 + q0; }, l0); 64 | } 65 | } 66 | } 67 | 68 | using namespace n0; 69 | -------------------------------------------------------------------------------- /e2e_tests/simple_cross_reference/a.cc: -------------------------------------------------------------------------------- 1 | #include "a.h" 2 | 3 | namespace { 4 | void LocalA() { 5 | Common(); 6 | } 7 | } // namespace 8 | 9 | void Common() {} -------------------------------------------------------------------------------- /e2e_tests/simple_cross_reference/a.h: -------------------------------------------------------------------------------- 1 | #ifndef A_H_ 2 | #define A_H_ 3 | 4 | void Common(); 5 | 6 | #endif // A_H_ -------------------------------------------------------------------------------- /e2e_tests/simple_cross_reference/b.cc: -------------------------------------------------------------------------------- 1 | #include "a.h" 2 | 3 | #if RANDOM_DEFINE 4 | static void LocalB() { 5 | Common(); 6 | } 7 | #endif // RANDOM_DEFINE 8 | 9 | static void LocalC() {} -------------------------------------------------------------------------------- /e2e_tests/simple_cross_reference/c.cc: -------------------------------------------------------------------------------- 1 | #include "a.h" 2 | 3 | #if RANDOM_DEFINE 4 | static void LocalC() { 5 | Common(); 6 | } 7 | #endif // RANDOM_DEFINE 8 | 9 | static void LocalD() {} -------------------------------------------------------------------------------- /e2e_tests/simple_cross_reference/compile_commands2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "directory" : "full_tests/simple_cross_reference", 4 | "command" : "clang -c -o a.o a.cc", 5 | "file" : "a.cc" 6 | }, 7 | { 8 | "directory" : "full_tests/simple_cross_reference", 9 | "command" : "clang -DRANDOM_DEFINE -c -o b.o b.cc", 10 | "file" : "b.cc" 11 | }, 12 | { 13 | "directory" : "full_tests/simple_cross_reference", 14 | "command" : "clang -DRANDOM_DEFINE -c -o b.o b.cc", 15 | "file" : "test.cc" 16 | } 17 | ] -------------------------------------------------------------------------------- /e2e_tests/simple_cross_reference/test.cc: -------------------------------------------------------------------------------- 1 | void foo() {} 2 | void bar() {} 3 | 4 | void foobar(); 5 | 6 | void foobar(int a, int b) {}; 7 | 8 | class HelloWorld { 9 | void method() {} 10 | }; 11 | 12 | static void staticfoo() { 13 | } -------------------------------------------------------------------------------- /e2e_tests/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | def BuildUri(relative_path): 4 | absolute_path = os.path.join(os.getcwd(), relative_path) 5 | map = { 6 | ' ': "%20", 7 | '#': "%23", 8 | '$': "%24", 9 | '&': "%26", 10 | '(': "%28", 11 | ')': "%29", 12 | '+': "%2B", 13 | ',': "%2C", 14 | ':': '%3A', 15 | ';': "%3B", 16 | '?': "%3F", 17 | '@': "%40", 18 | } 19 | 20 | result = "" 21 | for c in absolute_path: 22 | if c in map: 23 | result += map[c] 24 | else: 25 | result += c 26 | 27 | return 'file:///' + result.replace('\\', '/') 28 | 29 | -------------------------------------------------------------------------------- /index_tests/_empty_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | OUTPUT: 3 | { 4 | "includes": [], 5 | "skipped_by_preprocessor": [], 6 | "types": [], 7 | "funcs": [], 8 | "vars": [] 9 | } 10 | */ 11 | -------------------------------------------------------------------------------- /index_tests/class_forward_declaration.cc: -------------------------------------------------------------------------------- 1 | class Foo; 2 | class Foo; 3 | class Foo {}; 4 | class Foo; 5 | 6 | /* 7 | OUTPUT: 8 | { 9 | "includes": [], 10 | "skipped_by_preprocessor": [], 11 | "types": [{ 12 | "id": 0, 13 | "usr": 15041163540773201510, 14 | "detailed_name": "Foo", 15 | "short_name": "Foo", 16 | "kind": 5, 17 | "declarations": ["1:7-1:10|-1|1|1", "2:7-2:10|-1|1|1", "4:7-4:10|-1|1|1"], 18 | "spell": "3:7-3:10|-1|1|2", 19 | "extent": "3:1-3:13|-1|1|0", 20 | "bases": [], 21 | "derived": [], 22 | "types": [], 23 | "funcs": [], 24 | "vars": [], 25 | "instances": [], 26 | "uses": [] 27 | }], 28 | "funcs": [], 29 | "vars": [] 30 | } 31 | */ 32 | -------------------------------------------------------------------------------- /index_tests/constructors/invalid_reference.cc: -------------------------------------------------------------------------------- 1 | struct Foo {}; 2 | 3 | template 4 | Foo::Foo() {} 5 | 6 | /* 7 | EXTRA_FLAGS: 8 | -fms-compatibility 9 | -fdelayed-template-parsing 10 | 11 | OUTPUT: 12 | { 13 | "includes": [], 14 | "skipped_by_preprocessor": [], 15 | "types": [{ 16 | "id": 0, 17 | "usr": 15041163540773201510, 18 | "detailed_name": "Foo", 19 | "short_name": "Foo", 20 | "kind": 23, 21 | "declarations": ["4:6-4:9|-1|1|4"], 22 | "spell": "1:8-1:11|-1|1|2", 23 | "extent": "1:1-1:14|-1|1|0", 24 | "bases": [], 25 | "derived": [], 26 | "types": [], 27 | "funcs": [0], 28 | "vars": [], 29 | "instances": [], 30 | "uses": ["4:6-4:9|-1|1|4", "4:1-4:4|-1|1|4"] 31 | }], 32 | "funcs": [{ 33 | "id": 0, 34 | "usr": 17319723337446061757, 35 | "detailed_name": "Foo::Foo()", 36 | "short_name": "Foo", 37 | "kind": 9, 38 | "storage": 1, 39 | "declarations": [], 40 | "spell": "4:6-4:9|0|2|2", 41 | "extent": "4:1-4:11|-1|1|0", 42 | "declaring_type": 0, 43 | "bases": [], 44 | "derived": [], 45 | "vars": [], 46 | "uses": [], 47 | "callees": [] 48 | }], 49 | "vars": [] 50 | } 51 | */ 52 | -------------------------------------------------------------------------------- /index_tests/constructors/make_functions.h: -------------------------------------------------------------------------------- 1 | struct Bar {}; 2 | 3 | class Foobar { 4 | public: 5 | Foobar() {} 6 | Foobar(int) {} 7 | Foobar(int&&, Bar*, bool*) {} 8 | Foobar(int, Bar*, bool*) {} 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /index_tests/declaration_vs_definition/class.cc: -------------------------------------------------------------------------------- 1 | class Foo; 2 | class Foo; 3 | class Foo {}; 4 | class Foo; 5 | 6 | /* 7 | // NOTE: Separate decl/definition are not supported for classes. See source 8 | // for comments. 9 | OUTPUT: 10 | { 11 | "includes": [], 12 | "skipped_by_preprocessor": [], 13 | "types": [{ 14 | "id": 0, 15 | "usr": 15041163540773201510, 16 | "detailed_name": "Foo", 17 | "short_name": "Foo", 18 | "kind": 5, 19 | "declarations": ["1:7-1:10|-1|1|1", "2:7-2:10|-1|1|1", "4:7-4:10|-1|1|1"], 20 | "spell": "3:7-3:10|-1|1|2", 21 | "extent": "3:1-3:13|-1|1|0", 22 | "bases": [], 23 | "derived": [], 24 | "types": [], 25 | "funcs": [], 26 | "vars": [], 27 | "instances": [], 28 | "uses": [] 29 | }], 30 | "funcs": [], 31 | "vars": [] 32 | } 33 | */ 34 | -------------------------------------------------------------------------------- /index_tests/declaration_vs_definition/class_member.cc: -------------------------------------------------------------------------------- 1 | class Foo { 2 | int foo; 3 | }; 4 | 5 | /* 6 | OUTPUT: 7 | { 8 | "includes": [], 9 | "skipped_by_preprocessor": [], 10 | "types": [{ 11 | "id": 0, 12 | "usr": 15041163540773201510, 13 | "detailed_name": "Foo", 14 | "short_name": "Foo", 15 | "kind": 5, 16 | "declarations": [], 17 | "spell": "1:7-1:10|-1|1|2", 18 | "extent": "1:1-3:2|-1|1|0", 19 | "bases": [], 20 | "derived": [], 21 | "types": [], 22 | "funcs": [], 23 | "vars": [0], 24 | "instances": [], 25 | "uses": [] 26 | }, { 27 | "id": 1, 28 | "usr": 17, 29 | "detailed_name": "", 30 | "short_name": "", 31 | "kind": 0, 32 | "declarations": [], 33 | "bases": [], 34 | "derived": [], 35 | "types": [], 36 | "funcs": [], 37 | "vars": [], 38 | "instances": [0], 39 | "uses": [] 40 | }], 41 | "funcs": [], 42 | "vars": [{ 43 | "id": 0, 44 | "usr": 9736582033442720743, 45 | "detailed_name": "int Foo::foo", 46 | "short_name": "foo", 47 | "declarations": [], 48 | "spell": "2:7-2:10|0|2|2", 49 | "extent": "2:3-2:10|0|2|0", 50 | "type": 1, 51 | "uses": [], 52 | "kind": 8, 53 | "storage": 0 54 | }] 55 | } 56 | */ 57 | -------------------------------------------------------------------------------- /index_tests/declaration_vs_definition/class_member_static.cc: -------------------------------------------------------------------------------- 1 | class Foo { 2 | static int foo; 3 | }; 4 | 5 | int Foo::foo; 6 | 7 | /* 8 | OUTPUT: 9 | { 10 | "includes": [], 11 | "skipped_by_preprocessor": [], 12 | "types": [{ 13 | "id": 0, 14 | "usr": 15041163540773201510, 15 | "detailed_name": "Foo", 16 | "short_name": "Foo", 17 | "kind": 5, 18 | "declarations": [], 19 | "spell": "1:7-1:10|-1|1|2", 20 | "extent": "1:1-3:2|-1|1|0", 21 | "bases": [], 22 | "derived": [], 23 | "types": [], 24 | "funcs": [], 25 | "vars": [0], 26 | "instances": [], 27 | "uses": ["5:5-5:8|-1|1|4"] 28 | }, { 29 | "id": 1, 30 | "usr": 17, 31 | "detailed_name": "", 32 | "short_name": "", 33 | "kind": 0, 34 | "declarations": [], 35 | "bases": [], 36 | "derived": [], 37 | "types": [], 38 | "funcs": [], 39 | "vars": [], 40 | "instances": [0], 41 | "uses": [] 42 | }], 43 | "funcs": [], 44 | "vars": [{ 45 | "id": 0, 46 | "usr": 8942920329766232482, 47 | "detailed_name": "int Foo::foo", 48 | "short_name": "foo", 49 | "declarations": ["2:14-2:17|0|2|1"], 50 | "spell": "5:10-5:13|0|2|2", 51 | "extent": "5:1-5:13|-1|1|0", 52 | "type": 1, 53 | "uses": [], 54 | "kind": 8, 55 | "storage": 1 56 | }] 57 | } 58 | */ 59 | -------------------------------------------------------------------------------- /index_tests/declaration_vs_definition/func.cc: -------------------------------------------------------------------------------- 1 | void foo(); 2 | void foo(); 3 | void foo() {} 4 | void foo(); 5 | 6 | /* 7 | // Note: we always use the latest seen ("most local") definition/declaration. 8 | OUTPUT: 9 | { 10 | "includes": [], 11 | "skipped_by_preprocessor": [], 12 | "types": [], 13 | "funcs": [{ 14 | "id": 0, 15 | "usr": 4259594751088586730, 16 | "detailed_name": "void foo()", 17 | "short_name": "foo", 18 | "kind": 12, 19 | "storage": 1, 20 | "declarations": [{ 21 | "spell": "1:6-1:9|-1|1|1", 22 | "param_spellings": [] 23 | }, { 24 | "spell": "2:6-2:9|-1|1|1", 25 | "param_spellings": [] 26 | }, { 27 | "spell": "4:6-4:9|-1|1|1", 28 | "param_spellings": [] 29 | }], 30 | "spell": "3:6-3:9|-1|1|2", 31 | "extent": "3:1-3:14|-1|1|0", 32 | "bases": [], 33 | "derived": [], 34 | "vars": [], 35 | "uses": [], 36 | "callees": [] 37 | }], 38 | "vars": [] 39 | } 40 | */ 41 | -------------------------------------------------------------------------------- /index_tests/declaration_vs_definition/func_associated_function_params.cc: -------------------------------------------------------------------------------- 1 | int foo(int, int); 2 | int foo(int aa, 3 | int bb); 4 | int foo(int aaa, int bbb); 5 | int foo(int a, int b) { return 0; } 6 | 7 | /* 8 | OUTPUT: 9 | { 10 | "includes": [], 11 | "skipped_by_preprocessor": [], 12 | "types": [{ 13 | "id": 0, 14 | "usr": 17, 15 | "detailed_name": "", 16 | "short_name": "", 17 | "kind": 0, 18 | "declarations": [], 19 | "bases": [], 20 | "derived": [], 21 | "types": [], 22 | "funcs": [], 23 | "vars": [], 24 | "instances": [0, 1], 25 | "uses": [] 26 | }], 27 | "funcs": [{ 28 | "id": 0, 29 | "usr": 2747674671862363334, 30 | "detailed_name": "int foo(int a, int b)", 31 | "short_name": "foo", 32 | "kind": 12, 33 | "storage": 1, 34 | "declarations": [{ 35 | "spell": "1:5-1:8|-1|1|1", 36 | "param_spellings": ["1:12-1:12", "1:17-1:17"] 37 | }, { 38 | "spell": "2:5-2:8|-1|1|1", 39 | "param_spellings": ["2:13-2:15", "3:13-3:15"] 40 | }, { 41 | "spell": "4:5-4:8|-1|1|1", 42 | "param_spellings": ["4:13-4:16", "4:22-4:25"] 43 | }], 44 | "spell": "5:5-5:8|-1|1|2", 45 | "extent": "5:1-5:36|-1|1|0", 46 | "bases": [], 47 | "derived": [], 48 | "vars": [0, 1], 49 | "uses": [], 50 | "callees": [] 51 | }], 52 | "vars": [{ 53 | "id": 0, 54 | "usr": 10480417713467708012, 55 | "detailed_name": "int a", 56 | "short_name": "a", 57 | "declarations": [], 58 | "spell": "5:13-5:14|0|3|2", 59 | "extent": "5:9-5:14|0|3|0", 60 | "type": 0, 61 | "uses": [], 62 | "kind": 253, 63 | "storage": 1 64 | }, { 65 | "id": 1, 66 | "usr": 18099600680625658464, 67 | "detailed_name": "int b", 68 | "short_name": "b", 69 | "declarations": [], 70 | "spell": "5:20-5:21|0|3|2", 71 | "extent": "5:16-5:21|0|3|0", 72 | "type": 0, 73 | "uses": [], 74 | "kind": 253, 75 | "storage": 1 76 | }] 77 | } 78 | */ 79 | -------------------------------------------------------------------------------- /index_tests/enums/enum_decl.cc: -------------------------------------------------------------------------------- 1 | enum Foo { 2 | A, 3 | B = 20 4 | }; 5 | 6 | /* 7 | OUTPUT: 8 | { 9 | "includes": [], 10 | "skipped_by_preprocessor": [], 11 | "types": [{ 12 | "id": 0, 13 | "usr": 16985894625255407295, 14 | "detailed_name": "Foo", 15 | "short_name": "Foo", 16 | "kind": 10, 17 | "declarations": [], 18 | "spell": "1:6-1:9|-1|1|2", 19 | "extent": "1:1-4:2|-1|1|0", 20 | "bases": [], 21 | "derived": [], 22 | "types": [], 23 | "funcs": [], 24 | "vars": [], 25 | "instances": [], 26 | "uses": [] 27 | }], 28 | "funcs": [], 29 | "vars": [{ 30 | "id": 0, 31 | "usr": 439339022761937396, 32 | "detailed_name": "Foo::A", 33 | "short_name": "A", 34 | "hover": "Foo::A = 0", 35 | "declarations": [], 36 | "spell": "2:3-2:4|0|2|2", 37 | "extent": "2:3-2:4|0|2|0", 38 | "type": 0, 39 | "uses": [], 40 | "kind": 22, 41 | "storage": 0 42 | }, { 43 | "id": 1, 44 | "usr": 15962370213938840720, 45 | "detailed_name": "Foo::B", 46 | "short_name": "B", 47 | "hover": "Foo::B = 20", 48 | "declarations": [], 49 | "spell": "3:3-3:4|0|2|2", 50 | "extent": "3:3-3:9|0|2|0", 51 | "type": 0, 52 | "uses": [], 53 | "kind": 22, 54 | "storage": 0 55 | }] 56 | } 57 | */ 58 | -------------------------------------------------------------------------------- /index_tests/enums/enum_usage.cc: -------------------------------------------------------------------------------- 1 | enum class Foo { 2 | A, 3 | B = 20 4 | }; 5 | 6 | Foo x = Foo::A; 7 | 8 | /* 9 | OUTPUT: 10 | { 11 | "includes": [], 12 | "skipped_by_preprocessor": [], 13 | "types": [{ 14 | "id": 0, 15 | "usr": 16985894625255407295, 16 | "detailed_name": "Foo", 17 | "short_name": "Foo", 18 | "kind": 10, 19 | "declarations": [], 20 | "spell": "1:12-1:15|-1|1|2", 21 | "extent": "1:1-4:2|-1|1|0", 22 | "bases": [], 23 | "derived": [], 24 | "types": [], 25 | "funcs": [], 26 | "vars": [], 27 | "instances": [2], 28 | "uses": ["6:1-6:4|-1|1|4", "6:9-6:12|-1|1|4"] 29 | }], 30 | "funcs": [], 31 | "vars": [{ 32 | "id": 0, 33 | "usr": 439339022761937396, 34 | "detailed_name": "Foo::A", 35 | "short_name": "A", 36 | "hover": "Foo::A = 0", 37 | "declarations": [], 38 | "spell": "2:3-2:4|0|2|2", 39 | "extent": "2:3-2:4|0|2|0", 40 | "type": 0, 41 | "uses": ["6:14-6:15|-1|1|4"], 42 | "kind": 22, 43 | "storage": 0 44 | }, { 45 | "id": 1, 46 | "usr": 15962370213938840720, 47 | "detailed_name": "Foo::B", 48 | "short_name": "B", 49 | "hover": "Foo::B = 20", 50 | "declarations": [], 51 | "spell": "3:3-3:4|0|2|2", 52 | "extent": "3:3-3:9|0|2|0", 53 | "type": 0, 54 | "uses": [], 55 | "kind": 22, 56 | "storage": 0 57 | }, { 58 | "id": 2, 59 | "usr": 10677751717622394455, 60 | "detailed_name": "Foo x", 61 | "short_name": "x", 62 | "hover": "Foo x = Foo::A", 63 | "declarations": [], 64 | "spell": "6:5-6:6|-1|1|2", 65 | "extent": "6:1-6:15|-1|1|0", 66 | "type": 0, 67 | "uses": [], 68 | "kind": 13, 69 | "storage": 1 70 | }] 71 | } 72 | */ 73 | -------------------------------------------------------------------------------- /index_tests/function_declaration.cc: -------------------------------------------------------------------------------- 1 | void foo(int a, int b); 2 | 3 | /* 4 | OUTPUT: 5 | { 6 | "includes": [], 7 | "skipped_by_preprocessor": [], 8 | "types": [], 9 | "funcs": [{ 10 | "id": 0, 11 | "usr": 2747674671862363334, 12 | "detailed_name": "void foo(int a, int b)", 13 | "short_name": "foo", 14 | "kind": 12, 15 | "storage": 1, 16 | "declarations": [{ 17 | "spell": "1:6-1:9|-1|1|1", 18 | "param_spellings": ["1:14-1:15", "1:21-1:22"] 19 | }], 20 | "bases": [], 21 | "derived": [], 22 | "vars": [], 23 | "uses": [], 24 | "callees": [] 25 | }], 26 | "vars": [] 27 | } 28 | */ 29 | -------------------------------------------------------------------------------- /index_tests/function_declaration_definition.cc: -------------------------------------------------------------------------------- 1 | void foo(); 2 | 3 | void foo() {} 4 | 5 | /* 6 | OUTPUT: 7 | { 8 | "includes": [], 9 | "skipped_by_preprocessor": [], 10 | "types": [], 11 | "funcs": [{ 12 | "id": 0, 13 | "usr": 4259594751088586730, 14 | "detailed_name": "void foo()", 15 | "short_name": "foo", 16 | "kind": 12, 17 | "storage": 1, 18 | "declarations": [{ 19 | "spell": "1:6-1:9|-1|1|1", 20 | "param_spellings": [] 21 | }], 22 | "spell": "3:6-3:9|-1|1|2", 23 | "extent": "3:1-3:14|-1|1|0", 24 | "bases": [], 25 | "derived": [], 26 | "vars": [], 27 | "uses": [], 28 | "callees": [] 29 | }], 30 | "vars": [] 31 | } 32 | */ 33 | -------------------------------------------------------------------------------- /index_tests/function_definition.cc: -------------------------------------------------------------------------------- 1 | void foo() {} 2 | 3 | /* 4 | OUTPUT: 5 | { 6 | "includes": [], 7 | "skipped_by_preprocessor": [], 8 | "types": [], 9 | "funcs": [{ 10 | "id": 0, 11 | "usr": 4259594751088586730, 12 | "detailed_name": "void foo()", 13 | "short_name": "foo", 14 | "kind": 12, 15 | "storage": 1, 16 | "declarations": [], 17 | "spell": "1:6-1:9|-1|1|2", 18 | "extent": "1:1-1:14|-1|1|0", 19 | "bases": [], 20 | "derived": [], 21 | "vars": [], 22 | "uses": [], 23 | "callees": [] 24 | }], 25 | "vars": [] 26 | } 27 | */ 28 | -------------------------------------------------------------------------------- /index_tests/inheritance/class_inherit.cc: -------------------------------------------------------------------------------- 1 | class Parent {}; 2 | class Derived : public Parent {}; 3 | 4 | /* 5 | OUTPUT: 6 | { 7 | "includes": [], 8 | "skipped_by_preprocessor": [], 9 | "types": [{ 10 | "id": 0, 11 | "usr": 3866412049634585509, 12 | "detailed_name": "Parent", 13 | "short_name": "Parent", 14 | "kind": 5, 15 | "declarations": ["2:24-2:30|-1|1|4"], 16 | "spell": "1:7-1:13|-1|1|2", 17 | "extent": "1:1-1:16|-1|1|0", 18 | "bases": [], 19 | "derived": [1], 20 | "types": [], 21 | "funcs": [], 22 | "vars": [], 23 | "instances": [], 24 | "uses": ["2:24-2:30|-1|1|4"] 25 | }, { 26 | "id": 1, 27 | "usr": 10963370434658308541, 28 | "detailed_name": "Derived", 29 | "short_name": "Derived", 30 | "kind": 5, 31 | "declarations": [], 32 | "spell": "2:7-2:14|-1|1|2", 33 | "extent": "2:1-2:33|-1|1|0", 34 | "bases": [0], 35 | "derived": [], 36 | "types": [], 37 | "funcs": [], 38 | "vars": [], 39 | "instances": [], 40 | "uses": [] 41 | }], 42 | "funcs": [], 43 | "vars": [] 44 | } 45 | */ 46 | -------------------------------------------------------------------------------- /index_tests/inheritance/class_multiple_inherit.cc: -------------------------------------------------------------------------------- 1 | class Root {}; 2 | class MiddleA : public Root {}; 3 | class MiddleB : public Root {}; 4 | class Derived : public MiddleA, public MiddleB {}; 5 | 6 | /* 7 | OUTPUT: 8 | { 9 | "includes": [], 10 | "skipped_by_preprocessor": [], 11 | "types": [{ 12 | "id": 0, 13 | "usr": 3897841498936210886, 14 | "detailed_name": "Root", 15 | "short_name": "Root", 16 | "kind": 5, 17 | "declarations": ["2:24-2:28|-1|1|4", "3:24-3:28|-1|1|4"], 18 | "spell": "1:7-1:11|-1|1|2", 19 | "extent": "1:1-1:14|-1|1|0", 20 | "bases": [], 21 | "derived": [1, 2], 22 | "types": [], 23 | "funcs": [], 24 | "vars": [], 25 | "instances": [], 26 | "uses": ["2:24-2:28|-1|1|4", "3:24-3:28|-1|1|4"] 27 | }, { 28 | "id": 1, 29 | "usr": 11863524815063131483, 30 | "detailed_name": "MiddleA", 31 | "short_name": "MiddleA", 32 | "kind": 5, 33 | "declarations": ["4:24-4:31|-1|1|4"], 34 | "spell": "2:7-2:14|-1|1|2", 35 | "extent": "2:1-2:31|-1|1|0", 36 | "bases": [0], 37 | "derived": [3], 38 | "types": [], 39 | "funcs": [], 40 | "vars": [], 41 | "instances": [], 42 | "uses": ["4:24-4:31|-1|1|4"] 43 | }, { 44 | "id": 2, 45 | "usr": 14022569716337624303, 46 | "detailed_name": "MiddleB", 47 | "short_name": "MiddleB", 48 | "kind": 5, 49 | "declarations": ["4:40-4:47|-1|1|4"], 50 | "spell": "3:7-3:14|-1|1|2", 51 | "extent": "3:1-3:31|-1|1|0", 52 | "bases": [0], 53 | "derived": [3], 54 | "types": [], 55 | "funcs": [], 56 | "vars": [], 57 | "instances": [], 58 | "uses": ["4:40-4:47|-1|1|4"] 59 | }, { 60 | "id": 3, 61 | "usr": 10963370434658308541, 62 | "detailed_name": "Derived", 63 | "short_name": "Derived", 64 | "kind": 5, 65 | "declarations": [], 66 | "spell": "4:7-4:14|-1|1|2", 67 | "extent": "4:1-4:50|-1|1|0", 68 | "bases": [1, 2], 69 | "derived": [], 70 | "types": [], 71 | "funcs": [], 72 | "vars": [], 73 | "instances": [], 74 | "uses": [] 75 | }], 76 | "funcs": [], 77 | "vars": [] 78 | } 79 | */ 80 | -------------------------------------------------------------------------------- /index_tests/inheritance/function_override.cc: -------------------------------------------------------------------------------- 1 | class Root { 2 | virtual void foo(); 3 | }; 4 | class Derived : public Root { 5 | void foo() override {} 6 | }; 7 | 8 | /* 9 | OUTPUT: 10 | { 11 | "includes": [], 12 | "skipped_by_preprocessor": [], 13 | "types": [{ 14 | "id": 0, 15 | "usr": 3897841498936210886, 16 | "detailed_name": "Root", 17 | "short_name": "Root", 18 | "kind": 5, 19 | "declarations": ["4:24-4:28|-1|1|4"], 20 | "spell": "1:7-1:11|-1|1|2", 21 | "extent": "1:1-3:2|-1|1|0", 22 | "bases": [], 23 | "derived": [1], 24 | "types": [], 25 | "funcs": [0], 26 | "vars": [], 27 | "instances": [], 28 | "uses": ["4:24-4:28|-1|1|4"] 29 | }, { 30 | "id": 1, 31 | "usr": 10963370434658308541, 32 | "detailed_name": "Derived", 33 | "short_name": "Derived", 34 | "kind": 5, 35 | "declarations": [], 36 | "spell": "4:7-4:14|-1|1|2", 37 | "extent": "4:1-6:2|-1|1|0", 38 | "bases": [0], 39 | "derived": [], 40 | "types": [], 41 | "funcs": [1], 42 | "vars": [], 43 | "instances": [], 44 | "uses": [] 45 | }], 46 | "funcs": [{ 47 | "id": 0, 48 | "usr": 9948027785633571339, 49 | "detailed_name": "virtual void Root::foo()", 50 | "short_name": "foo", 51 | "kind": 6, 52 | "storage": 1, 53 | "declarations": [{ 54 | "spell": "2:16-2:19|0|2|1", 55 | "param_spellings": [] 56 | }], 57 | "declaring_type": 0, 58 | "bases": [], 59 | "derived": [1], 60 | "vars": [], 61 | "uses": [], 62 | "callees": [] 63 | }, { 64 | "id": 1, 65 | "usr": 6666242542855173890, 66 | "detailed_name": "void Derived::foo() override", 67 | "short_name": "foo", 68 | "kind": 6, 69 | "storage": 1, 70 | "declarations": [], 71 | "spell": "5:8-5:11|1|2|2", 72 | "extent": "5:3-5:25|1|2|0", 73 | "declaring_type": 1, 74 | "bases": [0], 75 | "derived": [], 76 | "vars": [], 77 | "uses": [], 78 | "callees": [] 79 | }], 80 | "vars": [] 81 | } 82 | */ 83 | -------------------------------------------------------------------------------- /index_tests/inheritance/interface_pure_virtual.cc: -------------------------------------------------------------------------------- 1 | class IFoo { 2 | virtual void foo() = 0; 3 | }; 4 | 5 | /* 6 | OUTPUT: 7 | { 8 | "includes": [], 9 | "skipped_by_preprocessor": [], 10 | "types": [{ 11 | "id": 0, 12 | "usr": 9949214233977131946, 13 | "detailed_name": "IFoo", 14 | "short_name": "IFoo", 15 | "kind": 5, 16 | "declarations": [], 17 | "spell": "1:7-1:11|-1|1|2", 18 | "extent": "1:1-3:2|-1|1|0", 19 | "bases": [], 20 | "derived": [], 21 | "types": [], 22 | "funcs": [0], 23 | "vars": [], 24 | "instances": [], 25 | "uses": [] 26 | }], 27 | "funcs": [{ 28 | "id": 0, 29 | "usr": 3277829753446788562, 30 | "detailed_name": "virtual void IFoo::foo() = 0", 31 | "short_name": "foo", 32 | "kind": 6, 33 | "storage": 1, 34 | "declarations": [{ 35 | "spell": "2:16-2:19|0|2|1", 36 | "param_spellings": [] 37 | }], 38 | "declaring_type": 0, 39 | "bases": [], 40 | "derived": [], 41 | "vars": [], 42 | "uses": [], 43 | "callees": [] 44 | }], 45 | "vars": [] 46 | } 47 | */ 48 | -------------------------------------------------------------------------------- /index_tests/method_declaration.cc: -------------------------------------------------------------------------------- 1 | class Foo { 2 | void foo(); 3 | }; 4 | 5 | /* 6 | // NOTE: Lack of declaring_type in functions and funcs in Foo is okay, because 7 | // those are processed when we find the definition for Foo::foo. Pure 8 | // virtuals are treated specially and get added to the type immediately. 9 | 10 | OUTPUT: 11 | { 12 | "includes": [], 13 | "skipped_by_preprocessor": [], 14 | "types": [{ 15 | "id": 0, 16 | "usr": 15041163540773201510, 17 | "detailed_name": "Foo", 18 | "short_name": "Foo", 19 | "kind": 5, 20 | "declarations": [], 21 | "spell": "1:7-1:10|-1|1|2", 22 | "extent": "1:1-3:2|-1|1|0", 23 | "bases": [], 24 | "derived": [], 25 | "types": [], 26 | "funcs": [0], 27 | "vars": [], 28 | "instances": [], 29 | "uses": [] 30 | }], 31 | "funcs": [{ 32 | "id": 0, 33 | "usr": 17922201480358737771, 34 | "detailed_name": "void Foo::foo()", 35 | "short_name": "foo", 36 | "kind": 6, 37 | "storage": 1, 38 | "declarations": [{ 39 | "spell": "2:8-2:11|0|2|1", 40 | "param_spellings": [] 41 | }], 42 | "declaring_type": 0, 43 | "bases": [], 44 | "derived": [], 45 | "vars": [], 46 | "uses": [], 47 | "callees": [] 48 | }], 49 | "vars": [] 50 | } 51 | */ 52 | -------------------------------------------------------------------------------- /index_tests/method_definition.cc: -------------------------------------------------------------------------------- 1 | class Foo { 2 | void foo() const; 3 | }; 4 | 5 | void Foo::foo() const {} 6 | 7 | /* 8 | OUTPUT: 9 | { 10 | "includes": [], 11 | "skipped_by_preprocessor": [], 12 | "types": [{ 13 | "id": 0, 14 | "usr": 15041163540773201510, 15 | "detailed_name": "Foo", 16 | "short_name": "Foo", 17 | "kind": 5, 18 | "declarations": [], 19 | "spell": "1:7-1:10|-1|1|2", 20 | "extent": "1:1-3:2|-1|1|0", 21 | "bases": [], 22 | "derived": [], 23 | "types": [], 24 | "funcs": [0], 25 | "vars": [], 26 | "instances": [], 27 | "uses": ["5:6-5:9|-1|1|4"] 28 | }], 29 | "funcs": [{ 30 | "id": 0, 31 | "usr": 6446764306530590711, 32 | "detailed_name": "void Foo::foo() const", 33 | "short_name": "foo", 34 | "kind": 6, 35 | "storage": 1, 36 | "declarations": [{ 37 | "spell": "2:8-2:11|0|2|1", 38 | "param_spellings": [] 39 | }], 40 | "spell": "5:11-5:14|0|2|2", 41 | "extent": "5:1-5:25|-1|1|0", 42 | "declaring_type": 0, 43 | "bases": [], 44 | "derived": [], 45 | "vars": [], 46 | "uses": [], 47 | "callees": [] 48 | }], 49 | "vars": [] 50 | } 51 | */ 52 | -------------------------------------------------------------------------------- /index_tests/method_inline_declaration.cc: -------------------------------------------------------------------------------- 1 | class Foo { 2 | void foo() {} 3 | }; 4 | 5 | /* 6 | OUTPUT: 7 | { 8 | "includes": [], 9 | "skipped_by_preprocessor": [], 10 | "types": [{ 11 | "id": 0, 12 | "usr": 15041163540773201510, 13 | "detailed_name": "Foo", 14 | "short_name": "Foo", 15 | "kind": 5, 16 | "declarations": [], 17 | "spell": "1:7-1:10|-1|1|2", 18 | "extent": "1:1-3:2|-1|1|0", 19 | "bases": [], 20 | "derived": [], 21 | "types": [], 22 | "funcs": [0], 23 | "vars": [], 24 | "instances": [], 25 | "uses": [] 26 | }], 27 | "funcs": [{ 28 | "id": 0, 29 | "usr": 17922201480358737771, 30 | "detailed_name": "void Foo::foo()", 31 | "short_name": "foo", 32 | "kind": 6, 33 | "storage": 1, 34 | "declarations": [], 35 | "spell": "2:8-2:11|0|2|2", 36 | "extent": "2:3-2:16|0|2|0", 37 | "declaring_type": 0, 38 | "bases": [], 39 | "derived": [], 40 | "vars": [], 41 | "uses": [], 42 | "callees": [] 43 | }], 44 | "vars": [] 45 | } 46 | */ 47 | -------------------------------------------------------------------------------- /index_tests/multi_file/funky_enum.h: -------------------------------------------------------------------------------- 1 | // This file cannot be built directory. It is included in an enum definition of 2 | // another file. 3 | 4 | A, 5 | B, 6 | C -------------------------------------------------------------------------------- /index_tests/multi_file/header.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct Base {}; 4 | 5 | struct SameFileDerived : Base {}; 6 | 7 | using Foo0 = SameFileDerived; 8 | 9 | template 10 | void Foo1() {} 11 | 12 | template 13 | struct Foo2 {}; 14 | 15 | enum Foo3 { A, B, C }; 16 | 17 | int Foo4; 18 | static int Foo5; -------------------------------------------------------------------------------- /index_tests/multi_file/simple_header.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void header(); -------------------------------------------------------------------------------- /index_tests/multi_file/simple_impl.cc: -------------------------------------------------------------------------------- 1 | #include "simple_header.h" 2 | 3 | void impl() { 4 | header(); 5 | } 6 | 7 | /* 8 | OUTPUT: simple_header.h 9 | { 10 | "includes": [], 11 | "skipped_by_preprocessor": [], 12 | "types": [], 13 | "funcs": [{ 14 | "id": 0, 15 | "usr": 16236105532929924676, 16 | "detailed_name": "void header()", 17 | "short_name": "header", 18 | "kind": 12, 19 | "storage": 1, 20 | "declarations": [{ 21 | "spell": "3:6-3:12|-1|1|1", 22 | "param_spellings": [] 23 | }], 24 | "bases": [], 25 | "derived": [], 26 | "vars": [], 27 | "uses": [], 28 | "callees": [] 29 | }], 30 | "vars": [] 31 | } 32 | OUTPUT: simple_impl.cc 33 | { 34 | "includes": [{ 35 | "line": 0, 36 | "resolved_path": "&simple_header.h" 37 | }], 38 | "skipped_by_preprocessor": [], 39 | "types": [], 40 | "funcs": [{ 41 | "id": 0, 42 | "usr": 3373269392705484958, 43 | "detailed_name": "void impl()", 44 | "short_name": "impl", 45 | "kind": 12, 46 | "storage": 1, 47 | "declarations": [], 48 | "spell": "3:6-3:10|-1|1|2", 49 | "extent": "3:1-5:2|-1|1|0", 50 | "bases": [], 51 | "derived": [], 52 | "vars": [], 53 | "uses": [], 54 | "callees": ["4:3-4:9|1|3|36"] 55 | }, { 56 | "id": 1, 57 | "usr": 16236105532929924676, 58 | "detailed_name": "", 59 | "short_name": "", 60 | "kind": 0, 61 | "storage": 0, 62 | "declarations": [], 63 | "bases": [], 64 | "derived": [], 65 | "vars": [], 66 | "uses": ["4:3-4:9|0|3|36"], 67 | "callees": [] 68 | }], 69 | "vars": [] 70 | } 71 | */ 72 | -------------------------------------------------------------------------------- /index_tests/multi_file/static.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct Buffer { 4 | static void CreateSharedBuffer(); 5 | }; 6 | -------------------------------------------------------------------------------- /index_tests/namespaces/anonymous_function.cc: -------------------------------------------------------------------------------- 1 | namespace { 2 | void foo(); 3 | } 4 | 5 | /* 6 | OUTPUT: 7 | { 8 | "includes": [], 9 | "skipped_by_preprocessor": [], 10 | "types": [{ 11 | "id": 0, 12 | "usr": 7144845543074395457, 13 | "detailed_name": "", 14 | "short_name": "", 15 | "kind": 0, 16 | "declarations": [], 17 | "bases": [], 18 | "derived": [], 19 | "types": [], 20 | "funcs": [0], 21 | "vars": [], 22 | "instances": [], 23 | "uses": [] 24 | }], 25 | "funcs": [{ 26 | "id": 0, 27 | "usr": 5010253035933134245, 28 | "detailed_name": "void (anonymous namespace)::foo()", 29 | "short_name": "foo", 30 | "kind": 12, 31 | "storage": 1, 32 | "declarations": [{ 33 | "spell": "2:6-2:9|0|2|1", 34 | "param_spellings": [] 35 | }], 36 | "declaring_type": 0, 37 | "bases": [], 38 | "derived": [], 39 | "vars": [], 40 | "uses": [], 41 | "callees": [] 42 | }], 43 | "vars": [] 44 | } 45 | */ 46 | -------------------------------------------------------------------------------- /index_tests/namespaces/function_declaration.cc: -------------------------------------------------------------------------------- 1 | namespace hello { 2 | void foo(int a, int b); 3 | } 4 | 5 | /* 6 | OUTPUT: 7 | { 8 | "includes": [], 9 | "skipped_by_preprocessor": [], 10 | "types": [{ 11 | "id": 0, 12 | "usr": 2029211996748007610, 13 | "detailed_name": "hello", 14 | "short_name": "hello", 15 | "kind": 3, 16 | "declarations": [], 17 | "spell": "1:11-1:16|-1|1|2", 18 | "extent": "1:1-3:2|-1|1|0", 19 | "bases": [1], 20 | "derived": [], 21 | "types": [], 22 | "funcs": [0], 23 | "vars": [], 24 | "instances": [], 25 | "uses": ["1:11-1:16|-1|1|4"] 26 | }, { 27 | "id": 1, 28 | "usr": 13838176792705659279, 29 | "detailed_name": "", 30 | "short_name": "", 31 | "kind": 0, 32 | "declarations": [], 33 | "bases": [], 34 | "derived": [0], 35 | "types": [], 36 | "funcs": [], 37 | "vars": [], 38 | "instances": [], 39 | "uses": [] 40 | }], 41 | "funcs": [{ 42 | "id": 0, 43 | "usr": 18343102288837190527, 44 | "detailed_name": "void hello::foo(int a, int b)", 45 | "short_name": "foo", 46 | "kind": 12, 47 | "storage": 1, 48 | "declarations": [{ 49 | "spell": "2:6-2:9|0|2|1", 50 | "param_spellings": ["2:14-2:15", "2:21-2:22"] 51 | }], 52 | "declaring_type": 0, 53 | "bases": [], 54 | "derived": [], 55 | "vars": [], 56 | "uses": [], 57 | "callees": [] 58 | }], 59 | "vars": [] 60 | } 61 | */ 62 | -------------------------------------------------------------------------------- /index_tests/namespaces/function_definition.cc: -------------------------------------------------------------------------------- 1 | namespace hello { 2 | void foo() {} 3 | } 4 | 5 | /* 6 | OUTPUT: 7 | { 8 | "includes": [], 9 | "skipped_by_preprocessor": [], 10 | "types": [{ 11 | "id": 0, 12 | "usr": 2029211996748007610, 13 | "detailed_name": "hello", 14 | "short_name": "hello", 15 | "kind": 3, 16 | "declarations": [], 17 | "spell": "1:11-1:16|-1|1|2", 18 | "extent": "1:1-3:2|-1|1|0", 19 | "bases": [1], 20 | "derived": [], 21 | "types": [], 22 | "funcs": [0], 23 | "vars": [], 24 | "instances": [], 25 | "uses": ["1:11-1:16|-1|1|4"] 26 | }, { 27 | "id": 1, 28 | "usr": 13838176792705659279, 29 | "detailed_name": "", 30 | "short_name": "", 31 | "kind": 0, 32 | "declarations": [], 33 | "bases": [], 34 | "derived": [0], 35 | "types": [], 36 | "funcs": [], 37 | "vars": [], 38 | "instances": [], 39 | "uses": [] 40 | }], 41 | "funcs": [{ 42 | "id": 0, 43 | "usr": 243328841292951622, 44 | "detailed_name": "void hello::foo()", 45 | "short_name": "foo", 46 | "kind": 12, 47 | "storage": 1, 48 | "declarations": [], 49 | "spell": "2:6-2:9|0|2|2", 50 | "extent": "2:1-2:14|0|2|0", 51 | "declaring_type": 0, 52 | "bases": [], 53 | "derived": [], 54 | "vars": [], 55 | "uses": [], 56 | "callees": [] 57 | }], 58 | "vars": [] 59 | } 60 | */ 61 | -------------------------------------------------------------------------------- /index_tests/namespaces/method_declaration.cc: -------------------------------------------------------------------------------- 1 | namespace hello { 2 | class Foo { 3 | void foo(); 4 | }; 5 | } 6 | 7 | /* 8 | OUTPUT: 9 | { 10 | "includes": [], 11 | "skipped_by_preprocessor": [], 12 | "types": [{ 13 | "id": 0, 14 | "usr": 2029211996748007610, 15 | "detailed_name": "hello", 16 | "short_name": "hello", 17 | "kind": 3, 18 | "declarations": [], 19 | "spell": "1:11-1:16|-1|1|2", 20 | "extent": "1:1-5:2|-1|1|0", 21 | "bases": [1], 22 | "derived": [], 23 | "types": [], 24 | "funcs": [], 25 | "vars": [], 26 | "instances": [], 27 | "uses": ["1:11-1:16|-1|1|4"] 28 | }, { 29 | "id": 1, 30 | "usr": 13838176792705659279, 31 | "detailed_name": "", 32 | "short_name": "", 33 | "kind": 0, 34 | "declarations": [], 35 | "bases": [], 36 | "derived": [0], 37 | "types": [], 38 | "funcs": [], 39 | "vars": [], 40 | "instances": [], 41 | "uses": [] 42 | }, { 43 | "id": 2, 44 | "usr": 4508214972876735896, 45 | "detailed_name": "hello::Foo", 46 | "short_name": "Foo", 47 | "kind": 5, 48 | "declarations": [], 49 | "spell": "2:7-2:10|0|2|2", 50 | "extent": "2:1-4:2|0|2|0", 51 | "bases": [], 52 | "derived": [], 53 | "types": [], 54 | "funcs": [0], 55 | "vars": [], 56 | "instances": [], 57 | "uses": [] 58 | }], 59 | "funcs": [{ 60 | "id": 0, 61 | "usr": 10487325150128053272, 62 | "detailed_name": "void hello::Foo::foo()", 63 | "short_name": "foo", 64 | "kind": 6, 65 | "storage": 1, 66 | "declarations": [{ 67 | "spell": "3:8-3:11|2|2|1", 68 | "param_spellings": [] 69 | }], 70 | "declaring_type": 2, 71 | "bases": [], 72 | "derived": [], 73 | "vars": [], 74 | "uses": [], 75 | "callees": [] 76 | }], 77 | "vars": [] 78 | } 79 | */ 80 | -------------------------------------------------------------------------------- /index_tests/namespaces/method_definition.cc: -------------------------------------------------------------------------------- 1 | namespace hello { 2 | class Foo { 3 | void foo(); 4 | }; 5 | 6 | void Foo::foo() {} 7 | } 8 | 9 | /* 10 | OUTPUT: 11 | { 12 | "includes": [], 13 | "skipped_by_preprocessor": [], 14 | "types": [{ 15 | "id": 0, 16 | "usr": 2029211996748007610, 17 | "detailed_name": "hello", 18 | "short_name": "hello", 19 | "kind": 3, 20 | "declarations": [], 21 | "spell": "1:11-1:16|-1|1|2", 22 | "extent": "1:1-7:2|-1|1|0", 23 | "bases": [1], 24 | "derived": [], 25 | "types": [], 26 | "funcs": [], 27 | "vars": [], 28 | "instances": [], 29 | "uses": ["1:11-1:16|-1|1|4"] 30 | }, { 31 | "id": 1, 32 | "usr": 13838176792705659279, 33 | "detailed_name": "", 34 | "short_name": "", 35 | "kind": 0, 36 | "declarations": [], 37 | "bases": [], 38 | "derived": [0], 39 | "types": [], 40 | "funcs": [], 41 | "vars": [], 42 | "instances": [], 43 | "uses": [] 44 | }, { 45 | "id": 2, 46 | "usr": 4508214972876735896, 47 | "detailed_name": "hello::Foo", 48 | "short_name": "Foo", 49 | "kind": 5, 50 | "declarations": [], 51 | "spell": "2:7-2:10|0|2|2", 52 | "extent": "2:1-4:2|0|2|0", 53 | "bases": [], 54 | "derived": [], 55 | "types": [], 56 | "funcs": [0], 57 | "vars": [], 58 | "instances": [], 59 | "uses": ["6:6-6:9|-1|1|4"] 60 | }], 61 | "funcs": [{ 62 | "id": 0, 63 | "usr": 10487325150128053272, 64 | "detailed_name": "void hello::Foo::foo()", 65 | "short_name": "foo", 66 | "kind": 6, 67 | "storage": 1, 68 | "declarations": [{ 69 | "spell": "3:8-3:11|2|2|1", 70 | "param_spellings": [] 71 | }], 72 | "spell": "6:11-6:14|2|2|2", 73 | "extent": "6:1-6:19|0|2|0", 74 | "declaring_type": 2, 75 | "bases": [], 76 | "derived": [], 77 | "vars": [], 78 | "uses": [], 79 | "callees": [] 80 | }], 81 | "vars": [] 82 | } 83 | */ 84 | -------------------------------------------------------------------------------- /index_tests/namespaces/method_inline_declaration.cc: -------------------------------------------------------------------------------- 1 | namespace hello { 2 | class Foo { 3 | void foo() {} 4 | }; 5 | } 6 | 7 | /* 8 | OUTPUT: 9 | { 10 | "includes": [], 11 | "skipped_by_preprocessor": [], 12 | "types": [{ 13 | "id": 0, 14 | "usr": 2029211996748007610, 15 | "detailed_name": "hello", 16 | "short_name": "hello", 17 | "kind": 3, 18 | "declarations": [], 19 | "spell": "1:11-1:16|-1|1|2", 20 | "extent": "1:1-5:2|-1|1|0", 21 | "bases": [1], 22 | "derived": [], 23 | "types": [], 24 | "funcs": [], 25 | "vars": [], 26 | "instances": [], 27 | "uses": ["1:11-1:16|-1|1|4"] 28 | }, { 29 | "id": 1, 30 | "usr": 13838176792705659279, 31 | "detailed_name": "", 32 | "short_name": "", 33 | "kind": 0, 34 | "declarations": [], 35 | "bases": [], 36 | "derived": [0], 37 | "types": [], 38 | "funcs": [], 39 | "vars": [], 40 | "instances": [], 41 | "uses": [] 42 | }, { 43 | "id": 2, 44 | "usr": 4508214972876735896, 45 | "detailed_name": "hello::Foo", 46 | "short_name": "Foo", 47 | "kind": 5, 48 | "declarations": [], 49 | "spell": "2:7-2:10|0|2|2", 50 | "extent": "2:1-4:2|0|2|0", 51 | "bases": [], 52 | "derived": [], 53 | "types": [], 54 | "funcs": [0], 55 | "vars": [], 56 | "instances": [], 57 | "uses": [] 58 | }], 59 | "funcs": [{ 60 | "id": 0, 61 | "usr": 10487325150128053272, 62 | "detailed_name": "void hello::Foo::foo()", 63 | "short_name": "foo", 64 | "kind": 6, 65 | "storage": 1, 66 | "declarations": [], 67 | "spell": "3:8-3:11|2|2|2", 68 | "extent": "3:3-3:16|2|2|0", 69 | "declaring_type": 2, 70 | "bases": [], 71 | "derived": [], 72 | "vars": [], 73 | "uses": [], 74 | "callees": [] 75 | }], 76 | "vars": [] 77 | } 78 | */ 79 | -------------------------------------------------------------------------------- /index_tests/outline/static_function_in_type.h: -------------------------------------------------------------------------------- 1 | namespace ns { 2 | 3 | class Manager; 4 | 5 | struct Foo { 6 | static void Register(Manager*); 7 | }; 8 | 9 | } // namespace ns -------------------------------------------------------------------------------- /index_tests/preprocessor/include_guard.cc: -------------------------------------------------------------------------------- 1 | #ifndef FOO 2 | #define FOO 3 | 4 | #endif 5 | 6 | /* 7 | OUTPUT: 8 | { 9 | "includes": [], 10 | "skipped_by_preprocessor": [], 11 | "types": [], 12 | "funcs": [], 13 | "vars": [{ 14 | "id": 0, 15 | "usr": 13076155634261037336, 16 | "detailed_name": "FOO", 17 | "short_name": "FOO", 18 | "hover": "#define FOO", 19 | "declarations": [], 20 | "spell": "2:9-2:12|-1|1|2", 21 | "extent": "2:9-2:12|-1|1|0", 22 | "uses": [], 23 | "kind": 255, 24 | "storage": 0 25 | }] 26 | } 27 | */ 28 | -------------------------------------------------------------------------------- /index_tests/preprocessor/skipped.cc: -------------------------------------------------------------------------------- 1 | 2 | #ifdef FOOBAR 3 | void hello(); 4 | #endif 5 | 6 | #if false 7 | 8 | 9 | 10 | #endif 11 | 12 | #if defined(OS_FOO) 13 | 14 | #endif 15 | 16 | /* 17 | OUTPUT: 18 | { 19 | "includes": [], 20 | "skipped_by_preprocessor": ["2:1-4:7", "6:1-10:7", "12:1-14:7"], 21 | "types": [], 22 | "funcs": [], 23 | "vars": [] 24 | } 25 | */ 26 | -------------------------------------------------------------------------------- /index_tests/templates/func_specialized_template_param.cc: -------------------------------------------------------------------------------- 1 | template 2 | class Template {}; 3 | 4 | struct Foo { 5 | void Bar(Template&); 6 | }; 7 | 8 | void Foo::Bar(Template&) {} 9 | 10 | /* 11 | OUTPUT: 12 | { 13 | "includes": [], 14 | "skipped_by_preprocessor": [], 15 | "types": [{ 16 | "id": 0, 17 | "usr": 17107291254533526269, 18 | "detailed_name": "Template", 19 | "short_name": "Template", 20 | "kind": 5, 21 | "declarations": [], 22 | "spell": "2:7-2:15|-1|1|2", 23 | "extent": "2:1-2:18|-1|1|0", 24 | "bases": [], 25 | "derived": [], 26 | "types": [], 27 | "funcs": [], 28 | "vars": [], 29 | "instances": [], 30 | "uses": ["5:12-5:20|-1|1|4", "8:15-8:23|-1|1|4"] 31 | }, { 32 | "id": 1, 33 | "usr": 15041163540773201510, 34 | "detailed_name": "Foo", 35 | "short_name": "Foo", 36 | "kind": 23, 37 | "declarations": [], 38 | "spell": "4:8-4:11|-1|1|2", 39 | "extent": "4:1-6:2|-1|1|0", 40 | "bases": [], 41 | "derived": [], 42 | "types": [], 43 | "funcs": [0], 44 | "vars": [], 45 | "instances": [], 46 | "uses": ["8:6-8:9|-1|1|4"] 47 | }], 48 | "funcs": [{ 49 | "id": 0, 50 | "usr": 8412238651648388423, 51 | "detailed_name": "void Foo::Bar(Template &)", 52 | "short_name": "Bar", 53 | "kind": 6, 54 | "storage": 1, 55 | "declarations": [{ 56 | "spell": "5:8-5:11|1|2|1", 57 | "param_spellings": ["5:29-5:29"] 58 | }], 59 | "spell": "8:11-8:14|1|2|2", 60 | "extent": "8:1-8:36|-1|1|0", 61 | "declaring_type": 1, 62 | "bases": [], 63 | "derived": [], 64 | "vars": [], 65 | "uses": [], 66 | "callees": [] 67 | }], 68 | "vars": [] 69 | } 70 | */ 71 | -------------------------------------------------------------------------------- /index_tests/templates/specialized_func_definition.cc: -------------------------------------------------------------------------------- 1 | template 2 | class Template { 3 | void Foo(); 4 | }; 5 | 6 | template 7 | void Template::Foo() {} 8 | 9 | template<> 10 | void Template::Foo() {} 11 | 12 | 13 | /* 14 | // TODO: usage information on Template is bad. 15 | // TODO: Foo() should have multiple definitions. 16 | 17 | EXTRA_FLAGS: 18 | -fms-compatibility 19 | -fdelayed-template-parsing 20 | 21 | OUTPUT: 22 | { 23 | "includes": [], 24 | "skipped_by_preprocessor": [], 25 | "types": [{ 26 | "id": 0, 27 | "usr": 17107291254533526269, 28 | "detailed_name": "Template", 29 | "short_name": "Template", 30 | "kind": 5, 31 | "declarations": [], 32 | "spell": "2:7-2:15|-1|1|2", 33 | "extent": "2:1-4:2|-1|1|0", 34 | "bases": [], 35 | "derived": [], 36 | "types": [], 37 | "funcs": [0], 38 | "vars": [], 39 | "instances": [], 40 | "uses": ["7:6-7:14|-1|1|4", "10:6-10:14|-1|1|4"] 41 | }, { 42 | "id": 1, 43 | "usr": 17649312483543982122, 44 | "detailed_name": "", 45 | "short_name": "", 46 | "kind": 0, 47 | "declarations": [], 48 | "bases": [], 49 | "derived": [], 50 | "types": [], 51 | "funcs": [], 52 | "vars": [], 53 | "instances": [], 54 | "uses": [] 55 | }], 56 | "funcs": [{ 57 | "id": 0, 58 | "usr": 11994188353303124840, 59 | "detailed_name": "template void Template::Foo()", 60 | "short_name": "Foo", 61 | "kind": 6, 62 | "storage": 1, 63 | "declarations": [{ 64 | "spell": "3:8-3:11|0|2|1", 65 | "param_spellings": [] 66 | }, { 67 | "spell": "10:22-10:25|-1|1|1", 68 | "param_spellings": [] 69 | }], 70 | "spell": "7:19-7:22|0|2|2", 71 | "extent": "6:1-7:24|-1|1|0", 72 | "declaring_type": 0, 73 | "bases": [], 74 | "derived": [], 75 | "vars": [], 76 | "uses": [], 77 | "callees": [] 78 | }], 79 | "vars": [] 80 | } 81 | */ 82 | -------------------------------------------------------------------------------- /index_tests/templates/template_func_usage_folded_into_one.cc: -------------------------------------------------------------------------------- 1 | template 2 | static int foo() { 3 | return 3; 4 | } 5 | 6 | int a = foo(); 7 | int b = foo(); 8 | 9 | // TODO: put template foo inside a namespace 10 | // TODO: put template foo inside a template class inside a namespace 11 | 12 | /* 13 | OUTPUT: 14 | { 15 | "includes": [], 16 | "skipped_by_preprocessor": [], 17 | "types": [{ 18 | "id": 0, 19 | "usr": 17, 20 | "detailed_name": "", 21 | "short_name": "", 22 | "kind": 0, 23 | "declarations": [], 24 | "bases": [], 25 | "derived": [], 26 | "types": [], 27 | "funcs": [], 28 | "vars": [], 29 | "instances": [0, 1], 30 | "uses": [] 31 | }], 32 | "funcs": [{ 33 | "id": 0, 34 | "usr": 326583651986177228, 35 | "detailed_name": "static int foo()", 36 | "short_name": "foo", 37 | "kind": 12, 38 | "storage": 3, 39 | "declarations": [], 40 | "spell": "2:12-2:15|-1|1|2", 41 | "extent": "2:1-4:2|-1|1|0", 42 | "bases": [], 43 | "derived": [], 44 | "vars": [], 45 | "uses": ["6:9-6:12|-1|1|36", "7:9-7:12|-1|1|36"], 46 | "callees": [] 47 | }], 48 | "vars": [{ 49 | "id": 0, 50 | "usr": 16721564935990383768, 51 | "detailed_name": "int a", 52 | "short_name": "a", 53 | "hover": "int a = foo()", 54 | "declarations": [], 55 | "spell": "6:5-6:6|-1|1|2", 56 | "extent": "6:1-6:19|-1|1|0", 57 | "type": 0, 58 | "uses": [], 59 | "kind": 13, 60 | "storage": 1 61 | }, { 62 | "id": 1, 63 | "usr": 12028309045033782423, 64 | "detailed_name": "int b", 65 | "short_name": "b", 66 | "hover": "int b = foo()", 67 | "declarations": [], 68 | "spell": "7:5-7:6|-1|1|2", 69 | "extent": "7:1-7:20|-1|1|0", 70 | "type": 0, 71 | "uses": [], 72 | "kind": 13, 73 | "storage": 1 74 | }] 75 | } 76 | */ 77 | -------------------------------------------------------------------------------- /index_tests/templates/template_type_usage_folded_into_one.cc: -------------------------------------------------------------------------------- 1 | template 2 | class Foo {}; 3 | 4 | Foo a; 5 | Foo b; 6 | 7 | /* 8 | OUTPUT: 9 | { 10 | "includes": [], 11 | "skipped_by_preprocessor": [], 12 | "types": [{ 13 | "id": 0, 14 | "usr": 10528472276654770367, 15 | "detailed_name": "Foo", 16 | "short_name": "Foo", 17 | "kind": 5, 18 | "declarations": [], 19 | "spell": "2:7-2:10|-1|1|2", 20 | "extent": "2:1-2:13|-1|1|0", 21 | "bases": [], 22 | "derived": [], 23 | "types": [], 24 | "funcs": [], 25 | "vars": [], 26 | "instances": [0, 1], 27 | "uses": ["4:1-4:4|-1|1|4", "5:1-5:4|-1|1|4"] 28 | }], 29 | "funcs": [], 30 | "vars": [{ 31 | "id": 0, 32 | "usr": 16721564935990383768, 33 | "detailed_name": "Foo a", 34 | "short_name": "a", 35 | "declarations": [], 36 | "spell": "4:10-4:11|-1|1|2", 37 | "extent": "4:1-4:11|-1|1|0", 38 | "type": 0, 39 | "uses": [], 40 | "kind": 13, 41 | "storage": 1 42 | }, { 43 | "id": 1, 44 | "usr": 12028309045033782423, 45 | "detailed_name": "Foo b", 46 | "short_name": "b", 47 | "declarations": [], 48 | "spell": "5:11-5:12|-1|1|2", 49 | "extent": "5:1-5:12|-1|1|0", 50 | "type": 0, 51 | "uses": [], 52 | "kind": 13, 53 | "storage": 1 54 | }] 55 | } 56 | */ 57 | -------------------------------------------------------------------------------- /index_tests/types/typedefs.cc: -------------------------------------------------------------------------------- 1 | typedef int (func)(const int *a, const int *b); 2 | static func g; 3 | 4 | /* 5 | OUTPUT: 6 | { 7 | "includes": [], 8 | "skipped_by_preprocessor": [], 9 | "types": [{ 10 | "id": 0, 11 | "usr": 13838176792705659279, 12 | "detailed_name": "", 13 | "short_name": "", 14 | "kind": 0, 15 | "declarations": [], 16 | "bases": [], 17 | "derived": [], 18 | "types": [], 19 | "funcs": [], 20 | "vars": [], 21 | "instances": [], 22 | "uses": [] 23 | }, { 24 | "id": 1, 25 | "usr": 10383876566159302459, 26 | "detailed_name": "func", 27 | "short_name": "func", 28 | "kind": 252, 29 | "hover": "typedef int (func)(const int *a, const int *b)", 30 | "declarations": [], 31 | "spell": "1:14-1:18|-1|1|2", 32 | "extent": "1:1-1:47|-1|1|0", 33 | "alias_of": 0, 34 | "bases": [], 35 | "derived": [], 36 | "types": [], 37 | "funcs": [], 38 | "vars": [], 39 | "instances": [], 40 | "uses": ["1:14-1:18|-1|1|4", "2:8-2:12|-1|1|4"] 41 | }], 42 | "funcs": [{ 43 | "id": 0, 44 | "usr": 8105378401105136463, 45 | "detailed_name": "static int g(const int *, const int *)", 46 | "short_name": "g", 47 | "kind": 12, 48 | "storage": 3, 49 | "declarations": [{ 50 | "spell": "2:13-2:14|-1|1|1", 51 | "param_spellings": ["2:13-2:13", "2:13-2:13"] 52 | }], 53 | "bases": [], 54 | "derived": [], 55 | "vars": [], 56 | "uses": [], 57 | "callees": [] 58 | }], 59 | "vars": [] 60 | } 61 | */ -------------------------------------------------------------------------------- /index_tests/unions/union_decl.cc: -------------------------------------------------------------------------------- 1 | union Foo { 2 | int a; 3 | bool b; 4 | }; 5 | 6 | /* 7 | OUTPUT: 8 | { 9 | "includes": [], 10 | "skipped_by_preprocessor": [], 11 | "types": [{ 12 | "id": 0, 13 | "usr": 8501689086387244262, 14 | "detailed_name": "Foo", 15 | "short_name": "Foo", 16 | "kind": 23, 17 | "declarations": [], 18 | "spell": "1:7-1:10|-1|1|2", 19 | "extent": "1:1-4:2|-1|1|0", 20 | "bases": [], 21 | "derived": [], 22 | "types": [], 23 | "funcs": [], 24 | "vars": [0, 1], 25 | "instances": [], 26 | "uses": [] 27 | }, { 28 | "id": 1, 29 | "usr": 17, 30 | "detailed_name": "", 31 | "short_name": "", 32 | "kind": 0, 33 | "declarations": [], 34 | "bases": [], 35 | "derived": [], 36 | "types": [], 37 | "funcs": [], 38 | "vars": [], 39 | "instances": [0], 40 | "uses": [] 41 | }, { 42 | "id": 2, 43 | "usr": 3, 44 | "detailed_name": "", 45 | "short_name": "", 46 | "kind": 0, 47 | "declarations": [], 48 | "bases": [], 49 | "derived": [], 50 | "types": [], 51 | "funcs": [], 52 | "vars": [], 53 | "instances": [1], 54 | "uses": [] 55 | }], 56 | "funcs": [], 57 | "vars": [{ 58 | "id": 0, 59 | "usr": 9529311430721959843, 60 | "detailed_name": "int Foo::a", 61 | "short_name": "a", 62 | "declarations": [], 63 | "spell": "2:7-2:8|0|2|2", 64 | "extent": "2:3-2:8|0|2|0", 65 | "type": 1, 66 | "uses": [], 67 | "kind": 8, 68 | "storage": 0 69 | }, { 70 | "id": 1, 71 | "usr": 8804696910588009104, 72 | "detailed_name": "bool Foo::b", 73 | "short_name": "b", 74 | "declarations": [], 75 | "spell": "3:8-3:9|0|2|2", 76 | "extent": "3:3-3:9|0|2|0", 77 | "type": 2, 78 | "uses": [], 79 | "kind": 8, 80 | "storage": 0 81 | }] 82 | } 83 | */ 84 | -------------------------------------------------------------------------------- /index_tests/usage/func_called_from_constructor.cc: -------------------------------------------------------------------------------- 1 | void called() {} 2 | 3 | struct Foo { 4 | Foo(); 5 | }; 6 | 7 | Foo::Foo() { 8 | called(); 9 | } 10 | 11 | /* 12 | OUTPUT: 13 | { 14 | "includes": [], 15 | "skipped_by_preprocessor": [], 16 | "types": [{ 17 | "id": 0, 18 | "usr": 15041163540773201510, 19 | "detailed_name": "Foo", 20 | "short_name": "Foo", 21 | "kind": 23, 22 | "declarations": ["4:3-4:6|-1|1|4", "7:6-7:9|-1|1|4"], 23 | "spell": "3:8-3:11|-1|1|2", 24 | "extent": "3:1-5:2|-1|1|0", 25 | "bases": [], 26 | "derived": [], 27 | "types": [], 28 | "funcs": [1], 29 | "vars": [], 30 | "instances": [], 31 | "uses": ["4:3-4:6|0|2|4", "7:6-7:9|-1|1|4", "7:1-7:4|-1|1|4"] 32 | }], 33 | "funcs": [{ 34 | "id": 0, 35 | "usr": 468307235068920063, 36 | "detailed_name": "void called()", 37 | "short_name": "called", 38 | "kind": 12, 39 | "storage": 1, 40 | "declarations": [], 41 | "spell": "1:6-1:12|-1|1|2", 42 | "extent": "1:1-1:17|-1|1|0", 43 | "bases": [], 44 | "derived": [], 45 | "vars": [], 46 | "uses": ["8:3-8:9|1|3|36"], 47 | "callees": [] 48 | }, { 49 | "id": 1, 50 | "usr": 3385168158331140247, 51 | "detailed_name": "Foo::Foo()", 52 | "short_name": "Foo", 53 | "kind": 9, 54 | "storage": 1, 55 | "declarations": [{ 56 | "spell": "4:3-4:6|0|2|1", 57 | "param_spellings": [] 58 | }], 59 | "spell": "7:6-7:9|0|2|2", 60 | "extent": "7:1-9:2|-1|1|0", 61 | "declaring_type": 0, 62 | "bases": [], 63 | "derived": [], 64 | "vars": [], 65 | "uses": [], 66 | "callees": ["8:3-8:9|0|3|36"] 67 | }], 68 | "vars": [] 69 | } 70 | */ 71 | -------------------------------------------------------------------------------- /index_tests/usage/func_called_from_macro_argument.cc: -------------------------------------------------------------------------------- 1 | #define MACRO_CALL(e) e 2 | 3 | bool called(bool a, bool b); 4 | 5 | void caller() { 6 | MACRO_CALL(called(true, true)); 7 | } 8 | 9 | /* 10 | OUTPUT: 11 | { 12 | "includes": [], 13 | "skipped_by_preprocessor": [], 14 | "types": [], 15 | "funcs": [{ 16 | "id": 0, 17 | "usr": 3787803219955606747, 18 | "detailed_name": "bool called(bool a, bool b)", 19 | "short_name": "called", 20 | "kind": 12, 21 | "storage": 1, 22 | "declarations": [{ 23 | "spell": "3:6-3:12|-1|1|1", 24 | "param_spellings": ["3:18-3:19", "3:26-3:27"] 25 | }], 26 | "bases": [], 27 | "derived": [], 28 | "vars": [], 29 | "uses": ["6:14-6:20|1|3|36"], 30 | "callees": [] 31 | }, { 32 | "id": 1, 33 | "usr": 11404881820527069090, 34 | "detailed_name": "void caller()", 35 | "short_name": "caller", 36 | "kind": 12, 37 | "storage": 1, 38 | "declarations": [], 39 | "spell": "5:6-5:12|-1|1|2", 40 | "extent": "5:1-7:2|-1|1|0", 41 | "bases": [], 42 | "derived": [], 43 | "vars": [], 44 | "uses": [], 45 | "callees": ["6:14-6:20|0|3|36"] 46 | }], 47 | "vars": [{ 48 | "id": 0, 49 | "usr": 1290746656694198202, 50 | "detailed_name": "MACRO_CALL", 51 | "short_name": "MACRO_CALL", 52 | "hover": "#define MACRO_CALL(e) e", 53 | "declarations": [], 54 | "spell": "1:9-1:19|-1|1|2", 55 | "extent": "1:9-1:24|-1|1|0", 56 | "uses": ["6:3-6:13|-1|1|4"], 57 | "kind": 255, 58 | "storage": 0 59 | }] 60 | } 61 | */ -------------------------------------------------------------------------------- /index_tests/usage/func_called_from_template.cc: -------------------------------------------------------------------------------- 1 | void called(); 2 | 3 | template 4 | void caller() { 5 | called(); 6 | } 7 | 8 | void foo() { 9 | caller(); 10 | } 11 | 12 | /* 13 | // NOTE: without caller() instantation caller() is never visited so 14 | // called() is never referenced. 15 | OUTPUT: 16 | { 17 | "includes": [], 18 | "skipped_by_preprocessor": [], 19 | "types": [], 20 | "funcs": [{ 21 | "id": 0, 22 | "usr": 468307235068920063, 23 | "detailed_name": "void called()", 24 | "short_name": "called", 25 | "kind": 12, 26 | "storage": 1, 27 | "declarations": [{ 28 | "spell": "1:6-1:12|-1|1|1", 29 | "param_spellings": [] 30 | }], 31 | "bases": [], 32 | "derived": [], 33 | "vars": [], 34 | "uses": ["5:3-5:9|1|3|32"], 35 | "callees": [] 36 | }, { 37 | "id": 1, 38 | "usr": 10177235824697315808, 39 | "detailed_name": "void caller()", 40 | "short_name": "caller", 41 | "kind": 12, 42 | "storage": 1, 43 | "declarations": [], 44 | "spell": "4:6-4:12|-1|1|2", 45 | "extent": "4:1-6:2|-1|1|0", 46 | "bases": [], 47 | "derived": [], 48 | "vars": [], 49 | "uses": ["9:3-9:9|2|3|32"], 50 | "callees": ["5:3-5:9|0|3|32"] 51 | }, { 52 | "id": 2, 53 | "usr": 4259594751088586730, 54 | "detailed_name": "void foo()", 55 | "short_name": "foo", 56 | "kind": 12, 57 | "storage": 1, 58 | "declarations": [], 59 | "spell": "8:6-8:9|-1|1|2", 60 | "extent": "8:1-10:2|-1|1|0", 61 | "bases": [], 62 | "derived": [], 63 | "vars": [], 64 | "uses": [], 65 | "callees": ["9:3-9:9|1|3|32"] 66 | }], 67 | "vars": [] 68 | } 69 | */ -------------------------------------------------------------------------------- /index_tests/usage/func_called_implicit_ctor.cc: -------------------------------------------------------------------------------- 1 | struct Wrapper { 2 | Wrapper(int i); 3 | }; 4 | 5 | int called() { return 1; } 6 | 7 | Wrapper caller() { 8 | return called(); 9 | } 10 | 11 | /* 12 | OUTPUT: 13 | { 14 | "includes": [], 15 | "skipped_by_preprocessor": [], 16 | "types": [{ 17 | "id": 0, 18 | "usr": 13611487872560323389, 19 | "detailed_name": "Wrapper", 20 | "short_name": "Wrapper", 21 | "kind": 23, 22 | "declarations": ["2:3-2:10|-1|1|4"], 23 | "spell": "1:8-1:15|-1|1|2", 24 | "extent": "1:1-3:2|-1|1|0", 25 | "bases": [], 26 | "derived": [], 27 | "types": [], 28 | "funcs": [0], 29 | "vars": [], 30 | "instances": [], 31 | "uses": ["2:3-2:10|0|2|4", "7:1-7:8|-1|1|4"] 32 | }], 33 | "funcs": [{ 34 | "id": 0, 35 | "usr": 10544127002917214589, 36 | "detailed_name": "Wrapper::Wrapper(int i)", 37 | "short_name": "Wrapper", 38 | "kind": 9, 39 | "storage": 1, 40 | "declarations": [{ 41 | "spell": "2:3-2:10|0|2|1", 42 | "param_spellings": ["2:15-2:16"] 43 | }], 44 | "declaring_type": 0, 45 | "bases": [], 46 | "derived": [], 47 | "vars": [], 48 | "uses": ["8:10-8:18|2|3|292"], 49 | "callees": [] 50 | }, { 51 | "id": 1, 52 | "usr": 468307235068920063, 53 | "detailed_name": "int called()", 54 | "short_name": "called", 55 | "kind": 12, 56 | "storage": 1, 57 | "declarations": [], 58 | "spell": "5:5-5:11|-1|1|2", 59 | "extent": "5:1-5:27|-1|1|0", 60 | "bases": [], 61 | "derived": [], 62 | "vars": [], 63 | "uses": ["8:10-8:16|2|3|36"], 64 | "callees": [] 65 | }, { 66 | "id": 2, 67 | "usr": 11404881820527069090, 68 | "detailed_name": "Wrapper caller()", 69 | "short_name": "caller", 70 | "kind": 12, 71 | "storage": 1, 72 | "declarations": [], 73 | "spell": "7:9-7:15|-1|1|2", 74 | "extent": "7:1-9:2|-1|1|0", 75 | "bases": [], 76 | "derived": [], 77 | "vars": [], 78 | "uses": [], 79 | "callees": ["8:10-8:18|0|3|292", "8:10-8:16|1|3|36"] 80 | }], 81 | "vars": [] 82 | } 83 | */ 84 | -------------------------------------------------------------------------------- /index_tests/usage/func_usage_addr_func.cc: -------------------------------------------------------------------------------- 1 | void consume(void (*)()) {} 2 | 3 | void used() {} 4 | 5 | void user() { 6 | void (*x)() = &used; 7 | consume(&used); 8 | } 9 | 10 | /* 11 | OUTPUT: 12 | { 13 | "includes": [], 14 | "skipped_by_preprocessor": [], 15 | "types": [], 16 | "funcs": [{ 17 | "id": 0, 18 | "usr": 12924914488846929470, 19 | "detailed_name": "void consume(void (*)())", 20 | "short_name": "consume", 21 | "kind": 12, 22 | "storage": 1, 23 | "declarations": [], 24 | "spell": "1:6-1:13|-1|1|2", 25 | "extent": "1:1-1:28|-1|1|0", 26 | "bases": [], 27 | "derived": [], 28 | "vars": [], 29 | "uses": ["7:3-7:10|2|3|36"], 30 | "callees": [] 31 | }, { 32 | "id": 1, 33 | "usr": 5264867802674151787, 34 | "detailed_name": "void used()", 35 | "short_name": "used", 36 | "kind": 12, 37 | "storage": 1, 38 | "declarations": [], 39 | "spell": "3:6-3:10|-1|1|2", 40 | "extent": "3:1-3:15|-1|1|0", 41 | "bases": [], 42 | "derived": [], 43 | "vars": [], 44 | "uses": ["6:18-6:22|2|3|132", "7:12-7:16|2|3|132"], 45 | "callees": [] 46 | }, { 47 | "id": 2, 48 | "usr": 9376923949268137283, 49 | "detailed_name": "void user()", 50 | "short_name": "user", 51 | "kind": 12, 52 | "storage": 1, 53 | "declarations": [], 54 | "spell": "5:6-5:10|-1|1|2", 55 | "extent": "5:1-8:2|-1|1|0", 56 | "bases": [], 57 | "derived": [], 58 | "vars": [0], 59 | "uses": [], 60 | "callees": ["6:18-6:22|1|3|132", "6:18-6:22|1|3|132", "7:3-7:10|0|3|36", "7:12-7:16|1|3|132"] 61 | }], 62 | "vars": [{ 63 | "id": 0, 64 | "usr": 13681544683892648258, 65 | "detailed_name": "void (*)() x", 66 | "short_name": "x", 67 | "declarations": [], 68 | "spell": "6:10-6:11|2|3|2", 69 | "extent": "6:3-6:22|2|3|0", 70 | "uses": [], 71 | "kind": 13, 72 | "storage": 1 73 | }] 74 | } 75 | */ 76 | -------------------------------------------------------------------------------- /index_tests/usage/func_usage_addr_method.cc: -------------------------------------------------------------------------------- 1 | struct Foo { 2 | void Used(); 3 | }; 4 | 5 | void user() { 6 | auto x = &Foo::Used; 7 | } 8 | 9 | 10 | /* 11 | OUTPUT: 12 | { 13 | "includes": [], 14 | "skipped_by_preprocessor": [], 15 | "types": [{ 16 | "id": 0, 17 | "usr": 15041163540773201510, 18 | "detailed_name": "Foo", 19 | "short_name": "Foo", 20 | "kind": 23, 21 | "declarations": [], 22 | "spell": "1:8-1:11|-1|1|2", 23 | "extent": "1:1-3:2|-1|1|0", 24 | "bases": [], 25 | "derived": [], 26 | "types": [], 27 | "funcs": [0], 28 | "vars": [], 29 | "instances": [], 30 | "uses": ["6:13-6:16|-1|1|4"] 31 | }], 32 | "funcs": [{ 33 | "id": 0, 34 | "usr": 18417145003926999463, 35 | "detailed_name": "void Foo::Used()", 36 | "short_name": "Used", 37 | "kind": 6, 38 | "storage": 1, 39 | "declarations": [{ 40 | "spell": "2:8-2:12|0|2|1", 41 | "param_spellings": [] 42 | }], 43 | "declaring_type": 0, 44 | "bases": [], 45 | "derived": [], 46 | "vars": [], 47 | "uses": ["6:18-6:22|1|3|132"], 48 | "callees": [] 49 | }, { 50 | "id": 1, 51 | "usr": 9376923949268137283, 52 | "detailed_name": "void user()", 53 | "short_name": "user", 54 | "kind": 12, 55 | "storage": 1, 56 | "declarations": [], 57 | "spell": "5:6-5:10|-1|1|2", 58 | "extent": "5:1-7:2|-1|1|0", 59 | "bases": [], 60 | "derived": [], 61 | "vars": [0], 62 | "uses": [], 63 | "callees": ["6:18-6:22|0|3|132", "6:18-6:22|0|3|132"] 64 | }], 65 | "vars": [{ 66 | "id": 0, 67 | "usr": 8436636043513449412, 68 | "detailed_name": "void (Foo::*)() x", 69 | "short_name": "x", 70 | "declarations": [], 71 | "spell": "6:8-6:9|1|3|2", 72 | "extent": "6:3-6:22|1|3|0", 73 | "uses": [], 74 | "kind": 13, 75 | "storage": 1 76 | }] 77 | } 78 | */ 79 | -------------------------------------------------------------------------------- /index_tests/usage/func_usage_call_func.cc: -------------------------------------------------------------------------------- 1 | void called() {} 2 | void caller() { 3 | called(); 4 | } 5 | 6 | /* 7 | OUTPUT: 8 | { 9 | "includes": [], 10 | "skipped_by_preprocessor": [], 11 | "types": [], 12 | "funcs": [{ 13 | "id": 0, 14 | "usr": 468307235068920063, 15 | "detailed_name": "void called()", 16 | "short_name": "called", 17 | "kind": 12, 18 | "storage": 1, 19 | "declarations": [], 20 | "spell": "1:6-1:12|-1|1|2", 21 | "extent": "1:1-1:17|-1|1|0", 22 | "bases": [], 23 | "derived": [], 24 | "vars": [], 25 | "uses": ["3:3-3:9|1|3|36"], 26 | "callees": [] 27 | }, { 28 | "id": 1, 29 | "usr": 11404881820527069090, 30 | "detailed_name": "void caller()", 31 | "short_name": "caller", 32 | "kind": 12, 33 | "storage": 1, 34 | "declarations": [], 35 | "spell": "2:6-2:12|-1|1|2", 36 | "extent": "2:1-4:2|-1|1|0", 37 | "bases": [], 38 | "derived": [], 39 | "vars": [], 40 | "uses": [], 41 | "callees": ["3:3-3:9|0|3|36"] 42 | }], 43 | "vars": [] 44 | } 45 | */ 46 | -------------------------------------------------------------------------------- /index_tests/usage/func_usage_call_method.cc: -------------------------------------------------------------------------------- 1 | struct Foo { 2 | void Used(); 3 | }; 4 | 5 | void user() { 6 | Foo* f = nullptr; 7 | f->Used(); 8 | } 9 | 10 | /* 11 | OUTPUT: 12 | { 13 | "includes": [], 14 | "skipped_by_preprocessor": [], 15 | "types": [{ 16 | "id": 0, 17 | "usr": 15041163540773201510, 18 | "detailed_name": "Foo", 19 | "short_name": "Foo", 20 | "kind": 23, 21 | "declarations": [], 22 | "spell": "1:8-1:11|-1|1|2", 23 | "extent": "1:1-3:2|-1|1|0", 24 | "bases": [], 25 | "derived": [], 26 | "types": [], 27 | "funcs": [0], 28 | "vars": [], 29 | "instances": [0], 30 | "uses": ["6:3-6:6|-1|1|4"] 31 | }], 32 | "funcs": [{ 33 | "id": 0, 34 | "usr": 18417145003926999463, 35 | "detailed_name": "void Foo::Used()", 36 | "short_name": "Used", 37 | "kind": 6, 38 | "storage": 1, 39 | "declarations": [{ 40 | "spell": "2:8-2:12|0|2|1", 41 | "param_spellings": [] 42 | }], 43 | "declaring_type": 0, 44 | "bases": [], 45 | "derived": [], 46 | "vars": [], 47 | "uses": ["7:6-7:10|1|3|36"], 48 | "callees": [] 49 | }, { 50 | "id": 1, 51 | "usr": 9376923949268137283, 52 | "detailed_name": "void user()", 53 | "short_name": "user", 54 | "kind": 12, 55 | "storage": 1, 56 | "declarations": [], 57 | "spell": "5:6-5:10|-1|1|2", 58 | "extent": "5:1-8:2|-1|1|0", 59 | "bases": [], 60 | "derived": [], 61 | "vars": [0], 62 | "uses": [], 63 | "callees": ["7:6-7:10|0|3|36"] 64 | }], 65 | "vars": [{ 66 | "id": 0, 67 | "usr": 3014406561587537195, 68 | "detailed_name": "Foo *f", 69 | "short_name": "f", 70 | "hover": "Foo *f = nullptr", 71 | "declarations": [], 72 | "spell": "6:8-6:9|1|3|2", 73 | "extent": "6:3-6:19|1|3|0", 74 | "type": 0, 75 | "uses": ["7:3-7:4|1|3|12"], 76 | "kind": 13, 77 | "storage": 1 78 | }] 79 | } 80 | */ 81 | -------------------------------------------------------------------------------- /index_tests/usage/func_usage_class_inline_var_def.cc: -------------------------------------------------------------------------------- 1 | static int helper() { 2 | return 5; 3 | } 4 | 5 | class Foo { 6 | int x = helper(); 7 | }; 8 | 9 | /* 10 | OUTPUT: 11 | { 12 | "includes": [], 13 | "skipped_by_preprocessor": [], 14 | "types": [{ 15 | "id": 0, 16 | "usr": 15041163540773201510, 17 | "detailed_name": "Foo", 18 | "short_name": "Foo", 19 | "kind": 5, 20 | "declarations": [], 21 | "spell": "5:7-5:10|-1|1|2", 22 | "extent": "5:1-7:2|-1|1|0", 23 | "bases": [], 24 | "derived": [], 25 | "types": [], 26 | "funcs": [], 27 | "vars": [0], 28 | "instances": [], 29 | "uses": [] 30 | }, { 31 | "id": 1, 32 | "usr": 17, 33 | "detailed_name": "", 34 | "short_name": "", 35 | "kind": 0, 36 | "declarations": [], 37 | "bases": [], 38 | "derived": [], 39 | "types": [], 40 | "funcs": [], 41 | "vars": [], 42 | "instances": [0], 43 | "uses": [] 44 | }], 45 | "funcs": [{ 46 | "id": 0, 47 | "usr": 9630503130605430498, 48 | "detailed_name": "static int helper()", 49 | "short_name": "helper", 50 | "kind": 12, 51 | "storage": 3, 52 | "declarations": [], 53 | "spell": "1:12-1:18|-1|1|2", 54 | "extent": "1:1-3:2|-1|1|0", 55 | "bases": [], 56 | "derived": [], 57 | "vars": [], 58 | "uses": ["6:11-6:17|0|2|36"], 59 | "callees": [] 60 | }], 61 | "vars": [{ 62 | "id": 0, 63 | "usr": 4220150017963593039, 64 | "detailed_name": "int Foo::x", 65 | "short_name": "x", 66 | "hover": "int Foo::x = helper()", 67 | "declarations": [], 68 | "spell": "6:7-6:8|0|2|2", 69 | "extent": "6:3-6:19|0|2|0", 70 | "type": 1, 71 | "uses": [], 72 | "kind": 8, 73 | "storage": 0 74 | }] 75 | } 76 | */ 77 | -------------------------------------------------------------------------------- /index_tests/usage/func_usage_forward_decl_func.cc: -------------------------------------------------------------------------------- 1 | void foo(); 2 | 3 | void usage() { 4 | foo(); 5 | } 6 | /* 7 | OUTPUT: 8 | { 9 | "includes": [], 10 | "skipped_by_preprocessor": [], 11 | "types": [], 12 | "funcs": [{ 13 | "id": 0, 14 | "usr": 4259594751088586730, 15 | "detailed_name": "void foo()", 16 | "short_name": "foo", 17 | "kind": 12, 18 | "storage": 1, 19 | "declarations": [{ 20 | "spell": "1:6-1:9|-1|1|1", 21 | "param_spellings": [] 22 | }], 23 | "bases": [], 24 | "derived": [], 25 | "vars": [], 26 | "uses": ["4:3-4:6|1|3|36"], 27 | "callees": [] 28 | }, { 29 | "id": 1, 30 | "usr": 6767773193109753523, 31 | "detailed_name": "void usage()", 32 | "short_name": "usage", 33 | "kind": 12, 34 | "storage": 1, 35 | "declarations": [], 36 | "spell": "3:6-3:11|-1|1|2", 37 | "extent": "3:1-5:2|-1|1|0", 38 | "bases": [], 39 | "derived": [], 40 | "vars": [], 41 | "uses": [], 42 | "callees": ["4:3-4:6|0|3|36"] 43 | }], 44 | "vars": [] 45 | } 46 | */ 47 | -------------------------------------------------------------------------------- /index_tests/usage/func_usage_forward_decl_method.cc: -------------------------------------------------------------------------------- 1 | struct Foo { 2 | void foo(); 3 | }; 4 | 5 | void usage() { 6 | Foo* f = nullptr; 7 | f->foo(); 8 | } 9 | /* 10 | OUTPUT: 11 | { 12 | "includes": [], 13 | "skipped_by_preprocessor": [], 14 | "types": [{ 15 | "id": 0, 16 | "usr": 15041163540773201510, 17 | "detailed_name": "Foo", 18 | "short_name": "Foo", 19 | "kind": 23, 20 | "declarations": [], 21 | "spell": "1:8-1:11|-1|1|2", 22 | "extent": "1:1-3:2|-1|1|0", 23 | "bases": [], 24 | "derived": [], 25 | "types": [], 26 | "funcs": [0], 27 | "vars": [], 28 | "instances": [0], 29 | "uses": ["6:3-6:6|-1|1|4"] 30 | }], 31 | "funcs": [{ 32 | "id": 0, 33 | "usr": 17922201480358737771, 34 | "detailed_name": "void Foo::foo()", 35 | "short_name": "foo", 36 | "kind": 6, 37 | "storage": 1, 38 | "declarations": [{ 39 | "spell": "2:8-2:11|0|2|1", 40 | "param_spellings": [] 41 | }], 42 | "declaring_type": 0, 43 | "bases": [], 44 | "derived": [], 45 | "vars": [], 46 | "uses": ["7:6-7:9|1|3|36"], 47 | "callees": [] 48 | }, { 49 | "id": 1, 50 | "usr": 6767773193109753523, 51 | "detailed_name": "void usage()", 52 | "short_name": "usage", 53 | "kind": 12, 54 | "storage": 1, 55 | "declarations": [], 56 | "spell": "5:6-5:11|-1|1|2", 57 | "extent": "5:1-8:2|-1|1|0", 58 | "bases": [], 59 | "derived": [], 60 | "vars": [0], 61 | "uses": [], 62 | "callees": ["7:6-7:9|0|3|36"] 63 | }], 64 | "vars": [{ 65 | "id": 0, 66 | "usr": 12410753116854389823, 67 | "detailed_name": "Foo *f", 68 | "short_name": "f", 69 | "hover": "Foo *f = nullptr", 70 | "declarations": [], 71 | "spell": "6:8-6:9|1|3|2", 72 | "extent": "6:3-6:19|1|3|0", 73 | "type": 0, 74 | "uses": ["7:3-7:4|1|3|12"], 75 | "kind": 13, 76 | "storage": 1 77 | }] 78 | } 79 | */ 80 | -------------------------------------------------------------------------------- /index_tests/usage/func_usage_template_func.cc: -------------------------------------------------------------------------------- 1 | template 2 | void accept(T); 3 | 4 | void foo() { 5 | accept(1); 6 | accept(true); 7 | } 8 | 9 | /* 10 | OUTPUT: 11 | { 12 | "includes": [], 13 | "skipped_by_preprocessor": [], 14 | "types": [{ 15 | "id": 0, 16 | "usr": 13420564603121289209, 17 | "detailed_name": "T", 18 | "short_name": "T", 19 | "kind": 26, 20 | "declarations": [], 21 | "spell": "1:19-1:20|0|3|2", 22 | "extent": "1:10-1:20|0|3|0", 23 | "bases": [], 24 | "derived": [], 25 | "types": [], 26 | "funcs": [], 27 | "vars": [], 28 | "instances": [], 29 | "uses": ["2:13-2:14|-1|1|4"] 30 | }], 31 | "funcs": [{ 32 | "id": 0, 33 | "usr": 10585861037135727329, 34 | "detailed_name": "void accept(T)", 35 | "short_name": "accept", 36 | "kind": 12, 37 | "storage": 1, 38 | "declarations": [{ 39 | "spell": "2:6-2:12|-1|1|1", 40 | "param_spellings": ["2:14-2:14"] 41 | }], 42 | "bases": [], 43 | "derived": [], 44 | "vars": [], 45 | "uses": ["5:3-5:9|1|3|36", "6:3-6:9|1|3|36"], 46 | "callees": [] 47 | }, { 48 | "id": 1, 49 | "usr": 4259594751088586730, 50 | "detailed_name": "void foo()", 51 | "short_name": "foo", 52 | "kind": 12, 53 | "storage": 1, 54 | "declarations": [], 55 | "spell": "4:6-4:9|-1|1|2", 56 | "extent": "4:1-7:2|-1|1|0", 57 | "bases": [], 58 | "derived": [], 59 | "vars": [], 60 | "uses": [], 61 | "callees": ["5:3-5:9|0|3|36", "6:3-6:9|0|3|36"] 62 | }], 63 | "vars": [] 64 | } 65 | */ 66 | -------------------------------------------------------------------------------- /index_tests/usage/type_usage_as_template_parameter_simple.cc: -------------------------------------------------------------------------------- 1 | template 2 | class unique_ptr {}; 3 | 4 | struct S; 5 | 6 | static unique_ptr foo; 7 | 8 | /* 9 | OUTPUT: 10 | { 11 | "includes": [], 12 | "skipped_by_preprocessor": [], 13 | "types": [{ 14 | "id": 0, 15 | "usr": 3286534761799572592, 16 | "detailed_name": "unique_ptr", 17 | "short_name": "unique_ptr", 18 | "kind": 5, 19 | "declarations": [], 20 | "spell": "2:7-2:17|-1|1|2", 21 | "extent": "2:1-2:20|-1|1|0", 22 | "bases": [], 23 | "derived": [], 24 | "types": [], 25 | "funcs": [], 26 | "vars": [], 27 | "instances": [0], 28 | "uses": ["6:8-6:18|-1|1|4"] 29 | }, { 30 | "id": 1, 31 | "usr": 4750332761459066907, 32 | "detailed_name": "S", 33 | "short_name": "S", 34 | "kind": 23, 35 | "declarations": ["4:8-4:9|-1|1|1"], 36 | "bases": [], 37 | "derived": [], 38 | "types": [], 39 | "funcs": [], 40 | "vars": [], 41 | "instances": [], 42 | "uses": ["6:19-6:20|-1|1|4"] 43 | }], 44 | "funcs": [], 45 | "vars": [{ 46 | "id": 0, 47 | "usr": 3398408600781120939, 48 | "detailed_name": "unique_ptr foo", 49 | "short_name": "foo", 50 | "declarations": [], 51 | "spell": "6:22-6:25|-1|1|2", 52 | "extent": "6:1-6:25|-1|1|0", 53 | "type": 0, 54 | "uses": [], 55 | "kind": 13, 56 | "storage": 3 57 | }] 58 | } 59 | */ 60 | -------------------------------------------------------------------------------- /index_tests/usage/type_usage_declare_extern.cc: -------------------------------------------------------------------------------- 1 | struct T {}; 2 | 3 | extern T t; 4 | /* 5 | OUTPUT: 6 | { 7 | "includes": [], 8 | "skipped_by_preprocessor": [], 9 | "types": [{ 10 | "id": 0, 11 | "usr": 5673439900521455039, 12 | "detailed_name": "T", 13 | "short_name": "T", 14 | "kind": 23, 15 | "declarations": [], 16 | "spell": "1:8-1:9|-1|1|2", 17 | "extent": "1:1-1:12|-1|1|0", 18 | "bases": [], 19 | "derived": [], 20 | "types": [], 21 | "funcs": [], 22 | "vars": [], 23 | "instances": [0], 24 | "uses": ["3:8-3:9|-1|1|4"] 25 | }], 26 | "funcs": [], 27 | "vars": [{ 28 | "id": 0, 29 | "usr": 1346710425945444872, 30 | "detailed_name": "T t", 31 | "short_name": "t", 32 | "declarations": ["3:10-3:11|-1|1|1"], 33 | "type": 0, 34 | "uses": [], 35 | "kind": 13, 36 | "storage": 2 37 | }] 38 | } 39 | */ 40 | -------------------------------------------------------------------------------- /index_tests/usage/type_usage_declare_param_prototype.cc: -------------------------------------------------------------------------------- 1 | struct Foo; 2 | 3 | void foo(Foo* f, Foo*); 4 | void foo(Foo* f, Foo*) {} 5 | 6 | /* 7 | // TODO: No interesting usage on prototype. But maybe that's ok! 8 | // TODO: We should have the same variable declared for both prototype and 9 | // declaration. So it should have a usage marker on both. Then we could 10 | // rename parameters! 11 | 12 | OUTPUT: 13 | { 14 | "includes": [], 15 | "skipped_by_preprocessor": [], 16 | "types": [{ 17 | "id": 0, 18 | "usr": 15041163540773201510, 19 | "detailed_name": "Foo", 20 | "short_name": "Foo", 21 | "kind": 23, 22 | "declarations": ["1:8-1:11|-1|1|1"], 23 | "bases": [], 24 | "derived": [], 25 | "types": [], 26 | "funcs": [], 27 | "vars": [], 28 | "instances": [0], 29 | "uses": ["3:10-3:13|-1|1|4", "3:18-3:21|-1|1|4", "4:10-4:13|-1|1|4", "4:18-4:21|-1|1|4"] 30 | }], 31 | "funcs": [{ 32 | "id": 0, 33 | "usr": 8908726657907936744, 34 | "detailed_name": "void foo(Foo *f, Foo *)", 35 | "short_name": "foo", 36 | "kind": 12, 37 | "storage": 1, 38 | "declarations": [{ 39 | "spell": "3:6-3:9|-1|1|1", 40 | "param_spellings": ["3:15-3:16", "3:22-3:22"] 41 | }], 42 | "spell": "4:6-4:9|-1|1|2", 43 | "extent": "4:1-4:26|-1|1|0", 44 | "bases": [], 45 | "derived": [], 46 | "vars": [0], 47 | "uses": [], 48 | "callees": [] 49 | }], 50 | "vars": [{ 51 | "id": 0, 52 | "usr": 2161866804398917919, 53 | "detailed_name": "Foo *f", 54 | "short_name": "f", 55 | "declarations": [], 56 | "spell": "4:15-4:16|0|3|2", 57 | "extent": "4:10-4:16|0|3|0", 58 | "type": 0, 59 | "uses": [], 60 | "kind": 253, 61 | "storage": 1 62 | }] 63 | } 64 | */ 65 | -------------------------------------------------------------------------------- /index_tests/usage/type_usage_declare_param_unnamed.cc: -------------------------------------------------------------------------------- 1 | struct ForwardType; 2 | void foo(ForwardType*) {} 3 | /* 4 | OUTPUT: 5 | { 6 | "includes": [], 7 | "skipped_by_preprocessor": [], 8 | "types": [{ 9 | "id": 0, 10 | "usr": 13749354388332789217, 11 | "detailed_name": "ForwardType", 12 | "short_name": "ForwardType", 13 | "kind": 23, 14 | "declarations": ["1:8-1:19|-1|1|1"], 15 | "bases": [], 16 | "derived": [], 17 | "types": [], 18 | "funcs": [], 19 | "vars": [], 20 | "instances": [], 21 | "uses": ["2:10-2:21|-1|1|4"] 22 | }], 23 | "funcs": [{ 24 | "id": 0, 25 | "usr": 15327735280790448926, 26 | "detailed_name": "void foo(ForwardType *)", 27 | "short_name": "foo", 28 | "kind": 12, 29 | "storage": 1, 30 | "declarations": [], 31 | "spell": "2:6-2:9|-1|1|2", 32 | "extent": "2:1-2:26|-1|1|0", 33 | "bases": [], 34 | "derived": [], 35 | "vars": [], 36 | "uses": [], 37 | "callees": [] 38 | }], 39 | "vars": [] 40 | } 41 | */ 42 | -------------------------------------------------------------------------------- /index_tests/usage/type_usage_declare_static.cc: -------------------------------------------------------------------------------- 1 | struct Type {}; 2 | static Type t; 3 | /* 4 | OUTPUT: 5 | { 6 | "includes": [], 7 | "skipped_by_preprocessor": [], 8 | "types": [{ 9 | "id": 0, 10 | "usr": 13487927231218873822, 11 | "detailed_name": "Type", 12 | "short_name": "Type", 13 | "kind": 23, 14 | "declarations": [], 15 | "spell": "1:8-1:12|-1|1|2", 16 | "extent": "1:1-1:15|-1|1|0", 17 | "bases": [], 18 | "derived": [], 19 | "types": [], 20 | "funcs": [], 21 | "vars": [], 22 | "instances": [0], 23 | "uses": ["2:8-2:12|-1|1|4"] 24 | }], 25 | "funcs": [], 26 | "vars": [{ 27 | "id": 0, 28 | "usr": 6601831367240627080, 29 | "detailed_name": "Type t", 30 | "short_name": "t", 31 | "declarations": [], 32 | "spell": "2:13-2:14|-1|1|2", 33 | "extent": "2:1-2:14|-1|1|0", 34 | "type": 0, 35 | "uses": [], 36 | "kind": 13, 37 | "storage": 3 38 | }] 39 | } 40 | */ 41 | -------------------------------------------------------------------------------- /index_tests/usage/type_usage_typedef_and_using_template.cc: -------------------------------------------------------------------------------- 1 | template 2 | struct Foo; 3 | 4 | using Foo1 = Foo; 5 | typedef Foo Foo2; 6 | 7 | /* 8 | OUTPUT: 9 | { 10 | "includes": [], 11 | "skipped_by_preprocessor": [], 12 | "types": [{ 13 | "id": 0, 14 | "usr": 10528472276654770367, 15 | "detailed_name": "Foo", 16 | "short_name": "Foo", 17 | "kind": 5, 18 | "declarations": ["2:8-2:11|-1|1|1"], 19 | "bases": [], 20 | "derived": [], 21 | "types": [], 22 | "funcs": [], 23 | "vars": [], 24 | "instances": [], 25 | "uses": ["4:14-4:17|-1|1|4", "5:9-5:12|-1|1|4"] 26 | }, { 27 | "id": 1, 28 | "usr": 1544499294580512394, 29 | "detailed_name": "Foo1", 30 | "short_name": "Foo1", 31 | "kind": 252, 32 | "hover": "using Foo1 = Foo", 33 | "declarations": [], 34 | "spell": "4:7-4:11|-1|1|2", 35 | "extent": "4:1-4:22|-1|1|0", 36 | "alias_of": 0, 37 | "bases": [], 38 | "derived": [], 39 | "types": [], 40 | "funcs": [], 41 | "vars": [], 42 | "instances": [], 43 | "uses": ["4:7-4:11|-1|1|4", "5:13-5:17|-1|1|4"] 44 | }, { 45 | "id": 2, 46 | "usr": 15933698173231330933, 47 | "detailed_name": "Foo2", 48 | "short_name": "Foo2", 49 | "kind": 252, 50 | "hover": "typedef Foo Foo2", 51 | "declarations": [], 52 | "spell": "5:19-5:23|-1|1|2", 53 | "extent": "5:1-5:23|-1|1|0", 54 | "alias_of": 0, 55 | "bases": [], 56 | "derived": [], 57 | "types": [], 58 | "funcs": [], 59 | "vars": [], 60 | "instances": [], 61 | "uses": ["5:19-5:23|-1|1|4"] 62 | }], 63 | "funcs": [], 64 | "vars": [] 65 | } 66 | */ 67 | -------------------------------------------------------------------------------- /index_tests/usage/type_usage_various.cc: -------------------------------------------------------------------------------- 1 | class Foo { 2 | Foo* make(); 3 | }; 4 | 5 | Foo* Foo::make() { 6 | Foo f; 7 | return nullptr; 8 | } 9 | 10 | extern Foo foo; 11 | 12 | /* 13 | OUTPUT: 14 | { 15 | "includes": [], 16 | "skipped_by_preprocessor": [], 17 | "types": [{ 18 | "id": 0, 19 | "usr": 15041163540773201510, 20 | "detailed_name": "Foo", 21 | "short_name": "Foo", 22 | "kind": 5, 23 | "declarations": [], 24 | "spell": "1:7-1:10|-1|1|2", 25 | "extent": "1:1-3:2|-1|1|0", 26 | "bases": [], 27 | "derived": [], 28 | "types": [], 29 | "funcs": [0], 30 | "vars": [], 31 | "instances": [0, 1], 32 | "uses": ["2:3-2:6|-1|1|4", "5:1-5:4|-1|1|4", "5:6-5:9|-1|1|4", "6:3-6:6|-1|1|4", "10:8-10:11|-1|1|4"] 33 | }], 34 | "funcs": [{ 35 | "id": 0, 36 | "usr": 9488177941273031343, 37 | "detailed_name": "Foo *Foo::make()", 38 | "short_name": "make", 39 | "kind": 6, 40 | "storage": 1, 41 | "declarations": [{ 42 | "spell": "2:8-2:12|0|2|1", 43 | "param_spellings": [] 44 | }], 45 | "spell": "5:11-5:15|0|2|2", 46 | "extent": "5:1-8:2|-1|1|0", 47 | "declaring_type": 0, 48 | "bases": [], 49 | "derived": [], 50 | "vars": [0], 51 | "uses": [], 52 | "callees": [] 53 | }], 54 | "vars": [{ 55 | "id": 0, 56 | "usr": 14873619387499024780, 57 | "detailed_name": "Foo f", 58 | "short_name": "f", 59 | "declarations": [], 60 | "spell": "6:7-6:8|0|3|2", 61 | "extent": "6:3-6:8|0|3|0", 62 | "type": 0, 63 | "uses": [], 64 | "kind": 13, 65 | "storage": 1 66 | }, { 67 | "id": 1, 68 | "usr": 14455976355866885943, 69 | "detailed_name": "Foo foo", 70 | "short_name": "foo", 71 | "declarations": ["10:12-10:15|-1|1|1"], 72 | "type": 0, 73 | "uses": [], 74 | "kind": 13, 75 | "storage": 2 76 | }] 77 | } 78 | */ 79 | -------------------------------------------------------------------------------- /index_tests/usage/usage_inside_of_call_simple.cc: -------------------------------------------------------------------------------- 1 | void called(int a); 2 | 3 | int gen() { return 1; } 4 | 5 | void foo() { 6 | called(gen() * gen()); 7 | } 8 | 9 | /* 10 | OUTPUT: 11 | { 12 | "includes": [], 13 | "skipped_by_preprocessor": [], 14 | "types": [], 15 | "funcs": [{ 16 | "id": 0, 17 | "usr": 18319417758892371313, 18 | "detailed_name": "void called(int a)", 19 | "short_name": "called", 20 | "kind": 12, 21 | "storage": 1, 22 | "declarations": [{ 23 | "spell": "1:6-1:12|-1|1|1", 24 | "param_spellings": ["1:17-1:18"] 25 | }], 26 | "bases": [], 27 | "derived": [], 28 | "vars": [], 29 | "uses": ["6:3-6:9|2|3|36"], 30 | "callees": [] 31 | }, { 32 | "id": 1, 33 | "usr": 11404602816585117695, 34 | "detailed_name": "int gen()", 35 | "short_name": "gen", 36 | "kind": 12, 37 | "storage": 1, 38 | "declarations": [], 39 | "spell": "3:5-3:8|-1|1|2", 40 | "extent": "3:1-3:24|-1|1|0", 41 | "bases": [], 42 | "derived": [], 43 | "vars": [], 44 | "uses": ["6:10-6:13|2|3|36", "6:18-6:21|2|3|36"], 45 | "callees": [] 46 | }, { 47 | "id": 2, 48 | "usr": 4259594751088586730, 49 | "detailed_name": "void foo()", 50 | "short_name": "foo", 51 | "kind": 12, 52 | "storage": 1, 53 | "declarations": [], 54 | "spell": "5:6-5:9|-1|1|2", 55 | "extent": "5:1-7:2|-1|1|0", 56 | "bases": [], 57 | "derived": [], 58 | "vars": [], 59 | "uses": [], 60 | "callees": ["6:3-6:9|0|3|36", "6:10-6:13|1|3|36", "6:18-6:21|1|3|36"] 61 | }], 62 | "vars": [] 63 | } 64 | */ 65 | -------------------------------------------------------------------------------- /index_tests/usage/var_usage_call_function.cc: -------------------------------------------------------------------------------- 1 | void called() {} 2 | 3 | void caller() { 4 | auto x = &called; 5 | x(); 6 | 7 | called(); 8 | } 9 | 10 | /* 11 | OUTPUT: 12 | { 13 | "includes": [], 14 | "skipped_by_preprocessor": [], 15 | "types": [], 16 | "funcs": [{ 17 | "id": 0, 18 | "usr": 468307235068920063, 19 | "detailed_name": "void called()", 20 | "short_name": "called", 21 | "kind": 12, 22 | "storage": 1, 23 | "declarations": [], 24 | "spell": "1:6-1:12|-1|1|2", 25 | "extent": "1:1-1:17|-1|1|0", 26 | "bases": [], 27 | "derived": [], 28 | "vars": [], 29 | "uses": ["4:13-4:19|1|3|132", "7:3-7:9|1|3|36"], 30 | "callees": [] 31 | }, { 32 | "id": 1, 33 | "usr": 11404881820527069090, 34 | "detailed_name": "void caller()", 35 | "short_name": "caller", 36 | "kind": 12, 37 | "storage": 1, 38 | "declarations": [], 39 | "spell": "3:6-3:12|-1|1|2", 40 | "extent": "3:1-8:2|-1|1|0", 41 | "bases": [], 42 | "derived": [], 43 | "vars": [0], 44 | "uses": [], 45 | "callees": ["4:13-4:19|0|3|132", "4:13-4:19|0|3|132", "7:3-7:9|0|3|36"] 46 | }], 47 | "vars": [{ 48 | "id": 0, 49 | "usr": 3510529098767253033, 50 | "detailed_name": "void (*)() x", 51 | "short_name": "x", 52 | "declarations": [], 53 | "spell": "4:8-4:9|1|3|2", 54 | "extent": "4:3-4:19|1|3|0", 55 | "uses": ["5:3-5:4|1|3|44"], 56 | "kind": 13, 57 | "storage": 1 58 | }] 59 | } 60 | */ 61 | -------------------------------------------------------------------------------- /index_tests/usage/var_usage_extern.cc: -------------------------------------------------------------------------------- 1 | extern int a; 2 | 3 | void foo() { 4 | a = 5; 5 | } 6 | /* 7 | OUTPUT: 8 | { 9 | "includes": [], 10 | "skipped_by_preprocessor": [], 11 | "types": [{ 12 | "id": 0, 13 | "usr": 17, 14 | "detailed_name": "", 15 | "short_name": "", 16 | "kind": 0, 17 | "declarations": [], 18 | "bases": [], 19 | "derived": [], 20 | "types": [], 21 | "funcs": [], 22 | "vars": [], 23 | "instances": [0], 24 | "uses": [] 25 | }], 26 | "funcs": [{ 27 | "id": 0, 28 | "usr": 4259594751088586730, 29 | "detailed_name": "void foo()", 30 | "short_name": "foo", 31 | "kind": 12, 32 | "storage": 1, 33 | "declarations": [], 34 | "spell": "3:6-3:9|-1|1|2", 35 | "extent": "3:1-5:2|-1|1|0", 36 | "bases": [], 37 | "derived": [], 38 | "vars": [], 39 | "uses": [], 40 | "callees": [] 41 | }], 42 | "vars": [{ 43 | "id": 0, 44 | "usr": 16721564935990383768, 45 | "detailed_name": "int a", 46 | "short_name": "a", 47 | "declarations": ["1:12-1:13|-1|1|1"], 48 | "type": 0, 49 | "uses": ["4:3-4:4|0|3|20"], 50 | "kind": 13, 51 | "storage": 2 52 | }] 53 | } 54 | */ 55 | -------------------------------------------------------------------------------- /index_tests/usage/var_usage_func_parameter.cc: -------------------------------------------------------------------------------- 1 | void foo(int a) { 2 | a += 10; 3 | } 4 | /* 5 | OUTPUT: 6 | { 7 | "includes": [], 8 | "skipped_by_preprocessor": [], 9 | "types": [{ 10 | "id": 0, 11 | "usr": 17, 12 | "detailed_name": "", 13 | "short_name": "", 14 | "kind": 0, 15 | "declarations": [], 16 | "bases": [], 17 | "derived": [], 18 | "types": [], 19 | "funcs": [], 20 | "vars": [], 21 | "instances": [0], 22 | "uses": [] 23 | }], 24 | "funcs": [{ 25 | "id": 0, 26 | "usr": 11998306017310352355, 27 | "detailed_name": "void foo(int a)", 28 | "short_name": "foo", 29 | "kind": 12, 30 | "storage": 1, 31 | "declarations": [], 32 | "spell": "1:6-1:9|-1|1|2", 33 | "extent": "1:1-3:2|-1|1|0", 34 | "bases": [], 35 | "derived": [], 36 | "vars": [0], 37 | "uses": [], 38 | "callees": [] 39 | }], 40 | "vars": [{ 41 | "id": 0, 42 | "usr": 10063793875496522529, 43 | "detailed_name": "int a", 44 | "short_name": "a", 45 | "declarations": [], 46 | "spell": "1:14-1:15|0|3|2", 47 | "extent": "1:10-1:15|0|3|0", 48 | "type": 0, 49 | "uses": ["2:3-2:4|0|3|4"], 50 | "kind": 253, 51 | "storage": 1 52 | }] 53 | } 54 | */ 55 | -------------------------------------------------------------------------------- /index_tests/usage/var_usage_local.cc: -------------------------------------------------------------------------------- 1 | void foo() { 2 | int x; 3 | x = 3; 4 | } 5 | /* 6 | OUTPUT: 7 | { 8 | "includes": [], 9 | "skipped_by_preprocessor": [], 10 | "types": [{ 11 | "id": 0, 12 | "usr": 17, 13 | "detailed_name": "", 14 | "short_name": "", 15 | "kind": 0, 16 | "declarations": [], 17 | "bases": [], 18 | "derived": [], 19 | "types": [], 20 | "funcs": [], 21 | "vars": [], 22 | "instances": [0], 23 | "uses": [] 24 | }], 25 | "funcs": [{ 26 | "id": 0, 27 | "usr": 4259594751088586730, 28 | "detailed_name": "void foo()", 29 | "short_name": "foo", 30 | "kind": 12, 31 | "storage": 1, 32 | "declarations": [], 33 | "spell": "1:6-1:9|-1|1|2", 34 | "extent": "1:1-4:2|-1|1|0", 35 | "bases": [], 36 | "derived": [], 37 | "vars": [0], 38 | "uses": [], 39 | "callees": [] 40 | }], 41 | "vars": [{ 42 | "id": 0, 43 | "usr": 8534460107894911680, 44 | "detailed_name": "int x", 45 | "short_name": "x", 46 | "declarations": [], 47 | "spell": "2:7-2:8|0|3|2", 48 | "extent": "2:3-2:8|0|3|0", 49 | "type": 0, 50 | "uses": ["3:3-3:4|0|3|20"], 51 | "kind": 13, 52 | "storage": 1 53 | }] 54 | } 55 | */ 56 | -------------------------------------------------------------------------------- /index_tests/usage/var_usage_shadowed_local.cc: -------------------------------------------------------------------------------- 1 | void foo() { 2 | int a; 3 | a = 1; 4 | { 5 | int a; 6 | a = 2; 7 | } 8 | a = 3; 9 | } 10 | /* 11 | OUTPUT: 12 | { 13 | "includes": [], 14 | "skipped_by_preprocessor": [], 15 | "types": [{ 16 | "id": 0, 17 | "usr": 17, 18 | "detailed_name": "", 19 | "short_name": "", 20 | "kind": 0, 21 | "declarations": [], 22 | "bases": [], 23 | "derived": [], 24 | "types": [], 25 | "funcs": [], 26 | "vars": [], 27 | "instances": [0, 1], 28 | "uses": [] 29 | }], 30 | "funcs": [{ 31 | "id": 0, 32 | "usr": 4259594751088586730, 33 | "detailed_name": "void foo()", 34 | "short_name": "foo", 35 | "kind": 12, 36 | "storage": 1, 37 | "declarations": [], 38 | "spell": "1:6-1:9|-1|1|2", 39 | "extent": "1:1-9:2|-1|1|0", 40 | "bases": [], 41 | "derived": [], 42 | "vars": [0, 1], 43 | "uses": [], 44 | "callees": [] 45 | }], 46 | "vars": [{ 47 | "id": 0, 48 | "usr": 17941402366659878910, 49 | "detailed_name": "int a", 50 | "short_name": "a", 51 | "declarations": [], 52 | "spell": "2:7-2:8|0|3|2", 53 | "extent": "2:3-2:8|0|3|0", 54 | "type": 0, 55 | "uses": ["3:3-3:4|0|3|20", "8:3-8:4|0|3|20"], 56 | "kind": 13, 57 | "storage": 1 58 | }, { 59 | "id": 1, 60 | "usr": 11094102496276744608, 61 | "detailed_name": "int a", 62 | "short_name": "a", 63 | "declarations": [], 64 | "spell": "5:9-5:10|0|3|2", 65 | "extent": "5:5-5:10|0|3|0", 66 | "type": 0, 67 | "uses": ["6:5-6:6|0|3|20"], 68 | "kind": 13, 69 | "storage": 1 70 | }] 71 | } 72 | */ 73 | -------------------------------------------------------------------------------- /index_tests/usage/var_usage_shadowed_parameter.cc: -------------------------------------------------------------------------------- 1 | void foo(int a) { 2 | a = 1; 3 | { 4 | int a; 5 | a = 2; 6 | } 7 | a = 3; 8 | } 9 | 10 | /* 11 | OUTPUT: 12 | { 13 | "includes": [], 14 | "skipped_by_preprocessor": [], 15 | "types": [{ 16 | "id": 0, 17 | "usr": 17, 18 | "detailed_name": "", 19 | "short_name": "", 20 | "kind": 0, 21 | "declarations": [], 22 | "bases": [], 23 | "derived": [], 24 | "types": [], 25 | "funcs": [], 26 | "vars": [], 27 | "instances": [0, 1], 28 | "uses": [] 29 | }], 30 | "funcs": [{ 31 | "id": 0, 32 | "usr": 11998306017310352355, 33 | "detailed_name": "void foo(int a)", 34 | "short_name": "foo", 35 | "kind": 12, 36 | "storage": 1, 37 | "declarations": [], 38 | "spell": "1:6-1:9|-1|1|2", 39 | "extent": "1:1-8:2|-1|1|0", 40 | "bases": [], 41 | "derived": [], 42 | "vars": [0, 1], 43 | "uses": [], 44 | "callees": [] 45 | }], 46 | "vars": [{ 47 | "id": 0, 48 | "usr": 11608231465452906059, 49 | "detailed_name": "int a", 50 | "short_name": "a", 51 | "declarations": [], 52 | "spell": "1:14-1:15|0|3|2", 53 | "extent": "1:10-1:15|0|3|0", 54 | "type": 0, 55 | "uses": ["2:3-2:4|0|3|20", "7:3-7:4|0|3|20"], 56 | "kind": 253, 57 | "storage": 1 58 | }, { 59 | "id": 1, 60 | "usr": 8011559936501990179, 61 | "detailed_name": "int a", 62 | "short_name": "a", 63 | "declarations": [], 64 | "spell": "4:9-4:10|0|3|2", 65 | "extent": "4:5-4:10|0|3|0", 66 | "type": 0, 67 | "uses": ["5:5-5:6|0|3|20"], 68 | "kind": 13, 69 | "storage": 1 70 | }] 71 | } 72 | */ 73 | -------------------------------------------------------------------------------- /index_tests/usage/var_usage_static.cc: -------------------------------------------------------------------------------- 1 | static int a; 2 | 3 | void foo() { 4 | a = 3; 5 | } 6 | 7 | /* 8 | OUTPUT: 9 | { 10 | "includes": [], 11 | "skipped_by_preprocessor": [], 12 | "types": [{ 13 | "id": 0, 14 | "usr": 17, 15 | "detailed_name": "", 16 | "short_name": "", 17 | "kind": 0, 18 | "declarations": [], 19 | "bases": [], 20 | "derived": [], 21 | "types": [], 22 | "funcs": [], 23 | "vars": [], 24 | "instances": [0], 25 | "uses": [] 26 | }], 27 | "funcs": [{ 28 | "id": 0, 29 | "usr": 4259594751088586730, 30 | "detailed_name": "void foo()", 31 | "short_name": "foo", 32 | "kind": 12, 33 | "storage": 1, 34 | "declarations": [], 35 | "spell": "3:6-3:9|-1|1|2", 36 | "extent": "3:1-5:2|-1|1|0", 37 | "bases": [], 38 | "derived": [], 39 | "vars": [], 40 | "uses": [], 41 | "callees": [] 42 | }], 43 | "vars": [{ 44 | "id": 0, 45 | "usr": 11823161916242867318, 46 | "detailed_name": "int a", 47 | "short_name": "a", 48 | "declarations": [], 49 | "spell": "1:12-1:13|-1|1|2", 50 | "extent": "1:1-1:13|-1|1|0", 51 | "type": 0, 52 | "uses": ["4:3-4:4|0|3|20"], 53 | "kind": 13, 54 | "storage": 3 55 | }] 56 | } 57 | */ 58 | -------------------------------------------------------------------------------- /index_tests/vars/class_member.cc: -------------------------------------------------------------------------------- 1 | class Foo { 2 | Foo* member; 3 | }; 4 | /* 5 | OUTPUT: 6 | { 7 | "includes": [], 8 | "skipped_by_preprocessor": [], 9 | "types": [{ 10 | "id": 0, 11 | "usr": 15041163540773201510, 12 | "detailed_name": "Foo", 13 | "short_name": "Foo", 14 | "kind": 5, 15 | "declarations": [], 16 | "spell": "1:7-1:10|-1|1|2", 17 | "extent": "1:1-3:2|-1|1|0", 18 | "bases": [], 19 | "derived": [], 20 | "types": [], 21 | "funcs": [], 22 | "vars": [0], 23 | "instances": [0], 24 | "uses": ["2:3-2:6|-1|1|4"] 25 | }], 26 | "funcs": [], 27 | "vars": [{ 28 | "id": 0, 29 | "usr": 13799811842374292251, 30 | "detailed_name": "Foo *Foo::member", 31 | "short_name": "member", 32 | "declarations": [], 33 | "spell": "2:8-2:14|0|2|2", 34 | "extent": "2:3-2:14|0|2|0", 35 | "type": 0, 36 | "uses": [], 37 | "kind": 8, 38 | "storage": 0 39 | }] 40 | } 41 | */ 42 | -------------------------------------------------------------------------------- /index_tests/vars/class_static_member.cc: -------------------------------------------------------------------------------- 1 | class Foo { 2 | static Foo* member; 3 | }; 4 | Foo* Foo::member = nullptr; 5 | 6 | /* 7 | OUTPUT: 8 | { 9 | "includes": [], 10 | "skipped_by_preprocessor": [], 11 | "types": [{ 12 | "id": 0, 13 | "usr": 15041163540773201510, 14 | "detailed_name": "Foo", 15 | "short_name": "Foo", 16 | "kind": 5, 17 | "declarations": [], 18 | "spell": "1:7-1:10|-1|1|2", 19 | "extent": "1:1-3:2|-1|1|0", 20 | "bases": [], 21 | "derived": [], 22 | "types": [], 23 | "funcs": [], 24 | "vars": [0], 25 | "instances": [0], 26 | "uses": ["2:10-2:13|-1|1|4", "4:1-4:4|-1|1|4", "4:6-4:9|-1|1|4"] 27 | }], 28 | "funcs": [], 29 | "vars": [{ 30 | "id": 0, 31 | "usr": 5844987037615239736, 32 | "detailed_name": "Foo *Foo::member", 33 | "short_name": "member", 34 | "hover": "Foo *Foo::member = nullptr", 35 | "declarations": ["2:15-2:21|0|2|1"], 36 | "spell": "4:11-4:17|0|2|2", 37 | "extent": "4:1-4:27|-1|1|0", 38 | "type": 0, 39 | "uses": [], 40 | "kind": 8, 41 | "storage": 1 42 | }] 43 | } 44 | */ 45 | -------------------------------------------------------------------------------- /index_tests/vars/class_static_member_decl_only.cc: -------------------------------------------------------------------------------- 1 | class Foo { 2 | static int member; 3 | }; 4 | /* 5 | OUTPUT: 6 | { 7 | "includes": [], 8 | "skipped_by_preprocessor": [], 9 | "types": [{ 10 | "id": 0, 11 | "usr": 15041163540773201510, 12 | "detailed_name": "Foo", 13 | "short_name": "Foo", 14 | "kind": 5, 15 | "declarations": [], 16 | "spell": "1:7-1:10|-1|1|2", 17 | "extent": "1:1-3:2|-1|1|0", 18 | "bases": [], 19 | "derived": [], 20 | "types": [], 21 | "funcs": [], 22 | "vars": [], 23 | "instances": [], 24 | "uses": [] 25 | }, { 26 | "id": 1, 27 | "usr": 17, 28 | "detailed_name": "", 29 | "short_name": "", 30 | "kind": 0, 31 | "declarations": [], 32 | "bases": [], 33 | "derived": [], 34 | "types": [], 35 | "funcs": [], 36 | "vars": [], 37 | "instances": [0], 38 | "uses": [] 39 | }], 40 | "funcs": [], 41 | "vars": [{ 42 | "id": 0, 43 | "usr": 5844987037615239736, 44 | "detailed_name": "int Foo::member", 45 | "short_name": "member", 46 | "declarations": ["2:14-2:20|0|2|1"], 47 | "type": 1, 48 | "uses": [], 49 | "kind": 8, 50 | "storage": 3 51 | }] 52 | } 53 | */ 54 | -------------------------------------------------------------------------------- /index_tests/vars/deduce_auto_type.cc: -------------------------------------------------------------------------------- 1 | class Foo {}; 2 | void f() { 3 | auto x = new Foo(); 4 | auto* y = new Foo(); 5 | } 6 | 7 | /* 8 | OUTPUT: 9 | { 10 | "includes": [], 11 | "skipped_by_preprocessor": [], 12 | "types": [{ 13 | "id": 0, 14 | "usr": 15041163540773201510, 15 | "detailed_name": "Foo", 16 | "short_name": "Foo", 17 | "kind": 5, 18 | "declarations": [], 19 | "spell": "1:7-1:10|-1|1|2", 20 | "extent": "1:1-1:13|-1|1|0", 21 | "bases": [], 22 | "derived": [], 23 | "types": [], 24 | "funcs": [], 25 | "vars": [], 26 | "instances": [0, 1], 27 | "uses": ["3:16-3:19|-1|1|4", "4:17-4:20|-1|1|4"] 28 | }], 29 | "funcs": [{ 30 | "id": 0, 31 | "usr": 880549676430489861, 32 | "detailed_name": "void f()", 33 | "short_name": "f", 34 | "kind": 12, 35 | "storage": 1, 36 | "declarations": [], 37 | "spell": "2:6-2:7|-1|1|2", 38 | "extent": "2:1-5:2|-1|1|0", 39 | "bases": [], 40 | "derived": [], 41 | "vars": [0, 1], 42 | "uses": [], 43 | "callees": [] 44 | }], 45 | "vars": [{ 46 | "id": 0, 47 | "usr": 9275666070987716270, 48 | "detailed_name": "Foo *x", 49 | "short_name": "x", 50 | "declarations": [], 51 | "spell": "3:8-3:9|0|3|2", 52 | "extent": "3:3-3:21|0|3|0", 53 | "type": 0, 54 | "uses": [], 55 | "kind": 13, 56 | "storage": 1 57 | }, { 58 | "id": 1, 59 | "usr": 16202433437488621027, 60 | "detailed_name": "Foo *y", 61 | "short_name": "y", 62 | "declarations": [], 63 | "spell": "4:9-4:10|0|3|2", 64 | "extent": "4:3-4:22|0|3|0", 65 | "type": 0, 66 | "uses": [], 67 | "kind": 13, 68 | "storage": 1 69 | }] 70 | } 71 | */ 72 | -------------------------------------------------------------------------------- /index_tests/vars/function_local.cc: -------------------------------------------------------------------------------- 1 | struct Foo; 2 | 3 | void foo() { 4 | Foo* a; 5 | } 6 | 7 | /* 8 | OUTPUT: 9 | { 10 | "includes": [], 11 | "skipped_by_preprocessor": [], 12 | "types": [{ 13 | "id": 0, 14 | "usr": 15041163540773201510, 15 | "detailed_name": "Foo", 16 | "short_name": "Foo", 17 | "kind": 23, 18 | "declarations": ["1:8-1:11|-1|1|1"], 19 | "bases": [], 20 | "derived": [], 21 | "types": [], 22 | "funcs": [], 23 | "vars": [], 24 | "instances": [0], 25 | "uses": ["4:3-4:6|-1|1|4"] 26 | }], 27 | "funcs": [{ 28 | "id": 0, 29 | "usr": 4259594751088586730, 30 | "detailed_name": "void foo()", 31 | "short_name": "foo", 32 | "kind": 12, 33 | "storage": 1, 34 | "declarations": [], 35 | "spell": "3:6-3:9|-1|1|2", 36 | "extent": "3:1-5:2|-1|1|0", 37 | "bases": [], 38 | "derived": [], 39 | "vars": [0], 40 | "uses": [], 41 | "callees": [] 42 | }], 43 | "vars": [{ 44 | "id": 0, 45 | "usr": 10782632605670042066, 46 | "detailed_name": "Foo *a", 47 | "short_name": "a", 48 | "declarations": [], 49 | "spell": "4:8-4:9|0|3|2", 50 | "extent": "4:3-4:9|0|3|0", 51 | "type": 0, 52 | "uses": [], 53 | "kind": 13, 54 | "storage": 1 55 | }] 56 | } 57 | */ 58 | -------------------------------------------------------------------------------- /index_tests/vars/function_param.cc: -------------------------------------------------------------------------------- 1 | struct Foo; 2 | 3 | void foo(Foo* p0, Foo* p1) {} 4 | 5 | /* 6 | OUTPUT: 7 | { 8 | "includes": [], 9 | "skipped_by_preprocessor": [], 10 | "types": [{ 11 | "id": 0, 12 | "usr": 15041163540773201510, 13 | "detailed_name": "Foo", 14 | "short_name": "Foo", 15 | "kind": 23, 16 | "declarations": ["1:8-1:11|-1|1|1"], 17 | "bases": [], 18 | "derived": [], 19 | "types": [], 20 | "funcs": [], 21 | "vars": [], 22 | "instances": [0, 1], 23 | "uses": ["3:10-3:13|-1|1|4", "3:19-3:22|-1|1|4"] 24 | }], 25 | "funcs": [{ 26 | "id": 0, 27 | "usr": 8908726657907936744, 28 | "detailed_name": "void foo(Foo *p0, Foo *p1)", 29 | "short_name": "foo", 30 | "kind": 12, 31 | "storage": 1, 32 | "declarations": [], 33 | "spell": "3:6-3:9|-1|1|2", 34 | "extent": "3:1-3:30|-1|1|0", 35 | "bases": [], 36 | "derived": [], 37 | "vars": [0, 1], 38 | "uses": [], 39 | "callees": [] 40 | }], 41 | "vars": [{ 42 | "id": 0, 43 | "usr": 4580260577538694711, 44 | "detailed_name": "Foo *p0", 45 | "short_name": "p0", 46 | "declarations": [], 47 | "spell": "3:15-3:17|0|3|2", 48 | "extent": "3:10-3:17|0|3|0", 49 | "type": 0, 50 | "uses": [], 51 | "kind": 253, 52 | "storage": 1 53 | }, { 54 | "id": 1, 55 | "usr": 12071725611268840435, 56 | "detailed_name": "Foo *p1", 57 | "short_name": "p1", 58 | "declarations": [], 59 | "spell": "3:24-3:26|0|3|2", 60 | "extent": "3:19-3:26|0|3|0", 61 | "type": 0, 62 | "uses": [], 63 | "kind": 253, 64 | "storage": 1 65 | }] 66 | } 67 | */ 68 | -------------------------------------------------------------------------------- /index_tests/vars/function_param_unnamed.cc: -------------------------------------------------------------------------------- 1 | void foo(int, int) {} 2 | /* 3 | OUTPUT: 4 | { 5 | "includes": [], 6 | "skipped_by_preprocessor": [], 7 | "types": [], 8 | "funcs": [{ 9 | "id": 0, 10 | "usr": 2747674671862363334, 11 | "detailed_name": "void foo(int, int)", 12 | "short_name": "foo", 13 | "kind": 12, 14 | "storage": 1, 15 | "declarations": [], 16 | "spell": "1:6-1:9|-1|1|2", 17 | "extent": "1:1-1:22|-1|1|0", 18 | "bases": [], 19 | "derived": [], 20 | "vars": [], 21 | "uses": [], 22 | "callees": [] 23 | }], 24 | "vars": [] 25 | } 26 | */ 27 | -------------------------------------------------------------------------------- /index_tests/vars/function_shadow_local.cc: -------------------------------------------------------------------------------- 1 | void foo() { 2 | int a; 3 | a = 1; 4 | { 5 | int a; 6 | a = 2; 7 | } 8 | a = 3; 9 | } 10 | /* 11 | OUTPUT: 12 | { 13 | "includes": [], 14 | "skipped_by_preprocessor": [], 15 | "types": [{ 16 | "id": 0, 17 | "usr": 17, 18 | "detailed_name": "", 19 | "short_name": "", 20 | "kind": 0, 21 | "declarations": [], 22 | "bases": [], 23 | "derived": [], 24 | "types": [], 25 | "funcs": [], 26 | "vars": [], 27 | "instances": [0, 1], 28 | "uses": [] 29 | }], 30 | "funcs": [{ 31 | "id": 0, 32 | "usr": 4259594751088586730, 33 | "detailed_name": "void foo()", 34 | "short_name": "foo", 35 | "kind": 12, 36 | "storage": 1, 37 | "declarations": [], 38 | "spell": "1:6-1:9|-1|1|2", 39 | "extent": "1:1-9:2|-1|1|0", 40 | "bases": [], 41 | "derived": [], 42 | "vars": [0, 1], 43 | "uses": [], 44 | "callees": [] 45 | }], 46 | "vars": [{ 47 | "id": 0, 48 | "usr": 3440226937504376525, 49 | "detailed_name": "int a", 50 | "short_name": "a", 51 | "declarations": [], 52 | "spell": "2:7-2:8|0|3|2", 53 | "extent": "2:3-2:8|0|3|0", 54 | "type": 0, 55 | "uses": ["3:3-3:4|0|3|20", "8:3-8:4|0|3|20"], 56 | "kind": 13, 57 | "storage": 1 58 | }, { 59 | "id": 1, 60 | "usr": 14700715011944976607, 61 | "detailed_name": "int a", 62 | "short_name": "a", 63 | "declarations": [], 64 | "spell": "5:9-5:10|0|3|2", 65 | "extent": "5:5-5:10|0|3|0", 66 | "type": 0, 67 | "uses": ["6:5-6:6|0|3|20"], 68 | "kind": 13, 69 | "storage": 1 70 | }] 71 | } 72 | */ 73 | -------------------------------------------------------------------------------- /index_tests/vars/function_shadow_param.cc: -------------------------------------------------------------------------------- 1 | void foo(int p) { 2 | { int p = 0; } 3 | } 4 | /* 5 | OUTPUT: 6 | { 7 | "includes": [], 8 | "skipped_by_preprocessor": [], 9 | "types": [{ 10 | "id": 0, 11 | "usr": 17, 12 | "detailed_name": "", 13 | "short_name": "", 14 | "kind": 0, 15 | "declarations": [], 16 | "bases": [], 17 | "derived": [], 18 | "types": [], 19 | "funcs": [], 20 | "vars": [], 21 | "instances": [0, 1], 22 | "uses": [] 23 | }], 24 | "funcs": [{ 25 | "id": 0, 26 | "usr": 11998306017310352355, 27 | "detailed_name": "void foo(int p)", 28 | "short_name": "foo", 29 | "kind": 12, 30 | "storage": 1, 31 | "declarations": [], 32 | "spell": "1:6-1:9|-1|1|2", 33 | "extent": "1:1-3:2|-1|1|0", 34 | "bases": [], 35 | "derived": [], 36 | "vars": [0, 1], 37 | "uses": [], 38 | "callees": [] 39 | }], 40 | "vars": [{ 41 | "id": 0, 42 | "usr": 5875271969926422921, 43 | "detailed_name": "int p", 44 | "short_name": "p", 45 | "declarations": [], 46 | "spell": "1:14-1:15|0|3|2", 47 | "extent": "1:10-1:15|0|3|0", 48 | "type": 0, 49 | "uses": [], 50 | "kind": 253, 51 | "storage": 1 52 | }, { 53 | "id": 1, 54 | "usr": 2147918703972955240, 55 | "detailed_name": "int p", 56 | "short_name": "p", 57 | "hover": "int p = 0", 58 | "declarations": [], 59 | "spell": "2:9-2:10|0|3|2", 60 | "extent": "2:5-2:14|0|3|0", 61 | "type": 0, 62 | "uses": [], 63 | "kind": 13, 64 | "storage": 1 65 | }] 66 | } 67 | */ 68 | -------------------------------------------------------------------------------- /index_tests/vars/global_variable.cc: -------------------------------------------------------------------------------- 1 | static int global = 0; 2 | /* 3 | OUTPUT: 4 | { 5 | "includes": [], 6 | "skipped_by_preprocessor": [], 7 | "types": [{ 8 | "id": 0, 9 | "usr": 17, 10 | "detailed_name": "", 11 | "short_name": "", 12 | "kind": 0, 13 | "declarations": [], 14 | "bases": [], 15 | "derived": [], 16 | "types": [], 17 | "funcs": [], 18 | "vars": [], 19 | "instances": [0], 20 | "uses": [] 21 | }], 22 | "funcs": [], 23 | "vars": [{ 24 | "id": 0, 25 | "usr": 6834525061342585382, 26 | "detailed_name": "int global", 27 | "short_name": "global", 28 | "hover": "int global = 0", 29 | "declarations": [], 30 | "spell": "1:12-1:18|-1|1|2", 31 | "extent": "1:1-1:22|-1|1|0", 32 | "type": 0, 33 | "uses": [], 34 | "kind": 13, 35 | "storage": 3 36 | }] 37 | } 38 | */ 39 | -------------------------------------------------------------------------------- /index_tests/vars/global_variable_decl_only.cc: -------------------------------------------------------------------------------- 1 | extern int global; 2 | /* 3 | OUTPUT: 4 | { 5 | "includes": [], 6 | "skipped_by_preprocessor": [], 7 | "types": [{ 8 | "id": 0, 9 | "usr": 17, 10 | "detailed_name": "", 11 | "short_name": "", 12 | "kind": 0, 13 | "declarations": [], 14 | "bases": [], 15 | "derived": [], 16 | "types": [], 17 | "funcs": [], 18 | "vars": [], 19 | "instances": [0], 20 | "uses": [] 21 | }], 22 | "funcs": [], 23 | "vars": [{ 24 | "id": 0, 25 | "usr": 9937941849651546906, 26 | "detailed_name": "int global", 27 | "short_name": "global", 28 | "declarations": ["1:12-1:18|-1|1|1"], 29 | "type": 0, 30 | "uses": [], 31 | "kind": 13, 32 | "storage": 2 33 | }] 34 | } 35 | */ 36 | -------------------------------------------------------------------------------- /index_tests/vars/type_instance_on_using_type.cc: -------------------------------------------------------------------------------- 1 | struct S {}; 2 | using F = S; 3 | void Foo() { 4 | F a; 5 | } 6 | 7 | // TODO: Should we also add a usage to |S|? 8 | 9 | /* 10 | OUTPUT: 11 | { 12 | "includes": [], 13 | "skipped_by_preprocessor": [], 14 | "types": [{ 15 | "id": 0, 16 | "usr": 4750332761459066907, 17 | "detailed_name": "S", 18 | "short_name": "S", 19 | "kind": 23, 20 | "declarations": [], 21 | "spell": "1:8-1:9|-1|1|2", 22 | "extent": "1:1-1:12|-1|1|0", 23 | "bases": [], 24 | "derived": [], 25 | "types": [], 26 | "funcs": [], 27 | "vars": [], 28 | "instances": [], 29 | "uses": ["2:11-2:12|-1|1|4"] 30 | }, { 31 | "id": 1, 32 | "usr": 7434820806199665424, 33 | "detailed_name": "F", 34 | "short_name": "F", 35 | "kind": 252, 36 | "hover": "using F = S", 37 | "declarations": [], 38 | "spell": "2:7-2:8|-1|1|2", 39 | "extent": "2:1-2:12|-1|1|0", 40 | "alias_of": 0, 41 | "bases": [], 42 | "derived": [], 43 | "types": [], 44 | "funcs": [], 45 | "vars": [], 46 | "instances": [0], 47 | "uses": ["2:7-2:8|-1|1|4", "4:3-4:4|-1|1|4"] 48 | }], 49 | "funcs": [{ 50 | "id": 0, 51 | "usr": 4654328188330986029, 52 | "detailed_name": "void Foo()", 53 | "short_name": "Foo", 54 | "kind": 12, 55 | "storage": 1, 56 | "declarations": [], 57 | "spell": "3:6-3:9|-1|1|2", 58 | "extent": "3:1-5:2|-1|1|0", 59 | "bases": [], 60 | "derived": [], 61 | "vars": [0], 62 | "uses": [], 63 | "callees": [] 64 | }], 65 | "vars": [{ 66 | "id": 0, 67 | "usr": 7730100248624586522, 68 | "detailed_name": "F a", 69 | "short_name": "a", 70 | "declarations": [], 71 | "spell": "4:5-4:6|0|3|2", 72 | "extent": "4:3-4:6|0|3|0", 73 | "type": 1, 74 | "uses": [], 75 | "kind": 13, 76 | "storage": 1 77 | }] 78 | } 79 | */ 80 | -------------------------------------------------------------------------------- /publish.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # This script tags the current commit with the current date and pushes it to 4 | # GitHub. This will then trigger CI which will build the release and publish 5 | # binaries. 6 | 7 | import datetime 8 | import subprocess 9 | import sys 10 | 11 | def RunOrExit(args): 12 | if subprocess.call(args) != 0: 13 | sys.exit(1) 14 | 15 | if __name__ == "__main__": 16 | # Example: v2018-01-13@1820 17 | tag_name = datetime.datetime.now().strftime('v%F@%H%M') 18 | RunOrExit(['git', 'tag', tag_name]) 19 | RunOrExit(['git', 'push', 'origin', tag_name]) 20 | -------------------------------------------------------------------------------- /src/atomic_object.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // A object which can be stored and taken from atomically. 9 | template 10 | struct AtomicObject { 11 | void Set(std::unique_ptr t) { 12 | std::lock_guard lock(mutex_); 13 | value_ = std::move(t); 14 | cv_.notify_one(); 15 | } 16 | 17 | void SetIfEmpty(std::unique_ptr t) { 18 | std::lock_guard lock(mutex_); 19 | if (value_) 20 | return; 21 | 22 | value_ = std::move(t); 23 | cv_.notify_one(); 24 | } 25 | 26 | std::unique_ptr Take() { 27 | std::unique_lock lock(mutex_); 28 | while (!value_) { 29 | // release lock as long as the wait and reaquire it afterwards. 30 | cv_.wait(lock); 31 | } 32 | 33 | return std::move(value_); 34 | } 35 | 36 | template 37 | void WithLock(TAction action) { 38 | std::unique_lock lock(mutex_); 39 | bool had_value = !!value_; 40 | action(value_); 41 | bool has_value = !!value_; 42 | 43 | if (had_value != has_value) 44 | cv_.notify_one(); 45 | } 46 | 47 | private: 48 | std::unique_ptr value_; 49 | mutable std::mutex mutex_; 50 | std::condition_variable cv_; 51 | }; -------------------------------------------------------------------------------- /src/c_cpp_properties.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "optional.h" 7 | 8 | struct CCppProperties { 9 | std::string cStandard; 10 | std::string cppStandard; 11 | std::vector args; 12 | }; 13 | 14 | optional LoadCCppProperties(const std::string& json_full_path, 15 | const std::string& project_dir); 16 | -------------------------------------------------------------------------------- /src/cache_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | struct Config; 12 | struct IndexFile; 13 | 14 | struct ICacheManager { 15 | struct FakeCacheEntry { 16 | std::string path; 17 | std::string content; 18 | std::string json; 19 | }; 20 | 21 | static std::shared_ptr Make(); 22 | static std::shared_ptr MakeFake( 23 | const std::vector& entries); 24 | 25 | virtual ~ICacheManager(); 26 | 27 | // Tries to load a cache for |path|, returning null if there is none. The 28 | // cache loader still owns the cache. 29 | IndexFile* TryLoad(const std::string& path); 30 | 31 | // Takes the existing cache or loads the cache at |path|. May return null if 32 | // the cache does not exist. 33 | std::unique_ptr TryTakeOrLoad(const std::string& path); 34 | 35 | // Takes the existing cache or loads the cache at |path|. Asserts the cache 36 | // exists. 37 | std::unique_ptr TakeOrLoad(const std::string& path); 38 | 39 | virtual void WriteToCache(IndexFile& file) = 0; 40 | 41 | virtual optional LoadCachedFileContents( 42 | const std::string& path) = 0; 43 | 44 | // Iterate over all loaded caches. 45 | void IterateLoadedCaches(std::function fn); 46 | 47 | protected: 48 | virtual std::unique_ptr RawCacheLoad(const std::string& path) = 0; 49 | std::unordered_map> caches_; 50 | }; 51 | -------------------------------------------------------------------------------- /src/clang_format.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "lsp.h" 4 | 5 | #include 6 | #include 7 | 8 | std::vector RunClangFormat(const std::string& filename, 9 | const std::string& file_contents, 10 | optional start_offset, 11 | optional end_offset); -------------------------------------------------------------------------------- /src/clang_index.cc: -------------------------------------------------------------------------------- 1 | #include "clang_index.h" 2 | 3 | #include 4 | 5 | ClangIndex::ClangIndex() : ClangIndex(1, 0) {} 6 | 7 | ClangIndex::ClangIndex(int exclude_declarations_from_pch, 8 | int display_diagnostics) { 9 | // llvm::InitializeAllTargets (and possibly others) called by 10 | // clang_createIndex transtively modifies/reads lib/Support/TargetRegistry.cpp 11 | // FirstTarget. There will be a race condition if two threads call 12 | // clang_createIndex concurrently. 13 | static std::mutex mutex_; 14 | std::lock_guard lock(mutex_); 15 | 16 | cx_index = 17 | clang_createIndex(exclude_declarations_from_pch, display_diagnostics); 18 | } 19 | 20 | ClangIndex::~ClangIndex() { 21 | clang_disposeIndex(cx_index); 22 | } 23 | -------------------------------------------------------------------------------- /src/clang_index.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | // Simple RAII wrapper about CXIndex. 6 | // Note: building a ClangIndex instance acquires a global lock, since libclang 7 | // API does not appear to be thread-safe here. 8 | class ClangIndex { 9 | public: 10 | ClangIndex(); 11 | ClangIndex(int exclude_declarations_from_pch, int display_diagnostics); 12 | ~ClangIndex(); 13 | CXIndex cx_index; 14 | }; 15 | -------------------------------------------------------------------------------- /src/clang_system_include_extractor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | // Run clang specified by `clang_binaries` and return the set of system includes 7 | // it uses. 8 | // 9 | // If the first entry in `clang_binaries` fails, the second is tried, and 10 | // so-forth, until one succeeds. 11 | std::vector FindSystemIncludeDirectories( 12 | const std::vector& compiler_drivers, 13 | const std::string& language, 14 | const std::string& working_directory, 15 | const std::vector& extra_flags); 16 | 17 | std::vector FindSystemDefines( 18 | const std::vector& compiler_drivers, 19 | const std::string& language, 20 | const std::string& working_directory, 21 | const std::vector& extra_flags); 22 | -------------------------------------------------------------------------------- /src/clang_translation_unit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "clang_cursor.h" 4 | #include "clang_index.h" 5 | #include "file_types.h" 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | // RAII wrapper around CXTranslationUnit which also makes it much more 14 | // challenging to use a CXTranslationUnit instance that is not correctly 15 | // initialized. 16 | struct ClangTranslationUnit { 17 | static std::unique_ptr Create( 18 | ClangIndex* index, 19 | const AbsolutePath& filepath, 20 | const std::vector& arguments, 21 | std::vector& unsaved_files, 22 | unsigned flags); 23 | 24 | static std::unique_ptr Reparse( 25 | std::unique_ptr tu, 26 | std::vector& unsaved); 27 | 28 | explicit ClangTranslationUnit(CXTranslationUnit tu); 29 | ~ClangTranslationUnit(); 30 | 31 | CXTranslationUnit cx_tu; 32 | }; -------------------------------------------------------------------------------- /src/clang_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "lsp_diagnostic.h" 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | // Builds an lsDiagnostic instance, but only if |path| matches the diagnostic 11 | // path. 12 | optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, 13 | const AbsolutePath& path); 14 | 15 | // Returns the absolute path to |file|. 16 | optional FileName(CXFile file); 17 | 18 | std::string ToString(CXString cx_string); 19 | 20 | std::string ToString(CXCursorKind cursor_kind); 21 | 22 | const char* ClangBuiltinTypeName(CXTypeKind); -------------------------------------------------------------------------------- /src/code_complete_cache.cc: -------------------------------------------------------------------------------- 1 | #include "code_complete_cache.h" 2 | 3 | void CodeCompleteCache::WithLock(std::function action) { 4 | std::lock_guard lock(mutex_); 5 | action(); 6 | } 7 | 8 | bool CodeCompleteCache::IsCacheValid(lsTextDocumentPositionParams position) { 9 | std::lock_guard lock(mutex_); 10 | return cached_path_ == position.textDocument.uri.GetAbsolutePath() && 11 | cached_completion_position_ == position.position; 12 | } 13 | 14 | void CodeCompleteCache::Clear() { 15 | std::lock_guard lock(mutex_); 16 | cached_path_.reset(); 17 | cached_completion_position_.reset(); 18 | cached_results_.clear(); 19 | } -------------------------------------------------------------------------------- /src/code_complete_cache.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "lsp_completion.h" 4 | 5 | #include 6 | 7 | #include 8 | 9 | // Cached completion information, so we can give fast completion results when 10 | // the user erases a character. vscode will resend the completion request if 11 | // that happens. 12 | struct CodeCompleteCache { 13 | // NOTE: Make sure to access these variables under |WithLock|. 14 | optional cached_path_; 15 | optional cached_completion_position_; 16 | std::vector cached_results_; 17 | 18 | std::mutex mutex_; 19 | 20 | void WithLock(std::function action); 21 | bool IsCacheValid(lsTextDocumentPositionParams position); 22 | void Clear(); 23 | }; 24 | -------------------------------------------------------------------------------- /src/compiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | // Used to identify the compiler type. 7 | enum class CompilerType { 8 | Unknown = 0, 9 | Clang = 1, 10 | GCC = 2, 11 | MSVC = 3, 12 | }; 13 | 14 | // Find out the compiler type for the specific driver. 15 | CompilerType FindCompilerType(const std::string& compiler_driver); 16 | 17 | // Whether the compiler accepts certain flag. 18 | bool CompilerAcceptsFlag(CompilerType compiler_type, const std::string& flag); 19 | 20 | // Append flag if the compiler accepts it. 21 | void CompilerAppendsFlagIfAccept(CompilerType compiler_type, 22 | const std::string& flag, 23 | std::vector& flags); 24 | -------------------------------------------------------------------------------- /src/diagnostics_engine.cc: -------------------------------------------------------------------------------- 1 | #include "diagnostics_engine.h" 2 | 3 | #include "queue_manager.h" 4 | 5 | #include 6 | 7 | void DiagnosticsEngine::Init() { 8 | frequencyMs_ = g_config->diagnostics.frequencyMs; 9 | match_ = std::make_unique(g_config->diagnostics.whitelist, 10 | g_config->diagnostics.blacklist); 11 | } 12 | 13 | void DiagnosticsEngine::Publish(WorkingFiles* working_files, 14 | std::string path, 15 | std::vector diagnostics) { 16 | // Cache diagnostics so we can show fixits. 17 | working_files->DoActionOnFile(path, [&](WorkingFile* working_file) { 18 | if (working_file) 19 | working_file->diagnostics_ = diagnostics; 20 | }); 21 | 22 | int64_t now = 23 | std::chrono::duration_cast( 24 | std::chrono::high_resolution_clock::now().time_since_epoch()) 25 | .count(); 26 | if (frequencyMs_ >= 0 && (nextPublish_ <= now || diagnostics.empty()) && 27 | match_->IsMatch(path)) { 28 | nextPublish_ = now + frequencyMs_; 29 | 30 | Out_TextDocumentPublishDiagnostics out; 31 | out.params.uri = lsDocumentUri::FromPath(path); 32 | out.params.diagnostics = diagnostics; 33 | QueueManager::WriteStdout(kMethodType_TextDocumentPublishDiagnostics, out); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/diagnostics_engine.h: -------------------------------------------------------------------------------- 1 | #include "lsp_diagnostic.h" 2 | 3 | #include "match.h" 4 | #include "working_files.h" 5 | 6 | struct DiagnosticsEngine { 7 | void Init(); 8 | void Publish(WorkingFiles* working_files, 9 | std::string path, 10 | std::vector diagnostics); 11 | 12 | std::unique_ptr match_; 13 | int64_t nextPublish_ = 0; 14 | int frequencyMs_; 15 | }; 16 | -------------------------------------------------------------------------------- /src/file_consumer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "file_contents.h" 4 | #include "utils.h" 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | struct IndexFile; 14 | 15 | // Needed for unordered_map usage below. 16 | MAKE_HASHABLE(CXFileUniqueID, t.data[0], t.data[1], t.data[2]); 17 | bool operator==(const CXFileUniqueID& a, const CXFileUniqueID& b); 18 | 19 | struct FileConsumerSharedState { 20 | mutable std::unordered_set used_files; 21 | mutable std::mutex mutex; 22 | 23 | // Mark the file as used. Returns true if the file was not previously used. 24 | bool Mark(const std::string& file); 25 | // Reset the used state (ie, mark the file as unused). 26 | void Reset(const std::string& file); 27 | }; 28 | 29 | // FileConsumer is used by the indexer. When it encouters a file, it tries to 30 | // take ownership over it. If the indexer has ownership over a file, it will 31 | // produce an index, otherwise, it will emit nothing for that declarations 32 | // and references coming from that file. 33 | // 34 | // The indexer does this because header files do not have their own translation 35 | // units but we still want to index them. 36 | struct FileConsumer { 37 | FileConsumer(FileConsumerSharedState* shared_state, 38 | const AbsolutePath& parse_file); 39 | 40 | // Returns true if this instance owns given |file|. This will also attempt to 41 | // take ownership over |file|. 42 | // 43 | // Returns IndexFile for the file or nullptr. |is_first_ownership| is set 44 | // to true iff the function just took ownership over the file. Otherwise it 45 | // is set to false. 46 | // 47 | // note: file_contents is passed as a parameter instead of as a member 48 | // variable since it is large and we do not want to copy it. 49 | IndexFile* TryConsumeFile(CXFile file, 50 | bool* is_first_ownership); 51 | 52 | // Returns and passes ownership of all local state. 53 | std::vector> TakeLocalState(); 54 | 55 | private: 56 | void EmitError(CXFile file) const; 57 | 58 | std::unordered_map> local_; 59 | FileConsumerSharedState* shared_; 60 | AbsolutePath parse_file_; 61 | }; -------------------------------------------------------------------------------- /src/file_contents.cc: -------------------------------------------------------------------------------- 1 | #include "file_contents.h" 2 | 3 | FileContents::FileContents() : line_offsets_{0} {} 4 | 5 | FileContents::FileContents(const AbsolutePath& path, const std::string& content) 6 | : path(path), content(content) { 7 | line_offsets_.push_back(0); 8 | for (size_t i = 0; i < content.size(); i++) { 9 | if (content[i] == '\n') 10 | line_offsets_.push_back(i + 1); 11 | } 12 | } 13 | 14 | optional FileContents::ToOffset(Position p) const { 15 | if (0 <= p.line && size_t(p.line) < line_offsets_.size()) { 16 | int ret = line_offsets_[p.line] + p.column; 17 | if (size_t(ret) < content.size()) 18 | return ret; 19 | } 20 | return nullopt; 21 | } 22 | 23 | optional FileContents::ContentsInRange(Range range) const { 24 | optional start_offset = ToOffset(range.start), 25 | end_offset = ToOffset(range.end); 26 | if (start_offset && end_offset && *start_offset < *end_offset) 27 | return content.substr(*start_offset, *end_offset - *start_offset); 28 | return nullopt; 29 | } 30 | -------------------------------------------------------------------------------- /src/file_contents.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "position.h" 4 | 5 | #include "optional.h" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | struct FileContents { 12 | FileContents(); 13 | FileContents(const AbsolutePath& path, const std::string& content); 14 | 15 | optional ToOffset(Position p) const; 16 | optional ContentsInRange(Range range) const; 17 | 18 | AbsolutePath path; 19 | std::string content; 20 | // {0, 1 + position of first newline, 1 + position of second newline, ...} 21 | std::vector line_offsets_; 22 | }; 23 | -------------------------------------------------------------------------------- /src/file_types.cc: -------------------------------------------------------------------------------- 1 | #include "file_types.h" 2 | 3 | #include "platform.h" 4 | #include "utils.h" 5 | 6 | #include 7 | 8 | // static 9 | AbsolutePath AbsolutePath::BuildDoNotUse(std::string_view path) { 10 | AbsolutePath p; 11 | p.path = std::string(path); 12 | return p; 13 | } 14 | 15 | AbsolutePath::AbsolutePath() {} 16 | 17 | AbsolutePath::AbsolutePath(const std::string& path, bool validate) 18 | : path(path) { 19 | // TODO: enable validation after fixing tests. 20 | validate = false; 21 | if (validate && !IsAbsolutePath(path)) { 22 | loguru::Text stack = loguru::stacktrace(); 23 | LOG_S(ERROR) << "Expected " << path << " to be absolute\n" << stack.c_str(); 24 | } 25 | } 26 | 27 | AbsolutePath::operator std::string() const { 28 | return path; 29 | } 30 | 31 | bool AbsolutePath::operator==(const AbsolutePath& rhs) const { 32 | return path == rhs.path; 33 | } 34 | 35 | bool AbsolutePath::operator!=(const AbsolutePath& rhs) const { 36 | return path != rhs.path; 37 | } 38 | 39 | void Reflect(Reader& visitor, AbsolutePath& value) { 40 | value.path = visitor.GetString(); 41 | } 42 | void Reflect(Writer& visitor, AbsolutePath& value) { 43 | visitor.String(value.path.c_str(), value.path.length()); 44 | } 45 | 46 | std::ostream& operator<<(std::ostream& out, const AbsolutePath& path) { 47 | out << path.path; 48 | return out; 49 | } 50 | 51 | Directory::Directory(const AbsolutePath& path) : path(path.path) { 52 | EnsureEndsInSlash(this->path); 53 | } 54 | 55 | bool Directory::operator==(const Directory& rhs) const { 56 | return path == rhs.path; 57 | } 58 | 59 | bool Directory::operator!=(const Directory& rhs) const { 60 | return path != rhs.path; 61 | } -------------------------------------------------------------------------------- /src/file_types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hash_utils.h" 4 | #include "serializer.h" 5 | 6 | #include 7 | #include 8 | 9 | struct AbsolutePath { 10 | static AbsolutePath BuildDoNotUse(std::string_view path); 11 | 12 | // Try not to use this. 13 | AbsolutePath(); 14 | 15 | // Provide implicit conversions to std::string for the time being. 16 | AbsolutePath(const std::string& path, bool validate = true); 17 | operator std::string() const; 18 | 19 | bool operator==(const AbsolutePath& rhs) const; 20 | bool operator!=(const AbsolutePath& rhs) const; 21 | 22 | std::string path; 23 | }; 24 | MAKE_HASHABLE(AbsolutePath, t.path); 25 | 26 | void Reflect(Reader& visitor, AbsolutePath& value); 27 | void Reflect(Writer& visitor, AbsolutePath& value); 28 | 29 | std::ostream& operator<<(std::ostream& out, const AbsolutePath& path); 30 | 31 | struct Directory { 32 | explicit Directory(const AbsolutePath& path); 33 | 34 | bool operator==(const Directory& rhs) const; 35 | bool operator!=(const Directory& rhs) const; 36 | 37 | std::string path; 38 | }; 39 | MAKE_HASHABLE(Directory, t.path); -------------------------------------------------------------------------------- /src/fuzzy_match.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | class FuzzyMatcher { 9 | public: 10 | constexpr static int kMaxPat = 100; 11 | constexpr static int kMaxText = 200; 12 | // Negative but far from INT_MIN so that intermediate results are hard to 13 | // overflow. 14 | constexpr static int kMinScore = INT_MIN / 4; 15 | 16 | FuzzyMatcher(std::string_view pattern); 17 | int Match(std::string_view text); 18 | 19 | private: 20 | std::string pat; 21 | std::string_view text; 22 | int pat_set, text_set; 23 | char low_pat[kMaxPat], low_text[kMaxText]; 24 | int pat_role[kMaxPat], text_role[kMaxText]; 25 | int dp[2][kMaxText + 1][2]; 26 | 27 | int MatchScore(int i, int j, bool last); 28 | int MissScore(int j, bool last); 29 | }; 30 | -------------------------------------------------------------------------------- /src/hash_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | // http://stackoverflow.com/a/38140932 6 | // 7 | // struct SomeHashKey { 8 | // std::string key1; 9 | // std::string key2; 10 | // bool key3; 11 | // }; 12 | // MAKE_HASHABLE(SomeHashKey, t.key1, t.key2, t.key3) 13 | 14 | inline void hash_combine(std::size_t& seed) {} 15 | 16 | template 17 | inline void hash_combine(std::size_t& seed, const T& v, Rest... rest) { 18 | std::hash hasher; 19 | seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 20 | hash_combine(seed, rest...); 21 | } 22 | 23 | #define MAKE_HASHABLE(type, ...) \ 24 | namespace std { \ 25 | template <> \ 26 | struct hash { \ 27 | std::size_t operator()(const type& t) const { \ 28 | std::size_t ret = 0; \ 29 | hash_combine(ret, __VA_ARGS__); \ 30 | return ret; \ 31 | } \ 32 | }; \ 33 | } 34 | 35 | #define MAKE_ENUM_HASHABLE(type) \ 36 | namespace std { \ 37 | template <> \ 38 | struct hash { \ 39 | std::size_t operator()(const type& t) const { \ 40 | return hash()(static_cast(t)); \ 41 | } \ 42 | }; \ 43 | } 44 | -------------------------------------------------------------------------------- /src/iindexer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | // TODO: 11 | // - rename indexer.h to clang_indexer.h and pull out non-clang specific code 12 | // like IndexFile 13 | // - rename this file to indexer.h 14 | 15 | struct Config; 16 | struct IndexFile; 17 | struct FileContents; 18 | struct FileConsumerSharedState; 19 | 20 | // Abstracts away the actual indexing process. Each IIndexer instance is 21 | // per-thread and constructing an instance may be extremely expensive (ie, 22 | // acquire a lock) and should be done as rarely as possible. 23 | struct IIndexer { 24 | struct TestEntry { 25 | std::string path; 26 | int num_indexes = 0; 27 | 28 | TestEntry(const std::string& path, int num_indexes); 29 | }; 30 | 31 | static std::unique_ptr MakeClangIndexer(); 32 | static std::unique_ptr MakeTestIndexer( 33 | std::initializer_list entries); 34 | 35 | virtual ~IIndexer() = default; 36 | virtual optional>> Index( 37 | FileConsumerSharedState* file_consumer_shared, 38 | std::string file, 39 | const std::vector& args, 40 | const std::vector& file_contents) = 0; 41 | }; 42 | -------------------------------------------------------------------------------- /src/import_manager.cc: -------------------------------------------------------------------------------- 1 | #include "import_manager.h" 2 | 3 | #include "assert.h" 4 | 5 | #include 6 | 7 | std::ostream& operator<<(std::ostream& os, const PipelineStatus& status) { 8 | switch (status) { 9 | case PipelineStatus::kNotSeen: 10 | os << "kNotSeen"; 11 | break; 12 | case PipelineStatus::kProcessingInitialImport: 13 | os << "kProcessingInitialImport"; 14 | break; 15 | case PipelineStatus::kImported: 16 | os << "kImported"; 17 | break; 18 | case PipelineStatus::kProcessingUpdate: 19 | os << "kProcessingUpdate"; 20 | break; 21 | default: 22 | assert(false); 23 | } 24 | return os; 25 | } 26 | 27 | PipelineStatus ImportManager::GetStatus(const std::string& path) { 28 | // Try reading the value 29 | { 30 | std::shared_lock lock(status_mutex_); 31 | auto it = status_.find(path); 32 | if (it != status_.end()) 33 | return it->second; 34 | } 35 | return PipelineStatus::kNotSeen; 36 | } -------------------------------------------------------------------------------- /src/import_pipeline.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct DiagnosticsEngine; 6 | struct FileConsumerSharedState; 7 | struct ImportManager; 8 | struct Project; 9 | struct QueryDatabase; 10 | struct SemanticHighlightSymbolCache; 11 | struct TimestampManager; 12 | struct WorkingFiles; 13 | struct CodeCompleteCache; 14 | 15 | // FIXME: rename 16 | struct ImportPipelineStatus { 17 | std::atomic num_active_threads; 18 | std::atomic next_progress_output; 19 | 20 | ImportPipelineStatus(); 21 | }; 22 | 23 | void Indexer_Main(DiagnosticsEngine* diag_engine, 24 | FileConsumerSharedState* file_consumer_shared, 25 | TimestampManager* timestamp_manager, 26 | ImportManager* import_manager, 27 | ImportPipelineStatus* status, 28 | Project* project, 29 | WorkingFiles* working_files, 30 | CodeCompleteCache* global_code_complete_cache, 31 | CodeCompleteCache* non_global_code_complete_cache); 32 | 33 | bool QueryDb_ImportMain(QueryDatabase* db, 34 | ImportManager* import_manager, 35 | ImportPipelineStatus* status, 36 | SemanticHighlightSymbolCache* semantic_cache, 37 | WorkingFiles* working_files); 38 | -------------------------------------------------------------------------------- /src/include_complete.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "lsp_completion.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | struct GroupMatch; 10 | struct Project; 11 | 12 | struct IncludeComplete { 13 | IncludeComplete(Project* project); 14 | 15 | // Starts scanning directories. Clears existing cache. 16 | void Rescan(); 17 | 18 | // Ensures the one-off file is inside |completion_items|. 19 | void AddFile(const std::string& absolute_path); 20 | 21 | // Scans the given directory and inserts all includes from this. This is a 22 | // blocking function and should be run off the querydb thread. 23 | void InsertIncludesFromDirectory(std::string directory, 24 | bool use_angle_brackets); 25 | void InsertStlIncludes(); 26 | 27 | optional FindCompletionItemForAbsolutePath( 28 | const std::string& absolute_path); 29 | 30 | // Insert item to |completion_items|. 31 | // Update |absolute_path_to_completion_item| and |inserted_paths|. 32 | void InsertCompletionItem(const std::string& absolute_path, 33 | lsCompletionItem&& item); 34 | 35 | // Guards |completion_items| when |is_scanning| is true. 36 | std::mutex completion_items_mutex; 37 | std::atomic is_scanning; 38 | std::vector completion_items; 39 | 40 | // Absolute file path to the completion item in |completion_items|. 41 | // Keep the one with shortest include path. 42 | std::unordered_map absolute_path_to_completion_item; 43 | 44 | // Only one completion item per include path. 45 | std::unordered_map inserted_paths; 46 | 47 | // Cached references 48 | Project* project_; 49 | std::unique_ptr match_; 50 | }; 51 | -------------------------------------------------------------------------------- /src/language.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "serializer.h" 4 | 5 | // Used to identify the language at a file level. The ordering is important, as 6 | // a file previously identified as `C`, will be changed to `Cpp` if it 7 | // encounters a c++ declaration. 8 | enum class LanguageId { Unknown = 0, C = 1, Cpp = 2, ObjC = 3, ObjCpp = 4 }; 9 | MAKE_REFLECT_TYPE_PROXY(LanguageId); 10 | MAKE_ENUM_HASHABLE(LanguageId); 11 | -------------------------------------------------------------------------------- /src/lex_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "lsp.h" 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | // Utility method to map |position| to an offset inside of |content|. 11 | int GetOffsetForPosition(lsPosition position, std::string_view content); 12 | 13 | // Finds the position for an |offset| in |content|. 14 | lsPosition GetPositionForOffset(int offset, std::string_view content); 15 | 16 | // Utility method to find a position for the given character. 17 | lsPosition CharPos(std::string_view search, 18 | char character, 19 | int character_offset = 0); 20 | 21 | // TODO: eliminate |line_number| param. 22 | optional ExtractQuotedRange(int line_number, const std::string& line); 23 | 24 | void LexFunctionDeclaration(const std::string& buffer_content, 25 | lsPosition declaration_spelling, 26 | optional type_name, 27 | std::string* insert_text, 28 | int* newlines_after_name); 29 | 30 | std::string_view LexIdentifierAroundPos(lsPosition position, 31 | std::string_view content); 32 | 33 | std::pair CaseFoldingSubsequenceMatch(std::string_view search, 34 | std::string_view content); 35 | -------------------------------------------------------------------------------- /src/lsp_code_action.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "lsp.h" 4 | 5 | // codeAction 6 | struct CommandArgs { 7 | lsDocumentUri textDocumentUri; 8 | std::vector edits; 9 | }; 10 | MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(CommandArgs, textDocumentUri, edits); 11 | 12 | // codeLens 13 | struct lsCodeLensUserData {}; 14 | MAKE_REFLECT_EMPTY_STRUCT(lsCodeLensUserData); 15 | 16 | struct lsCodeLensCommandArguments { 17 | lsDocumentUri uri; 18 | lsPosition position; 19 | std::vector locations; 20 | }; 21 | 22 | // FIXME Don't use array in vscode-cquery 23 | inline void Reflect(Writer& visitor, lsCodeLensCommandArguments& value) { 24 | visitor.StartArray(3); 25 | Reflect(visitor, value.uri); 26 | Reflect(visitor, value.position); 27 | Reflect(visitor, value.locations); 28 | visitor.EndArray(); 29 | } 30 | 31 | inline void Reflect(Reader& visitor, lsCodeLensCommandArguments& value) { 32 | int i = 0; 33 | visitor.IterArray([&](Reader& visitor) { 34 | switch (i++) { 35 | case 0: 36 | Reflect(visitor, value.uri); 37 | break; 38 | case 1: 39 | Reflect(visitor, value.position); 40 | break; 41 | case 2: 42 | Reflect(visitor, value.locations); 43 | break; 44 | } 45 | }); 46 | } 47 | -------------------------------------------------------------------------------- /src/lsp_diagnostic.cc: -------------------------------------------------------------------------------- 1 | #include "lsp_diagnostic.h" 2 | 3 | bool lsDiagnostic::operator==(const lsDiagnostic& rhs) const { 4 | // Just check the important fields. 5 | return range == rhs.range && message == rhs.message; 6 | } 7 | bool lsDiagnostic::operator!=(const lsDiagnostic& rhs) const { 8 | return !(*this == rhs); 9 | } -------------------------------------------------------------------------------- /src/match.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | struct Matcher { 10 | static optional Create(const std::string& search); 11 | 12 | bool IsMatch(const std::string& value) const; 13 | 14 | std::string regex_string; 15 | std::regex regex; 16 | }; 17 | 18 | // Check multiple |Matcher| instances at the same time. 19 | struct GroupMatch { 20 | GroupMatch(const std::vector& whitelist, 21 | const std::vector& blacklist); 22 | 23 | bool IsMatch(const std::string& value, 24 | std::string* match_failure_reason = nullptr) const; 25 | 26 | std::vector whitelist; 27 | std::vector blacklist; 28 | }; -------------------------------------------------------------------------------- /src/maybe.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | // Like optional, but the stored data is responsible for containing the empty 8 | // state. T should define a function `bool T::HasValueForMaybe_()`. 9 | template 10 | class Maybe { 11 | T storage; 12 | 13 | public: 14 | constexpr Maybe() = default; 15 | Maybe(const Maybe&) = default; 16 | Maybe(std::nullopt_t) {} 17 | Maybe(const T& x) : storage(x) {} 18 | Maybe(T&& x) : storage(std::forward(x)) {} 19 | 20 | Maybe& operator=(const Maybe&) = default; 21 | Maybe& operator=(const T& x) { 22 | storage = x; 23 | return *this; 24 | } 25 | 26 | const T* operator->() const { return &storage; } 27 | T* operator->() { return &storage; } 28 | const T& operator*() const { return storage; } 29 | T& operator*() { return storage; } 30 | 31 | bool HasValue() const { return storage.HasValueForMaybe_(); } 32 | explicit operator bool() const { return HasValue(); } 33 | operator optional() const { 34 | if (HasValue()) 35 | return storage; 36 | return nullopt; 37 | } 38 | 39 | void operator=(optional&& o) { storage = o ? *o : T(); } 40 | 41 | // Does not test if has_value() 42 | bool operator==(const Maybe& o) const { return storage == o.storage; } 43 | bool operator!=(const Maybe& o) const { return !(*this == o); } 44 | }; 45 | -------------------------------------------------------------------------------- /src/messages/cquery_base.cc: -------------------------------------------------------------------------------- 1 | #include "message_handler.h" 2 | #include "query_utils.h" 3 | #include "queue_manager.h" 4 | 5 | namespace { 6 | 7 | MethodType kMethodType = "$cquery/base"; 8 | 9 | struct In_CqueryBase : public RequestInMessage { 10 | MethodType GetMethodType() const override { return kMethodType; } 11 | 12 | lsTextDocumentPositionParams params; 13 | }; 14 | MAKE_REFLECT_STRUCT(In_CqueryBase, id, params); 15 | REGISTER_IN_MESSAGE(In_CqueryBase); 16 | 17 | struct Handler_CqueryBase : BaseMessageHandler { 18 | MethodType GetMethodType() const override { return kMethodType; } 19 | 20 | void Run(In_CqueryBase* request) override { 21 | QueryFile* file; 22 | if (!FindFileOrFail(db, project, request->id, 23 | request->params.textDocument.uri.GetAbsolutePath(), 24 | &file)) { 25 | return; 26 | } 27 | 28 | WorkingFile* working_file = 29 | working_files->GetFileByFilename(file->def->path); 30 | 31 | Out_LocationList out; 32 | out.id = request->id; 33 | for (QueryId::SymbolRef sym : 34 | FindSymbolsAtLocation(working_file, file, request->params.position)) { 35 | if (sym.kind == SymbolKind::Type) { 36 | if (const auto* def = db->GetType(sym).AnyDef()) { 37 | out.result = GetLsLocations(db, working_files, 38 | GetDeclarations(db, def->bases)); 39 | } 40 | break; 41 | } else if (sym.kind == SymbolKind::Func) { 42 | if (const auto* def = db->GetFunc(sym).AnyDef()) { 43 | out.result = GetLsLocations(db, working_files, 44 | GetDeclarations(db, def->bases)); 45 | } 46 | break; 47 | } 48 | } 49 | QueueManager::WriteStdout(kMethodType, out); 50 | } 51 | }; 52 | REGISTER_MESSAGE_HANDLER(Handler_CqueryBase); 53 | } // namespace 54 | -------------------------------------------------------------------------------- /src/messages/cquery_callers.cc: -------------------------------------------------------------------------------- 1 | #include "message_handler.h" 2 | #include "query_utils.h" 3 | #include "queue_manager.h" 4 | 5 | namespace { 6 | MethodType kMethodType = "$cquery/callers"; 7 | 8 | struct In_CqueryCallers : public RequestInMessage { 9 | MethodType GetMethodType() const override { return kMethodType; } 10 | lsTextDocumentPositionParams params; 11 | }; 12 | MAKE_REFLECT_STRUCT(In_CqueryCallers, id, params); 13 | REGISTER_IN_MESSAGE(In_CqueryCallers); 14 | 15 | struct Handler_CqueryCallers : BaseMessageHandler { 16 | MethodType GetMethodType() const override { return kMethodType; } 17 | void Run(In_CqueryCallers* request) override { 18 | QueryFile* file; 19 | if (!FindFileOrFail(db, project, request->id, 20 | request->params.textDocument.uri.GetAbsolutePath(), 21 | &file)) { 22 | return; 23 | } 24 | 25 | WorkingFile* working_file = 26 | working_files->GetFileByFilename(file->def->path); 27 | 28 | Out_LocationList out; 29 | out.id = request->id; 30 | for (QueryId::SymbolRef sym : 31 | FindSymbolsAtLocation(working_file, file, request->params.position)) { 32 | if (sym.kind == SymbolKind::Func) { 33 | QueryFunc& func = db->GetFunc(sym); 34 | std::vector uses = func.uses; 35 | for (QueryId::LexicalRef func_ref : GetRefsForAllBases(db, func)) 36 | uses.push_back(func_ref); 37 | for (QueryId::LexicalRef func_ref : GetRefsForAllDerived(db, func)) 38 | uses.push_back(func_ref); 39 | out.result = GetLsLocations(db, working_files, uses); 40 | break; 41 | } 42 | } 43 | QueueManager::WriteStdout(kMethodType, out); 44 | } 45 | }; 46 | REGISTER_MESSAGE_HANDLER(Handler_CqueryCallers); 47 | } // namespace 48 | -------------------------------------------------------------------------------- /src/messages/cquery_did_view.cc: -------------------------------------------------------------------------------- 1 | #include "clang_complete.h" 2 | #include "message_handler.h" 3 | #include "working_files.h" 4 | 5 | namespace { 6 | MethodType kMethodType = "$cquery/textDocumentDidView"; 7 | 8 | struct In_CqueryTextDocumentDidView : public NotificationInMessage { 9 | MethodType GetMethodType() const override { return kMethodType; } 10 | struct Params { 11 | lsDocumentUri textDocumentUri; 12 | }; 13 | Params params; 14 | }; 15 | MAKE_REFLECT_STRUCT(In_CqueryTextDocumentDidView::Params, textDocumentUri); 16 | MAKE_REFLECT_STRUCT(In_CqueryTextDocumentDidView, params); 17 | REGISTER_IN_MESSAGE(In_CqueryTextDocumentDidView); 18 | 19 | struct Handler_CqueryDidView 20 | : BaseMessageHandler { 21 | MethodType GetMethodType() const override { return kMethodType; } 22 | void Run(In_CqueryTextDocumentDidView* request) override { 23 | AbsolutePath path = request->params.textDocumentUri.GetAbsolutePath(); 24 | 25 | WorkingFile* working_file = working_files->GetFileByFilename(path); 26 | if (!working_file) 27 | return; 28 | QueryFile* file = nullptr; 29 | if (!FindFileOrFail(db, project, nullopt, path, &file)) 30 | return; 31 | 32 | clang_complete->NotifyView(path); 33 | clang_complete->DiagnosticsUpdate(path); 34 | 35 | if (file->def) { 36 | EmitInactiveLines(working_file, file->def->inactive_regions); 37 | EmitSemanticHighlighting(db, semantic_cache, working_file, file); 38 | } 39 | } 40 | }; 41 | REGISTER_MESSAGE_HANDLER(Handler_CqueryDidView); 42 | } // namespace 43 | -------------------------------------------------------------------------------- /src/messages/cquery_file_info.cc: -------------------------------------------------------------------------------- 1 | #include "message_handler.h" 2 | #include "query_utils.h" 3 | #include "queue_manager.h" 4 | 5 | namespace { 6 | MethodType kMethodType = "$cquery/fileInfo"; 7 | 8 | struct lsDocumentSymbolParams { 9 | lsTextDocumentIdentifier textDocument; 10 | }; 11 | MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument); 12 | 13 | struct In_CqueryFileInfo : public RequestInMessage { 14 | MethodType GetMethodType() const override { return kMethodType; } 15 | lsDocumentSymbolParams params; 16 | }; 17 | MAKE_REFLECT_STRUCT(In_CqueryFileInfo, id, params); 18 | REGISTER_IN_MESSAGE(In_CqueryFileInfo); 19 | 20 | struct Out_CqueryFileInfo : public lsOutMessage { 21 | lsRequestId id; 22 | QueryFile::Def result; 23 | }; 24 | MAKE_REFLECT_STRUCT(Out_CqueryFileInfo, jsonrpc, id, result); 25 | 26 | struct Handler_CqueryFileInfo : BaseMessageHandler { 27 | MethodType GetMethodType() const override { return kMethodType; } 28 | void Run(In_CqueryFileInfo* request) override { 29 | QueryFile* file; 30 | if (!FindFileOrFail(db, project, request->id, 31 | request->params.textDocument.uri.GetAbsolutePath(), 32 | &file)) { 33 | return; 34 | } 35 | 36 | Out_CqueryFileInfo out; 37 | out.id = request->id; 38 | // Expose some fields of |QueryFile::Def|. 39 | out.result.path = file->def->path; 40 | out.result.args_hash = file->def->args_hash; 41 | out.result.language = file->def->language; 42 | out.result.includes = file->def->includes; 43 | out.result.inactive_regions = file->def->inactive_regions; 44 | QueueManager::WriteStdout(kMethodType, out); 45 | } 46 | }; 47 | REGISTER_MESSAGE_HANDLER(Handler_CqueryFileInfo); 48 | } // namespace 49 | -------------------------------------------------------------------------------- /src/messages/cquery_index_file.cc: -------------------------------------------------------------------------------- 1 | #include "cache_manager.h" 2 | #include "message_handler.h" 3 | #include "platform.h" 4 | #include "queue_manager.h" 5 | 6 | #include 7 | 8 | namespace { 9 | MethodType kMethodType = "$cquery/indexFile"; 10 | 11 | struct In_CqueryIndexFile : public NotificationInMessage { 12 | MethodType GetMethodType() const override { return kMethodType; } 13 | struct Params { 14 | std::string path; 15 | std::vector args; 16 | bool is_interactive = false; 17 | std::string contents; 18 | }; 19 | Params params; 20 | }; 21 | MAKE_REFLECT_STRUCT(In_CqueryIndexFile::Params, 22 | path, 23 | args, 24 | is_interactive, 25 | contents); 26 | MAKE_REFLECT_STRUCT(In_CqueryIndexFile, params); 27 | REGISTER_IN_MESSAGE(In_CqueryIndexFile); 28 | 29 | struct Handler_CqueryIndexFile : BaseMessageHandler { 30 | MethodType GetMethodType() const override { return kMethodType; } 31 | void Run(In_CqueryIndexFile* request) override { 32 | optional path = NormalizePath(request->params.path); 33 | if (!path) 34 | ABORT_S() << "Unable to find " << request->params.path; 35 | 36 | LOG_S(INFO) << "Indexing file " << request->params.path; 37 | QueueManager::instance()->index_request.Enqueue( 38 | Index_Request(path->path, request->params.args, 39 | request->params.is_interactive, request->params.contents, 40 | ICacheManager::Make()), 41 | true /*priority*/); 42 | } 43 | }; 44 | REGISTER_MESSAGE_HANDLER(Handler_CqueryIndexFile); 45 | } // namespace 46 | -------------------------------------------------------------------------------- /src/messages/cquery_vars.cc: -------------------------------------------------------------------------------- 1 | #include "message_handler.h" 2 | #include "query_utils.h" 3 | #include "queue_manager.h" 4 | 5 | namespace { 6 | MethodType kMethodType = "$cquery/vars"; 7 | 8 | struct In_CqueryVars : public RequestInMessage { 9 | MethodType GetMethodType() const override { return kMethodType; } 10 | 11 | lsTextDocumentPositionParams params; 12 | }; 13 | MAKE_REFLECT_STRUCT(In_CqueryVars, id, params); 14 | REGISTER_IN_MESSAGE(In_CqueryVars); 15 | 16 | struct Handler_CqueryVars : BaseMessageHandler { 17 | MethodType GetMethodType() const override { return kMethodType; } 18 | 19 | void Run(In_CqueryVars* request) override { 20 | QueryFile* file; 21 | if (!FindFileOrFail(db, project, request->id, 22 | request->params.textDocument.uri.GetAbsolutePath(), 23 | &file)) { 24 | return; 25 | } 26 | 27 | WorkingFile* working_file = 28 | working_files->GetFileByFilename(file->def->path); 29 | 30 | Out_LocationList out; 31 | out.id = request->id; 32 | for (QueryId::SymbolRef sym : 33 | FindSymbolsAtLocation(working_file, file, request->params.position)) { 34 | switch (sym.kind) { 35 | default: 36 | break; 37 | case SymbolKind::Var: { 38 | const QueryVar::Def* def = db->GetVar(sym).AnyDef(); 39 | if (!def || !def->type) 40 | continue; 41 | } 42 | // fallthrough 43 | case SymbolKind::Type: { 44 | QueryType& type = db->GetType(sym); 45 | out.result = GetLsLocations(db, working_files, 46 | GetDeclarations(db, type.instances)); 47 | break; 48 | } 49 | } 50 | } 51 | QueueManager::WriteStdout(kMethodType, out); 52 | } 53 | }; 54 | REGISTER_MESSAGE_HANDLER(Handler_CqueryVars); 55 | } // namespace 56 | -------------------------------------------------------------------------------- /src/messages/cquery_wait.cc: -------------------------------------------------------------------------------- 1 | #include "import_manager.h" 2 | #include "import_pipeline.h" 3 | #include "message_handler.h" 4 | #include "queue_manager.h" 5 | 6 | #include 7 | 8 | namespace { 9 | MethodType kMethodType = "$cquery/wait"; 10 | 11 | struct In_CqueryWait : public NotificationInMessage { 12 | MethodType GetMethodType() const override { return kMethodType; } 13 | }; 14 | MAKE_REFLECT_EMPTY_STRUCT(In_CqueryWait); 15 | REGISTER_IN_MESSAGE(In_CqueryWait); 16 | 17 | struct Handler_CqueryWait : MessageHandler { 18 | MethodType GetMethodType() const override { return kMethodType; } 19 | 20 | void Run(std::unique_ptr request) override { 21 | // TODO: use status message system here, then run querydb as normal? Maybe 22 | // this cannot be a normal message, ie, it needs to be re-entrant. 23 | 24 | LOG_S(INFO) << "Waiting for idle"; 25 | int idle_count = 0; 26 | while (true) { 27 | bool has_work = false; 28 | has_work |= import_pipeline_status->num_active_threads != 0; 29 | has_work |= QueueManager::instance()->HasWork(); 30 | has_work |= QueryDb_ImportMain(db, import_manager, import_pipeline_status, 31 | semantic_cache, working_files); 32 | if (!has_work) 33 | ++idle_count; 34 | else 35 | idle_count = 0; 36 | 37 | // There are race conditions between each of the three checks above, 38 | // so we retry a bunch of times to try to avoid any. 39 | if (idle_count > 10) 40 | break; 41 | } 42 | LOG_S(INFO) << "Done waiting for idle"; 43 | } 44 | }; 45 | REGISTER_MESSAGE_HANDLER(Handler_CqueryWait); 46 | } // namespace 47 | -------------------------------------------------------------------------------- /src/messages/exit.cc: -------------------------------------------------------------------------------- 1 | #include "message_handler.h" 2 | 3 | #include 4 | 5 | namespace { 6 | struct In_Exit : public NotificationInMessage { 7 | MethodType GetMethodType() const override { return kMethodType_Exit; } 8 | }; 9 | MAKE_REFLECT_EMPTY_STRUCT(In_Exit); 10 | REGISTER_IN_MESSAGE(In_Exit); 11 | 12 | struct Handler_Exit : MessageHandler { 13 | MethodType GetMethodType() const override { return kMethodType_Exit; } 14 | 15 | void Run(std::unique_ptr request) override { 16 | LOG_S(INFO) << "Exiting; got exit message"; 17 | exit(0); 18 | } 19 | }; 20 | REGISTER_MESSAGE_HANDLER(Handler_Exit); 21 | } // namespace 22 | -------------------------------------------------------------------------------- /src/messages/shutdown.cc: -------------------------------------------------------------------------------- 1 | #include "message_handler.h" 2 | #include "queue_manager.h" 3 | 4 | namespace { 5 | MethodType kMethodType = "shutdown"; 6 | 7 | struct In_Shutdown : public RequestInMessage { 8 | MethodType GetMethodType() const override { return kMethodType; } 9 | }; 10 | MAKE_REFLECT_STRUCT(In_Shutdown, id); 11 | REGISTER_IN_MESSAGE(In_Shutdown); 12 | 13 | struct Out_Shutdown : public lsOutMessage { 14 | lsRequestId id; 15 | JsonNull result; 16 | }; 17 | MAKE_REFLECT_STRUCT(Out_Shutdown, jsonrpc, id, result); 18 | 19 | struct Handler_Shutdown : BaseMessageHandler { 20 | MethodType GetMethodType() const override { return kMethodType; } 21 | void Run(In_Shutdown* request) override { 22 | Out_Shutdown out; 23 | out.id = request->id; 24 | QueueManager::WriteStdout(kMethodType, out); 25 | } 26 | }; 27 | REGISTER_MESSAGE_HANDLER(Handler_Shutdown); 28 | } // namespace 29 | -------------------------------------------------------------------------------- /src/messages/text_document_did_change.cc: -------------------------------------------------------------------------------- 1 | #include "cache_manager.h" 2 | #include "clang_complete.h" 3 | #include "message_handler.h" 4 | #include "project.h" 5 | #include "queue_manager.h" 6 | #include "working_files.h" 7 | 8 | #include 9 | 10 | namespace { 11 | MethodType kMethodType = "textDocument/didChange"; 12 | 13 | struct In_TextDocumentDidChange : public NotificationInMessage { 14 | MethodType GetMethodType() const override { return kMethodType; } 15 | lsTextDocumentDidChangeParams params; 16 | }; 17 | 18 | MAKE_REFLECT_STRUCT(In_TextDocumentDidChange, params); 19 | REGISTER_IN_MESSAGE(In_TextDocumentDidChange); 20 | 21 | struct Handler_TextDocumentDidChange 22 | : BaseMessageHandler { 23 | MethodType GetMethodType() const override { return kMethodType; } 24 | 25 | void Run(In_TextDocumentDidChange* request) override { 26 | AbsolutePath path = request->params.textDocument.uri.GetAbsolutePath(); 27 | working_files->OnChange(request->params); 28 | if (g_config->enableIndexOnDidChange) { 29 | WorkingFile* working_file = working_files->GetFileByFilename(path); 30 | Project::Entry entry = project->FindCompilationEntryForFile(path); 31 | QueueManager::instance()->index_request.Enqueue( 32 | Index_Request(entry.filename, entry.args, true /*is_interactive*/, 33 | working_file->buffer_content, ICacheManager::Make()), 34 | true /*priority*/); 35 | } 36 | clang_complete->NotifyEdit(path); 37 | clang_complete->DiagnosticsUpdate(path); 38 | } 39 | }; 40 | REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidChange); 41 | } // namespace 42 | -------------------------------------------------------------------------------- /src/messages/text_document_did_close.cc: -------------------------------------------------------------------------------- 1 | #include "clang_complete.h" 2 | #include "message_handler.h" 3 | #include "queue_manager.h" 4 | #include "working_files.h" 5 | 6 | namespace { 7 | MethodType kMethodType = "textDocument/didClose"; 8 | 9 | struct In_TextDocumentDidClose : public NotificationInMessage { 10 | MethodType GetMethodType() const override { return kMethodType; } 11 | struct Params { 12 | lsTextDocumentIdentifier textDocument; 13 | }; 14 | Params params; 15 | }; 16 | MAKE_REFLECT_STRUCT(In_TextDocumentDidClose::Params, textDocument); 17 | MAKE_REFLECT_STRUCT(In_TextDocumentDidClose, params); 18 | REGISTER_IN_MESSAGE(In_TextDocumentDidClose); 19 | 20 | struct Handler_TextDocumentDidClose 21 | : BaseMessageHandler { 22 | MethodType GetMethodType() const override { return kMethodType; } 23 | 24 | void Run(In_TextDocumentDidClose* request) override { 25 | AbsolutePath path = request->params.textDocument.uri.GetAbsolutePath(); 26 | 27 | // Clear any diagnostics for the file. 28 | Out_TextDocumentPublishDiagnostics out; 29 | out.params.uri = request->params.textDocument.uri; 30 | QueueManager::WriteStdout(kMethodType, out); 31 | 32 | // Remove internal state. 33 | working_files->OnClose(request->params.textDocument); 34 | clang_complete->NotifyClose(path); 35 | } 36 | }; 37 | REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDidClose); 38 | } // namespace 39 | -------------------------------------------------------------------------------- /src/messages/text_document_formatting.cc: -------------------------------------------------------------------------------- 1 | #include "clang_format.h" 2 | #include "message_handler.h" 3 | #include "platform.h" 4 | #include "queue_manager.h" 5 | #include "working_files.h" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace { 12 | MethodType kMethodType = "textDocument/formatting"; 13 | 14 | struct In_TextDocumentFormatting : public RequestInMessage { 15 | MethodType GetMethodType() const override { return kMethodType; } 16 | struct Params { 17 | lsTextDocumentIdentifier textDocument; 18 | lsFormattingOptions options; 19 | }; 20 | Params params; 21 | }; 22 | MAKE_REFLECT_STRUCT(In_TextDocumentFormatting::Params, textDocument, options); 23 | MAKE_REFLECT_STRUCT(In_TextDocumentFormatting, id, params); 24 | REGISTER_IN_MESSAGE(In_TextDocumentFormatting); 25 | 26 | struct Out_TextDocumentFormatting 27 | : public lsOutMessage { 28 | lsRequestId id; 29 | std::vector result; 30 | }; 31 | MAKE_REFLECT_STRUCT(Out_TextDocumentFormatting, jsonrpc, id, result); 32 | 33 | struct Handler_TextDocumentFormatting 34 | : BaseMessageHandler { 35 | MethodType GetMethodType() const override { return kMethodType; } 36 | void Run(In_TextDocumentFormatting* request) override { 37 | Out_TextDocumentFormatting response; 38 | response.id = request->id; 39 | 40 | WorkingFile* working_file = working_files->GetFileByFilename( 41 | request->params.textDocument.uri.GetAbsolutePath()); 42 | response.result = 43 | RunClangFormat(working_file->filename, working_file->buffer_content, 44 | nullopt /*start_offset*/, nullopt /*end_offset*/); 45 | 46 | QueueManager::WriteStdout(kMethodType, response); 47 | } 48 | }; 49 | REGISTER_MESSAGE_HANDLER(Handler_TextDocumentFormatting); 50 | } // namespace 51 | -------------------------------------------------------------------------------- /src/messages/text_document_implementation.cc: -------------------------------------------------------------------------------- 1 | #include "message_handler.h" 2 | #include "query_utils.h" 3 | #include "queue_manager.h" 4 | 5 | #include 6 | 7 | namespace { 8 | MethodType kMethodType = "textDocument/implementation"; 9 | 10 | struct In_TextDocumentImplementation : public RequestInMessage { 11 | MethodType GetMethodType() const override { return kMethodType; } 12 | lsTextDocumentPositionParams params; 13 | }; 14 | MAKE_REFLECT_STRUCT(In_TextDocumentImplementation, id, params); 15 | REGISTER_IN_MESSAGE(In_TextDocumentImplementation); 16 | 17 | struct Handler_TextDocumentImplementation 18 | : BaseMessageHandler { 19 | MethodType GetMethodType() const override { return kMethodType; } 20 | 21 | void Run(In_TextDocumentImplementation* request) override { 22 | QueryFile* file; 23 | if (!FindFileOrFail(db, project, request->id, 24 | request->params.textDocument.uri.GetAbsolutePath(), 25 | &file)) { 26 | return; 27 | } 28 | 29 | WorkingFile* working_file = 30 | working_files->GetFileByFilename(file->def->path); 31 | 32 | Out_LocationList out; 33 | out.id = request->id; 34 | 35 | for (QueryId::SymbolRef sym : 36 | FindSymbolsAtLocation(working_file, file, request->params.position)) { 37 | if (sym.kind == SymbolKind::Type) { 38 | QueryType& type = db->GetType(sym); 39 | out.result = GetLsLocations(db, working_files, 40 | GetDeclarations(db, type.derived)); 41 | break; 42 | } else if (sym.kind == SymbolKind::Func) { 43 | QueryFunc& func = db->GetFunc(sym); 44 | out.result = GetLsLocations(db, working_files, 45 | GetDeclarations(db, func.derived)); 46 | break; 47 | } 48 | } 49 | 50 | if (out.result.size() >= g_config->xref.maxNum) 51 | out.result.resize(g_config->xref.maxNum); 52 | QueueManager::WriteStdout(kMethodType, out); 53 | } 54 | }; 55 | REGISTER_MESSAGE_HANDLER(Handler_TextDocumentImplementation); 56 | } // namespace 57 | -------------------------------------------------------------------------------- /src/messages/text_document_type_definition.cc: -------------------------------------------------------------------------------- 1 | #include "message_handler.h" 2 | #include "query_utils.h" 3 | #include "queue_manager.h" 4 | 5 | namespace { 6 | MethodType kMethodType = "textDocument/typeDefinition"; 7 | 8 | struct In_TextDocumentTypeDefinition : public RequestInMessage { 9 | MethodType GetMethodType() const override { return kMethodType; } 10 | lsTextDocumentPositionParams params; 11 | }; 12 | MAKE_REFLECT_STRUCT(In_TextDocumentTypeDefinition, id, params); 13 | REGISTER_IN_MESSAGE(In_TextDocumentTypeDefinition); 14 | 15 | struct Handler_TextDocumentTypeDefinition 16 | : BaseMessageHandler { 17 | MethodType GetMethodType() const override { return kMethodType; } 18 | void Run(In_TextDocumentTypeDefinition* request) override { 19 | QueryFile* file; 20 | if (!FindFileOrFail(db, project, request->id, 21 | request->params.textDocument.uri.GetAbsolutePath(), 22 | &file, nullptr)) { 23 | return; 24 | } 25 | WorkingFile* working_file = 26 | working_files->GetFileByFilename(file->def->path); 27 | 28 | Out_LocationList out; 29 | out.id = request->id; 30 | for (QueryId::SymbolRef sym : 31 | FindSymbolsAtLocation(working_file, file, request->params.position)) { 32 | AnyId id = sym.id; 33 | switch (sym.kind) { 34 | case SymbolKind::Var: { 35 | const QueryVar::Def* def = db->GetVar(sym).AnyDef(); 36 | if (!def || !def->type) 37 | continue; 38 | id = *def->type; 39 | } 40 | // fallthrough 41 | case SymbolKind::Type: { 42 | QueryType& type = db->GetType({id, SymbolKind::Type}); 43 | for (const auto& def : type.def) 44 | if (def.spell) { 45 | if (auto ls_loc = GetLsLocation(db, working_files, *def.spell)) 46 | out.result.push_back(*ls_loc); 47 | } 48 | break; 49 | } 50 | default: 51 | break; 52 | } 53 | } 54 | 55 | QueueManager::WriteStdout(kMethodType, out); 56 | } 57 | }; 58 | REGISTER_MESSAGE_HANDLER(Handler_TextDocumentTypeDefinition); 59 | 60 | } // namespace 61 | -------------------------------------------------------------------------------- /src/messages/workspace_did_change_configuration.cc: -------------------------------------------------------------------------------- 1 | #include "cache_manager.h" 2 | #include "clang_complete.h" 3 | #include "message_handler.h" 4 | #include "project.h" 5 | #include "queue_manager.h" 6 | #include "timer.h" 7 | #include "working_files.h" 8 | 9 | #include 10 | 11 | namespace { 12 | MethodType kMethodType = "workspace/didChangeConfiguration"; 13 | 14 | struct lsDidChangeConfigurationParams { 15 | bool placeholder; 16 | }; 17 | MAKE_REFLECT_STRUCT(lsDidChangeConfigurationParams, placeholder); 18 | 19 | struct In_WorkspaceDidChangeConfiguration : public NotificationInMessage { 20 | MethodType GetMethodType() const override { return kMethodType; } 21 | lsDidChangeConfigurationParams params; 22 | }; 23 | MAKE_REFLECT_STRUCT(In_WorkspaceDidChangeConfiguration, params); 24 | REGISTER_IN_MESSAGE(In_WorkspaceDidChangeConfiguration); 25 | 26 | struct Handler_WorkspaceDidChangeConfiguration 27 | : BaseMessageHandler { 28 | MethodType GetMethodType() const override { return kMethodType; } 29 | void Run(In_WorkspaceDidChangeConfiguration* request) override { 30 | Timer time; 31 | project->Load(g_config->projectRoot); 32 | time.ResetAndPrint("[perf] Loaded compilation entries (" + 33 | std::to_string(project->entries.size()) + " files)"); 34 | 35 | time.Reset(); 36 | project->Index(QueueManager::instance(), working_files, lsRequestId()); 37 | time.ResetAndPrint( 38 | "[perf] Dispatched workspace/didChangeConfiguration index requests"); 39 | 40 | clang_complete->FlushAllSessions(); 41 | LOG_S(INFO) << "Flushed all clang complete sessions"; 42 | } 43 | }; 44 | REGISTER_MESSAGE_HANDLER(Handler_WorkspaceDidChangeConfiguration); 45 | } // namespace 46 | -------------------------------------------------------------------------------- /src/messages/workspace_execute_command.cc: -------------------------------------------------------------------------------- 1 | #include "lsp_code_action.h" 2 | #include "message_handler.h" 3 | #include "query_utils.h" 4 | #include "queue_manager.h" 5 | 6 | namespace { 7 | MethodType kMethodType = "workspace/executeCommand"; 8 | 9 | struct In_WorkspaceExecuteCommand : public RequestInMessage { 10 | MethodType GetMethodType() const override { return kMethodType; } 11 | lsCommand params; 12 | }; 13 | MAKE_REFLECT_STRUCT(In_WorkspaceExecuteCommand, id, params); 14 | REGISTER_IN_MESSAGE(In_WorkspaceExecuteCommand); 15 | 16 | struct Out_WorkspaceExecuteCommand 17 | : public lsOutMessage { 18 | lsRequestId id; 19 | std::vector result; 20 | }; 21 | MAKE_REFLECT_STRUCT(Out_WorkspaceExecuteCommand, jsonrpc, id, result); 22 | 23 | struct Handler_WorkspaceExecuteCommand 24 | : BaseMessageHandler { 25 | MethodType GetMethodType() const override { return kMethodType; } 26 | void Run(In_WorkspaceExecuteCommand* request) override { 27 | const auto& params = request->params; 28 | Out_WorkspaceExecuteCommand out; 29 | out.id = request->id; 30 | if (params.command == "cquery._applyFixIt") { 31 | } else if (params.command == "cquery._autoImplement") { 32 | } else if (params.command == "cquery._insertInclude") { 33 | } else if (params.command == "cquery.showReferences") { 34 | out.result = params.arguments.locations; 35 | } 36 | 37 | QueueManager::WriteStdout(kMethodType, out); 38 | } 39 | }; 40 | REGISTER_MESSAGE_HANDLER(Handler_WorkspaceExecuteCommand); 41 | 42 | } // namespace 43 | -------------------------------------------------------------------------------- /src/method.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "serializer.h" 4 | #include "utils.h" 5 | 6 | #include 7 | 8 | using MethodType = const char*; 9 | extern MethodType kMethodType_Unknown; 10 | extern MethodType kMethodType_Exit; 11 | extern MethodType kMethodType_TextDocumentPublishDiagnostics; 12 | extern MethodType kMethodType_CqueryPublishInactiveRegions; 13 | extern MethodType kMethodType_CqueryQueryDbStatus; 14 | extern MethodType kMethodType_CqueryPublishSemanticHighlighting; 15 | 16 | struct lsRequestId { 17 | // The client can send the request id as an int or a string. We should output 18 | // the same format we received. 19 | enum Type { kNone, kInt, kString }; 20 | Type type = kNone; 21 | 22 | int value = -1; 23 | 24 | bool has_value() const { return type != kNone; } 25 | }; 26 | void Reflect(Reader& visitor, lsRequestId& value); 27 | void Reflect(Writer& visitor, lsRequestId& value); 28 | 29 | // Debug method to convert an id to a string. 30 | std::string ToString(const lsRequestId& id); 31 | 32 | struct InMessage { 33 | virtual ~InMessage(); 34 | 35 | virtual MethodType GetMethodType() const = 0; 36 | virtual lsRequestId GetRequestId() const = 0; 37 | }; 38 | 39 | struct RequestInMessage : public InMessage { 40 | // number or string, actually no null 41 | lsRequestId id; 42 | lsRequestId GetRequestId() const override; 43 | }; 44 | 45 | // NotificationInMessage does not have |id|. 46 | struct NotificationInMessage : public InMessage { 47 | lsRequestId GetRequestId() const override; 48 | }; 49 | -------------------------------------------------------------------------------- /src/options.cc: -------------------------------------------------------------------------------- 1 | #include "options.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | std::unordered_map ParseOptions(int argc, 8 | char** argv) { 9 | std::unordered_map output; 10 | 11 | for (int i = 1; i < argc; ++i) { 12 | std::string arg = argv[i]; 13 | if (arg[0] == '-') { 14 | auto equal = arg.find('='); 15 | if (equal != std::string::npos) { 16 | output[arg.substr(0, equal)] = arg.substr(equal + 1); 17 | } else if (i + 1 < argc && argv[i + 1][0] != '-') 18 | output[arg] = argv[++i]; 19 | else 20 | output[arg] = ""; 21 | } 22 | } 23 | 24 | return output; 25 | } 26 | 27 | bool HasOption(const std::unordered_map& options, 28 | const std::string& option) { 29 | return options.find(option) != options.end(); 30 | } 31 | -------------------------------------------------------------------------------- /src/options.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | std::unordered_map ParseOptions(int argc, 6 | char** argv); 7 | 8 | bool HasOption(const std::unordered_map& options, 9 | const std::string& option); -------------------------------------------------------------------------------- /src/position.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "maybe.h" 4 | #include "serializer.h" 5 | #include "utils.h" 6 | 7 | #include 8 | #include 9 | 10 | struct Position { 11 | int16_t line; 12 | int16_t column; 13 | 14 | Position(); 15 | Position(int16_t line, int16_t column); 16 | explicit Position(const char* encoded); 17 | 18 | bool HasValueForMaybe_() const { return line >= 0; } 19 | std::string ToString(); 20 | std::string ToPrettyString(const std::string& filename); 21 | 22 | // Compare two Positions and check if they are equal. Ignores the value of 23 | // |interesting|. 24 | bool operator==(const Position& that) const; 25 | bool operator!=(const Position& that) const; 26 | bool operator<(const Position& that) const; 27 | }; 28 | static_assert( 29 | sizeof(Position) == 4, 30 | "Investigate, Position should be 32-bits for indexer size reasons"); 31 | MAKE_HASHABLE(Position, t.line, t.column); 32 | 33 | struct Range { 34 | Position start; 35 | Position end; 36 | 37 | Range(); 38 | explicit Range(Position position); 39 | Range(Position start, Position end); 40 | explicit Range(const char* encoded); 41 | 42 | bool HasValueForMaybe_() const { return start.HasValueForMaybe_(); } 43 | bool Contains(int line, int column) const; 44 | Range RemovePrefix(Position position) const; 45 | 46 | std::string ToString(); 47 | 48 | bool operator==(const Range& that) const; 49 | bool operator!=(const Range& that) const; 50 | bool operator<(const Range& that) const; 51 | }; 52 | MAKE_HASHABLE(Range, t.start, t.end); 53 | 54 | // Reflection 55 | void Reflect(Reader& visitor, Position& value); 56 | void Reflect(Writer& visitor, Position& value); 57 | void Reflect(Reader& visitor, Range& value); 58 | void Reflect(Writer& visitor, Range& value); 59 | -------------------------------------------------------------------------------- /src/project.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "config.h" 4 | #include "method.h" 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | class QueueManager; 15 | struct WorkingFiles; 16 | 17 | struct Project { 18 | struct Entry { 19 | AbsolutePath filename; 20 | std::vector args; 21 | // If true, this entry is inferred and was not read from disk. 22 | bool is_inferred = false; 23 | }; 24 | 25 | // Include directories for "" headers 26 | std::vector quote_include_directories; 27 | // Include directories for <> headers 28 | std::vector angle_include_directories; 29 | 30 | std::vector entries; 31 | spp::sparse_hash_map absolute_path_to_entry_index_; 32 | 33 | // Loads a project for the given |directory|. 34 | // 35 | // If |g_config->compilationDatabaseDirectory| is not empty, look for .cquery 36 | // or compile_commands.json in it, otherwise they are retrieved in 37 | // |root_directory|. 38 | // 39 | // For .cquery, recursive directory listing is used and files with known 40 | // suffixes are indexed. .cquery files can exist in subdirectories and they 41 | // will affect flags in their subtrees (relative paths are relative to the 42 | // project root, not subdirectories). For compile_commands.json, its entries 43 | // are indexed. 44 | void Load(const AbsolutePath& root_directory); 45 | 46 | // Lookup the CompilationEntry for |filename|. If no entry was found this 47 | // will infer one based on existing project structure. 48 | Entry FindCompilationEntryForFile(const AbsolutePath& filename); 49 | 50 | // If the client has overridden the flags, or specified them for a file 51 | // that is not in the compilation_database.json make sure those changes 52 | // are permanent. 53 | void SetFlagsForFile(const std::vector& flags, 54 | const AbsolutePath& path); 55 | 56 | // Run |action| on every file in the project. 57 | void ForAllFilteredFiles( 58 | std::function action); 59 | 60 | void Index(QueueManager* queue, WorkingFiles* working_files, lsRequestId id); 61 | }; 62 | -------------------------------------------------------------------------------- /src/recorder.cc: -------------------------------------------------------------------------------- 1 | #include "recorder.h" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | namespace { 9 | std::ofstream* g_file_in = nullptr; 10 | std::ofstream* g_file_out = nullptr; 11 | } // namespace 12 | 13 | void EnableRecording(std::string path) { 14 | if (path.empty()) 15 | path = "cquery"; 16 | 17 | // We can only call |EnableRecording| once. 18 | assert(!g_file_in && !g_file_out); 19 | 20 | // Open the files. 21 | g_file_in = new std::ofstream( 22 | path + ".in", std::ios::out | std::ios::trunc | std::ios::binary); 23 | g_file_out = new std::ofstream( 24 | path + ".out", std::ios::out | std::ios::trunc | std::ios::binary); 25 | 26 | // Make sure we can write to the files. 27 | bool bad = false; 28 | if (!g_file_in->good()) { 29 | LOG_S(ERROR) << "record: cannot write to " << path << ".in"; 30 | bad = true; 31 | } 32 | if (!g_file_out->good()) { 33 | LOG_S(ERROR) << "record: cannot write to " << path << ".out"; 34 | bad = true; 35 | } 36 | if (bad) { 37 | delete g_file_in; 38 | delete g_file_out; 39 | g_file_in = nullptr; 40 | g_file_out = nullptr; 41 | } 42 | } 43 | 44 | void RecordInput(std::string_view content) { 45 | if (!g_file_in) 46 | return; 47 | (*g_file_in) << "Content-Length: " << content.size() << "\r\n\r\n" << content; 48 | (*g_file_in).flush(); 49 | } 50 | 51 | void RecordOutput(std::string_view content) { 52 | if (!g_file_out) 53 | return; 54 | (*g_file_out) << content; 55 | (*g_file_out).flush(); 56 | } -------------------------------------------------------------------------------- /src/recorder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | void EnableRecording(std::string path); 8 | void RecordInput(std::string_view content); 9 | void RecordOutput(std::string_view content); -------------------------------------------------------------------------------- /src/semantic_highlight_symbol_cache.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "lru_cache.h" 4 | #include "match.h" 5 | #include "query.h" 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | // Caches symbols for a single file for semantic highlighting to provide 13 | // relatively stable ids. Only supports xxx files at a time. 14 | struct SemanticHighlightSymbolCache { 15 | struct Entry { 16 | SemanticHighlightSymbolCache* all_caches_ = nullptr; 17 | 18 | // The path this cache belongs to. 19 | std::string path; 20 | // Detailed symbol name to stable id. 21 | using TNameToId = std::unordered_map; 22 | TNameToId detailed_type_name_to_stable_id; 23 | TNameToId detailed_func_name_to_stable_id; 24 | TNameToId detailed_var_name_to_stable_id; 25 | 26 | Entry(SemanticHighlightSymbolCache* all_caches, const std::string& path); 27 | 28 | optional TryGetStableId(SymbolKind kind, 29 | const std::string& detailed_name); 30 | int GetStableId(SymbolKind kind, const std::string& detailed_name); 31 | 32 | TNameToId* GetMapForSymbol_(SymbolKind kind); 33 | }; 34 | 35 | constexpr static int kCacheSize = 10; 36 | LruCache> cache_; 37 | uint32_t next_stable_id_ = 0; 38 | std::unique_ptr match_; 39 | 40 | SemanticHighlightSymbolCache(); 41 | void Init(); 42 | std::shared_ptr GetCacheForFile(const std::string& path); 43 | }; 44 | -------------------------------------------------------------------------------- /src/standard_includes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // A set of standard libary header names, ie, "vector". 4 | extern const char* kStandardLibraryIncludes[177]; -------------------------------------------------------------------------------- /src/task.h: -------------------------------------------------------------------------------- 1 | #if false 2 | #pragma once 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | enum class TaskThread { 13 | Indexer, 14 | QueryDb, 15 | }; 16 | 17 | struct TaskManager { 18 | using TTask = std::function; 19 | using TIdleTask = std::function; 20 | 21 | TaskManager(); 22 | 23 | // Run |task| at some point in the future. This will run the task as soon as possible. 24 | void Post(TaskThread thread, const TTask& task); 25 | 26 | // Run |task| whenever there is nothing else to run. 27 | void SetIdle(TaskThread thread, const TIdleTask& idle_task); 28 | 29 | // Run pending tasks for |thread|. Stop running tasks after |max_time| has 30 | // elapsed. Returns true if tasks were run. 31 | bool RunTasks(TaskThread thread, optional> max_time); 32 | 33 | struct TaskQueue { 34 | optional idle_task; 35 | std::vector tasks; 36 | std::mutex tasks_mutex; 37 | }; 38 | 39 | std::unordered_map> pending_tasks_; 40 | }; 41 | #endif -------------------------------------------------------------------------------- /src/test.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | bool RunIndexTests(const std::string& filter_path, bool enable_update); 6 | -------------------------------------------------------------------------------- /src/third_party_impl.cc: -------------------------------------------------------------------------------- 1 | #define DOCTEST_CONFIG_IMPLEMENT 2 | #include 3 | 4 | #define LOGURU_IMPLEMENTATION 1 5 | #include 6 | -------------------------------------------------------------------------------- /src/threaded_queue.cc: -------------------------------------------------------------------------------- 1 | #include "threaded_queue.h" 2 | 3 | // static 4 | bool MultiQueueWaiter::HasState( 5 | std::initializer_list queues) { 6 | for (BaseThreadQueue* queue : queues) { 7 | if (!queue->IsEmpty()) 8 | return true; 9 | } 10 | return false; 11 | } 12 | 13 | bool MultiQueueWaiter::ValidateWaiter( 14 | std::initializer_list queues) { 15 | for (BaseThreadQueue* queue : queues) { 16 | if (queue->waiter.get() != this) 17 | return false; 18 | } 19 | return true; 20 | } 21 | -------------------------------------------------------------------------------- /src/timer.cc: -------------------------------------------------------------------------------- 1 | #include "timer.h" 2 | 3 | #include 4 | 5 | using namespace std::chrono; 6 | 7 | // static 8 | long long Timer::GetCurrentTimeInMilliseconds() { 9 | auto time_since_epoch = Clock::now().time_since_epoch(); 10 | return duration_cast(time_since_epoch).count(); 11 | } 12 | 13 | Timer::Timer() { 14 | Reset(); 15 | } 16 | 17 | long long Timer::ElapsedMicroseconds() const { 18 | time_point end = Clock::now(); 19 | long long elapsed = elapsed_; 20 | if (start_.has_value()) { 21 | elapsed += duration_cast(end - *start_).count(); 22 | } 23 | return elapsed; 24 | } 25 | 26 | long long Timer::ElapsedMicrosecondsAndReset() { 27 | long long elapsed = ElapsedMicroseconds(); 28 | Reset(); 29 | return elapsed; 30 | } 31 | 32 | void Timer::Reset() { 33 | start_ = Clock::now(); 34 | elapsed_ = 0; 35 | } 36 | 37 | void Timer::ResetAndPrint(const std::string& message) { 38 | long long elapsed = ElapsedMicroseconds(); 39 | long long milliseconds = elapsed / 1000; 40 | long long remaining = elapsed - milliseconds; 41 | LOG_S(INFO) << message << " took " << milliseconds << "." << remaining 42 | << "ms"; 43 | Reset(); 44 | } 45 | 46 | void Timer::Pause() { 47 | assert(start_.has_value()); 48 | 49 | time_point end = Clock::now(); 50 | long long elapsed = duration_cast(end - *start_).count(); 51 | 52 | elapsed_ += elapsed; 53 | start_ = nullopt; 54 | } 55 | 56 | void Timer::Resume() { 57 | assert(!start_.has_value()); 58 | start_ = Clock::now(); 59 | } 60 | 61 | ScopedPerfTimer::ScopedPerfTimer(const std::string& message) 62 | : message_(message) {} 63 | 64 | ScopedPerfTimer::~ScopedPerfTimer() { 65 | timer_.ResetAndPrint(message_); 66 | } 67 | -------------------------------------------------------------------------------- /src/timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct Timer { 9 | using Clock = std::chrono::high_resolution_clock; 10 | 11 | static long long GetCurrentTimeInMilliseconds(); 12 | 13 | // Creates a new timer. A timer is always running. 14 | Timer(); 15 | 16 | // Returns elapsed microseconds. 17 | long long ElapsedMicroseconds() const; 18 | // Returns elapsed microseconds and restarts/resets the timer. 19 | long long ElapsedMicrosecondsAndReset(); 20 | // Restart/reset the timer. 21 | void Reset(); 22 | // Resets timer and prints a message like " took 5ms" 23 | void ResetAndPrint(const std::string& message); 24 | // Pause the timer. 25 | void Pause(); 26 | // Resume the timer after it has been paused. 27 | void Resume(); 28 | 29 | // Raw start time. 30 | optional> start_; 31 | // Elapsed time. 32 | long long elapsed_ = 0; 33 | }; 34 | 35 | struct ScopedPerfTimer { 36 | ScopedPerfTimer(const std::string& message); 37 | ~ScopedPerfTimer(); 38 | 39 | Timer timer_; 40 | std::string message_; 41 | }; 42 | -------------------------------------------------------------------------------- /src/timestamp_manager.cc: -------------------------------------------------------------------------------- 1 | #include "timestamp_manager.h" 2 | 3 | #include "cache_manager.h" 4 | #include "indexer.h" 5 | 6 | optional TimestampManager::GetLastCachedModificationTime( 7 | ICacheManager* cache_manager, 8 | const std::string& path) { 9 | { 10 | std::lock_guard guard(mutex_); 11 | auto it = timestamps_.find(path); 12 | if (it != timestamps_.end()) 13 | return it->second; 14 | } 15 | IndexFile* file = cache_manager->TryLoad(path); 16 | if (!file) 17 | return nullopt; 18 | 19 | UpdateCachedModificationTime(path, file->last_modification_time); 20 | return file->last_modification_time; 21 | } 22 | 23 | void TimestampManager::UpdateCachedModificationTime(const std::string& path, 24 | int64_t timestamp) { 25 | std::lock_guard guard(mutex_); 26 | timestamps_[path] = timestamp; 27 | } 28 | -------------------------------------------------------------------------------- /src/timestamp_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct ICacheManager; 9 | 10 | // Caches timestamps of cc files so we can avoid a filesystem reads. This is 11 | // important for import perf, as during dependency checking the same files are 12 | // checked over and over again if they are common headers. 13 | struct TimestampManager { 14 | optional GetLastCachedModificationTime(ICacheManager* cache_manager, 15 | const std::string& path); 16 | 17 | void UpdateCachedModificationTime(const std::string& path, int64_t timestamp); 18 | 19 | // TODO: use std::shared_mutex so we can have multiple readers. 20 | std::mutex mutex_; 21 | std::unordered_map timestamps_; 22 | }; -------------------------------------------------------------------------------- /src/type_printer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "indexer.h" 4 | 5 | std::string GetFunctionSignature(IndexFile* db, 6 | NamespaceHelper* ns, 7 | const CXIdxDeclInfo* decl); 8 | -------------------------------------------------------------------------------- /src/work_thread.cc: -------------------------------------------------------------------------------- 1 | #include "work_thread.h" 2 | 3 | #include "platform.h" 4 | 5 | // static 6 | void WorkThread::StartThread(const std::string& thread_name, 7 | std::function entry_point) { 8 | new std::thread([thread_name, entry_point]() { 9 | SetCurrentThreadName(thread_name); 10 | entry_point(); 11 | }); 12 | } -------------------------------------------------------------------------------- /src/work_thread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | // Helper methods for starting threads that do some work. Enables test code to 10 | // wait for all work to complete. 11 | struct WorkThread { 12 | // Launch a new thread. |entry_point| will be called continously. It should 13 | // return true if it there is still known work to be done. 14 | static void StartThread(const std::string& thread_name, 15 | std::function entry_point); 16 | 17 | // Static-only class. 18 | WorkThread() = delete; 19 | }; -------------------------------------------------------------------------------- /third_party/optional.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if __cplusplus < 201703L 4 | #include "optional.hpp" 5 | using std::experimental::nullopt; 6 | using std::experimental::optional; 7 | namespace std { 8 | using std::experimental::nullopt_t; 9 | } 10 | #else 11 | #include 12 | using std::nullopt; 13 | using std::optional; 14 | #endif 15 | -------------------------------------------------------------------------------- /third_party/siphash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | int siphash(const uint8_t *in, const size_t inlen, const uint8_t *k, 7 | uint8_t *out, const size_t outlen); 8 | -------------------------------------------------------------------------------- /third_party/string_view.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define STX_NAMESPACE_NAME std 3 | #include "string_view.hpp" 4 | -------------------------------------------------------------------------------- /waf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | print('cquery no longer supports building with waf. Please use cmake instead.') 6 | print('') 7 | print('Here is a quick getting-started:') 8 | print('') 9 | print(' # remove previous waf build directory') 10 | print(' $ rm -rf build') 11 | print(' ') 12 | print(' # setup new cmake build directory') 13 | print(' $ mkdir build') 14 | print(' $ cd build') 15 | print(' $ cmake .. -DCMAKE_BUILD_TYPE=release -DCMAKE_INSTALL_PREFIX=release -DCMAKE_EXPORT_COMPILE_COMMANDS=YES') 16 | print(' $ make install -j8') 17 | print('') 18 | print('See https://github.com/cquery-project/cquery/wiki/Building-cquery for more details') 19 | 20 | sys.exit(1) 21 | --------------------------------------------------------------------------------