diff --git a/CMakeLists.txt b/CMakeLists.txt index 52e26ebc..97d13160 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -211,6 +211,7 @@ target_sources(ccls PRIVATE src/diagnostics_engine.cc src/file_consumer.cc src/file_contents.cc + src/filesystem.cc src/fuzzy_match.cc src/iindexer.cc src/import_manager.cc diff --git a/index_tests/constructors/constructor.cc b/index_tests/constructors/constructor.cc index b36665ad..8e26369d 100644 --- a/index_tests/constructors/constructor.cc +++ b/index_tests/constructors/constructor.cc @@ -67,7 +67,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 10983126130596230582, + "usr": 18410644574635149442, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", @@ -80,7 +80,7 @@ OUTPUT: "storage": 1 }, { "id": 1, - "usr": 17165811951126099095, + "usr": 11468802633764653592, "detailed_name": "Foo *f2", "qual_name_offset": 5, "short_name": "f2", diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc index 59c46409..d750286f 100644 --- a/index_tests/constructors/destructor.cc +++ b/index_tests/constructors/destructor.cc @@ -89,7 +89,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 1893354193220338759, + "usr": 9954632887635271906, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", diff --git a/index_tests/constructors/implicit_constructor.cc b/index_tests/constructors/implicit_constructor.cc index bd7b719e..06c475c9 100644 --- a/index_tests/constructors/implicit_constructor.cc +++ b/index_tests/constructors/implicit_constructor.cc @@ -66,7 +66,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 449111627548814328, + "usr": 17348451315735351657, "detailed_name": "Type foo0", "qual_name_offset": 5, "short_name": "foo0", @@ -79,7 +79,7 @@ OUTPUT: "storage": 1 }, { "id": 1, - "usr": 17097499197730163115, + "usr": 3757978174345638825, "detailed_name": "Type foo1", "qual_name_offset": 5, "short_name": "foo1", diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc index a2c3a4be..9150cc48 100644 --- a/index_tests/constructors/make_functions.cc +++ b/index_tests/constructors/make_functions.cc @@ -143,7 +143,7 @@ OUTPUT: make_functions.cc "skipped_by_preprocessor": [], "types": [{ "id": 0, - "usr": 9281343527065946499, + "usr": 7902098450755788854, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", @@ -160,7 +160,7 @@ OUTPUT: make_functions.cc "uses": ["4:1-4:2|-1|1|4"] }, { "id": 1, - "usr": 10771590811355716928, + "usr": 12533159752419999454, "detailed_name": "Args", "qual_name_offset": 0, "short_name": "Args", @@ -177,7 +177,7 @@ OUTPUT: make_functions.cc "uses": ["4:15-4:19|-1|1|4"] }, { "id": 2, - "usr": 11897454629873246477, + "usr": 18441628706991062891, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", @@ -194,7 +194,7 @@ OUTPUT: make_functions.cc "uses": ["9:1-9:2|-1|1|4"] }, { "id": 3, - "usr": 3337128087216004141, + "usr": 9441341235704820385, "detailed_name": "Args", "qual_name_offset": 0, "short_name": "Args", @@ -347,7 +347,7 @@ OUTPUT: make_functions.cc }], "vars": [{ "id": 0, - "usr": 8463700030555379526, + "usr": 15288691366352169805, "detailed_name": "Args &&... args", "qual_name_offset": 11, "short_name": "args", @@ -359,7 +359,7 @@ OUTPUT: make_functions.cc "storage": 1 }, { "id": 1, - "usr": 3908732770590594660, + "usr": 12338908251430965107, "detailed_name": "Args... args", "qual_name_offset": 8, "short_name": "args", diff --git a/index_tests/declaration_vs_definition/func_associated_function_params.cc b/index_tests/declaration_vs_definition/func_associated_function_params.cc index ee705c0d..02287ca8 100644 --- a/index_tests/declaration_vs_definition/func_associated_function_params.cc +++ b/index_tests/declaration_vs_definition/func_associated_function_params.cc @@ -53,7 +53,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 14555488990109936920, + "usr": 10480417713467708012, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", @@ -66,7 +66,7 @@ OUTPUT: "storage": 1 }, { "id": 1, - "usr": 10963664335057337329, + "usr": 18099600680625658464, "detailed_name": "int b", "qual_name_offset": 4, "short_name": "b", diff --git a/index_tests/inheritance/class_inherit_templated_parent.cc b/index_tests/inheritance/class_inherit_templated_parent.cc index 3056a4ff..f106d3c9 100644 --- a/index_tests/inheritance/class_inherit_templated_parent.cc +++ b/index_tests/inheritance/class_inherit_templated_parent.cc @@ -102,7 +102,7 @@ OUTPUT: "uses": ["13:56-13:64|-1|1|4"] }, { "id": 5, - "usr": 7916588271848318236, + "usr": 780719166805015998, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", @@ -138,7 +138,7 @@ OUTPUT: "funcs": [], "vars": [{ "id": 0, - "usr": 12990052348105569112, + "usr": 3880651725784125791, "detailed_name": "unsigned int T", "qual_name_offset": 13, "short_name": "T", diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc index 5ed38fa3..c06408f3 100644 --- a/index_tests/lambdas/lambda.cc +++ b/index_tests/lambdas/lambda.cc @@ -33,7 +33,7 @@ OUTPUT: "uses": [] }, { "id": 1, - "usr": 14635009347499519042, + "usr": 1287417953265234030, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -65,7 +65,7 @@ OUTPUT: "callees": ["9:14-9:15|1|3|32", "10:14-10:15|1|3|32", "11:14-11:15|1|3|32"] }, { "id": 1, - "usr": 17926497908620168464, + "usr": 1328781044864682611, "detailed_name": "", "qual_name_offset": 0, "short_name": "", @@ -80,7 +80,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 12666114896600231317, + "usr": 17270098654620601683, "detailed_name": "int x", "qual_name_offset": 4, "short_name": "x", @@ -93,7 +93,7 @@ OUTPUT: "storage": 1 }, { "id": 1, - "usr": 2981279427664991319, + "usr": 16806544259835773270, "detailed_name": "lambda dosomething", "qual_name_offset": 7, "short_name": "dosomething", @@ -106,7 +106,7 @@ OUTPUT: "storage": 1 }, { "id": 2, - "usr": 12879188959314906706, + "usr": 2034725908368218782, "detailed_name": "int y", "qual_name_offset": 4, "short_name": "y", diff --git a/index_tests/macros/foo.cc b/index_tests/macros/foo.cc index f03b19de..4fb7a6e7 100644 --- a/index_tests/macros/foo.cc +++ b/index_tests/macros/foo.cc @@ -92,7 +92,7 @@ OUTPUT: "storage": 0 }, { "id": 2, - "usr": 2056319845419860263, + "usr": 14946041066794678724, "detailed_name": "DISALLOW", "qual_name_offset": 0, "short_name": "DISALLOW", diff --git a/index_tests/namespaces/anonymous_function.cc b/index_tests/namespaces/anonymous_function.cc index 701ab855..878cb81a 100644 --- a/index_tests/namespaces/anonymous_function.cc +++ b/index_tests/namespaces/anonymous_function.cc @@ -26,7 +26,7 @@ OUTPUT: "funcs": [{ "id": 0, "usr": 5010253035933134245, - "detailed_name": "void (anon)::foo()", + "detailed_name": "void (anon ns)::foo()", "qual_name_offset": 5, "short_name": "foo", "kind": 12, diff --git a/index_tests/namespaces/namespace_alias.cc b/index_tests/namespaces/namespace_alias.cc index 2c8280f5..15cf5c65 100644 --- a/index_tests/namespaces/namespace_alias.cc +++ b/index_tests/namespaces/namespace_alias.cc @@ -150,7 +150,7 @@ OUTPUT: "storage": 1 }, { "id": 1, - "usr": 6030927277961448585, + "usr": 107714981785063096, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", @@ -164,7 +164,7 @@ OUTPUT: "storage": 1 }, { "id": 2, - "usr": 7657277353101371136, + "usr": 1200087780658383286, "detailed_name": "int b", "qual_name_offset": 4, "short_name": "b", diff --git a/index_tests/namespaces/namespace_reference.cc b/index_tests/namespaces/namespace_reference.cc index cf559e1c..5636a6f4 100644 --- a/index_tests/namespaces/namespace_reference.cc +++ b/index_tests/namespaces/namespace_reference.cc @@ -111,7 +111,7 @@ OUTPUT: "storage": 1 }, { "id": 1, - "usr": 3649375698083002347, + "usr": 7976909968919750794, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index 9d05094f..7782eea6 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -187,7 +187,7 @@ OUTPUT: static_function_in_type.cc }], "vars": [{ "id": 0, - "usr": 13569879755236306838, + "usr": 9285345059965948351, "detailed_name": "ns::Manager *m", "qual_name_offset": 13, "short_name": "m", diff --git a/index_tests/preprocessor/include_guard.cc b/index_tests/preprocessor/include_guard.cc index 592fab71..33a82ca3 100644 --- a/index_tests/preprocessor/include_guard.cc +++ b/index_tests/preprocessor/include_guard.cc @@ -12,7 +12,7 @@ OUTPUT: "funcs": [], "vars": [{ "id": 0, - "usr": 11674328179498211370, + "usr": 13076155634261037336, "detailed_name": "FOO", "qual_name_offset": 0, "short_name": "FOO", diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index 42a89405..c268b290 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -87,7 +87,7 @@ OUTPUT: "uses": ["10:26-10:32|-1|1|4", "13:13-13:19|-1|1|4", "14:14-14:20|-1|1|4"] }, { "id": 4, - "usr": 2205716167465743256, + "usr": 14511917000226829276, "detailed_name": "", "qual_name_offset": 0, "short_name": "", diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc index 840493fa..0d667a2d 100644 --- a/index_tests/templates/specialization.cc +++ b/index_tests/templates/specialization.cc @@ -83,7 +83,7 @@ OUTPUT: "uses": ["7:1-7:9|-1|1|4"] }, { "id": 2, - "usr": 9673599782548740467, + "usr": 10862637711685426953, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", @@ -100,7 +100,7 @@ OUTPUT: "uses": ["5:16-5:17|-1|1|4"] }, { "id": 3, - "usr": 7143192229126273961, + "usr": 756188769017350739, "detailed_name": "Args", "qual_name_offset": 0, "short_name": "Args", @@ -166,7 +166,7 @@ OUTPUT: "uses": ["31:1-31:7|-1|1|4"] }, { "id": 7, - "usr": 8880262253425334092, + "usr": 3421332160420436276, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", @@ -251,7 +251,7 @@ OUTPUT: "uses": [] }, { "id": 12, - "usr": 14111105212951082474, + "usr": 2461355892344618654, "detailed_name": "T", "qual_name_offset": 0, "short_name": "T", @@ -433,7 +433,7 @@ OUTPUT: "storage": 0 }, { "id": 7, - "usr": 17826688417349629938, + "usr": 10307767688451422448, "detailed_name": "T Value", "qual_name_offset": 2, "short_name": "Value", diff --git a/index_tests/templates/template_var_usage_folded_into_one.cc b/index_tests/templates/template_var_usage_folded_into_one.cc index 02e01c73..fd4bd404 100644 --- a/index_tests/templates/template_var_usage_folded_into_one.cc +++ b/index_tests/templates/template_var_usage_folded_into_one.cc @@ -71,7 +71,7 @@ OUTPUT: "uses": ["8:1-8:2|-1|1|4", "8:11-8:12|-1|1|4"] }, { "id": 2, - "usr": 11919899838872947844, + "usr": 8864163146308556810, "detailed_name": "", "qual_name_offset": 0, "short_name": "", diff --git a/index_tests/usage/func_usage_addr_func.cc b/index_tests/usage/func_usage_addr_func.cc index e87d6f34..8851f96e 100644 --- a/index_tests/usage/func_usage_addr_func.cc +++ b/index_tests/usage/func_usage_addr_func.cc @@ -64,7 +64,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 16088407831770615719, + "usr": 13681544683892648258, "detailed_name": "void (*)() x", "qual_name_offset": 11, "short_name": "x", diff --git a/index_tests/usage/func_usage_addr_method.cc b/index_tests/usage/func_usage_addr_method.cc index 52d5739c..3babaf65 100644 --- a/index_tests/usage/func_usage_addr_method.cc +++ b/index_tests/usage/func_usage_addr_method.cc @@ -67,7 +67,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 4636142131003982569, + "usr": 8436636043513449412, "detailed_name": "void (Foo::*)() x", "qual_name_offset": 16, "short_name": "x", diff --git a/index_tests/usage/func_usage_call_method.cc b/index_tests/usage/func_usage_call_method.cc index d18cc327..d2d33b00 100644 --- a/index_tests/usage/func_usage_call_method.cc +++ b/index_tests/usage/func_usage_call_method.cc @@ -67,7 +67,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 14045150712868309451, + "usr": 3014406561587537195, "detailed_name": "Foo *f", "qual_name_offset": 5, "short_name": "f", diff --git a/index_tests/usage/func_usage_forward_decl_method.cc b/index_tests/usage/func_usage_forward_decl_method.cc index 1d595bdf..0c5b0bbb 100644 --- a/index_tests/usage/func_usage_forward_decl_method.cc +++ b/index_tests/usage/func_usage_forward_decl_method.cc @@ -66,7 +66,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 16229832321010999607, + "usr": 12410753116854389823, "detailed_name": "Foo *f", "qual_name_offset": 5, "short_name": "f", diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc index 973043fb..e7cdd887 100644 --- a/index_tests/usage/type_usage_as_template_parameter.cc +++ b/index_tests/usage/type_usage_as_template_parameter.cc @@ -95,7 +95,7 @@ OUTPUT: "storage": 3 }, { "id": 2, - "usr": 3364438781074774169, + "usr": 2462000803278878465, "detailed_name": "unique_ptr *local", "qual_name_offset": 15, "short_name": "local", diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index e740286d..f5614cc8 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -228,7 +228,7 @@ OUTPUT: "storage": 2 }, { "id": 1, - "usr": 500112618220246, + "usr": 11547294959889394856, "detailed_name": "unique_ptr, S2> *local", "qual_name_offset": 36, "short_name": "local", diff --git a/index_tests/usage/type_usage_declare_local.cc b/index_tests/usage/type_usage_declare_local.cc index b501a77b..2822020d 100644 --- a/index_tests/usage/type_usage_declare_local.cc +++ b/index_tests/usage/type_usage_declare_local.cc @@ -63,7 +63,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 16374832544037266261, + "usr": 11033478034711123650, "detailed_name": "ForwardType *a", "qual_name_offset": 13, "short_name": "a", @@ -76,7 +76,7 @@ OUTPUT: "storage": 1 }, { "id": 1, - "usr": 2580122838476012357, + "usr": 8949902309768550158, "detailed_name": "ImplementedType b", "qual_name_offset": 16, "short_name": "b", diff --git a/index_tests/usage/type_usage_declare_param.cc b/index_tests/usage/type_usage_declare_param.cc index 60fccd12..b12d9ec3 100644 --- a/index_tests/usage/type_usage_declare_param.cc +++ b/index_tests/usage/type_usage_declare_param.cc @@ -60,7 +60,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 13058491096576226774, + "usr": 2584795197111552890, "detailed_name": "ForwardType *f", "qual_name_offset": 13, "short_name": "f", @@ -73,7 +73,7 @@ OUTPUT: "storage": 1 }, { "id": 1, - "usr": 11055777568039014776, + "usr": 5136230284979460117, "detailed_name": "ImplementedType a", "qual_name_offset": 16, "short_name": "a", diff --git a/index_tests/usage/type_usage_declare_param_prototype.cc b/index_tests/usage/type_usage_declare_param_prototype.cc index 05b6c4d4..7b16a92f 100644 --- a/index_tests/usage/type_usage_declare_param_prototype.cc +++ b/index_tests/usage/type_usage_declare_param_prototype.cc @@ -51,7 +51,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 13823260660189154978, + "usr": 2161866804398917919, "detailed_name": "Foo *f", "qual_name_offset": 5, "short_name": "f", diff --git a/index_tests/usage/type_usage_declare_qualifiers.cc b/index_tests/usage/type_usage_declare_qualifiers.cc index 799906b3..08621964 100644 --- a/index_tests/usage/type_usage_declare_qualifiers.cc +++ b/index_tests/usage/type_usage_declare_qualifiers.cc @@ -48,7 +48,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 7997456978847868736, + "usr": 16414210592877294238, "detailed_name": "Type &a0", "qual_name_offset": 6, "short_name": "a0", @@ -61,7 +61,7 @@ OUTPUT: "storage": 1 }, { "id": 1, - "usr": 17228576662112939520, + "usr": 11558141642862804306, "detailed_name": "const Type &a1", "qual_name_offset": 12, "short_name": "a1", @@ -74,7 +74,7 @@ OUTPUT: "storage": 1 }, { "id": 2, - "usr": 15429032129697337561, + "usr": 1536316608590232194, "detailed_name": "Type a2", "qual_name_offset": 5, "short_name": "a2", @@ -87,7 +87,7 @@ OUTPUT: "storage": 1 }, { "id": 3, - "usr": 6081981442495435784, + "usr": 316760354845869406, "detailed_name": "Type *a3", "qual_name_offset": 6, "short_name": "a3", @@ -100,7 +100,7 @@ OUTPUT: "storage": 1 }, { "id": 4, - "usr": 5004072032239834773, + "usr": 12321730890779907974, "detailed_name": "const Type *a4", "qual_name_offset": 12, "short_name": "a4", @@ -113,7 +113,7 @@ OUTPUT: "storage": 1 }, { "id": 5, - "usr": 14939253431683105646, + "usr": 4771437488905761633, "detailed_name": "const Type *const a5", "qual_name_offset": 18, "short_name": "a5", diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc index f948a0f7..a2ae182e 100644 --- a/index_tests/usage/type_usage_various.cc +++ b/index_tests/usage/type_usage_various.cc @@ -55,7 +55,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 16380484338511689669, + "usr": 14873619387499024780, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index 23988cc3..c005b4bf 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -132,7 +132,7 @@ OUTPUT: "storage": 0 }, { "id": 2, - "usr": 8039186520399841081, + "usr": 13284113377394221067, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", diff --git a/index_tests/usage/var_usage_call_function.cc b/index_tests/usage/var_usage_call_function.cc index e2d4f2fa..1c34a7f2 100644 --- a/index_tests/usage/var_usage_call_function.cc +++ b/index_tests/usage/var_usage_call_function.cc @@ -48,7 +48,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 9121974011454213596, + "usr": 3510529098767253033, "detailed_name": "void (*)() x", "qual_name_offset": 11, "short_name": "x", diff --git a/index_tests/usage/var_usage_class_member.cc b/index_tests/usage/var_usage_class_member.cc index d69730a6..003834a7 100644 --- a/index_tests/usage/var_usage_class_member.cc +++ b/index_tests/usage/var_usage_class_member.cc @@ -134,7 +134,7 @@ OUTPUT: "storage": 0 }, { "id": 2, - "usr": 14669930844300034456, + "usr": 16303259148898744165, "detailed_name": "Foo f", "qual_name_offset": 4, "short_name": "f", diff --git a/index_tests/usage/var_usage_local.cc b/index_tests/usage/var_usage_local.cc index 009367ea..64b460c6 100644 --- a/index_tests/usage/var_usage_local.cc +++ b/index_tests/usage/var_usage_local.cc @@ -42,7 +42,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 14014650769929566957, + "usr": 8534460107894911680, "detailed_name": "int x", "qual_name_offset": 4, "short_name": "x", diff --git a/index_tests/usage/var_usage_shadowed_local.cc b/index_tests/usage/var_usage_shadowed_local.cc index e63910aa..4e6bbe48 100644 --- a/index_tests/usage/var_usage_shadowed_local.cc +++ b/index_tests/usage/var_usage_shadowed_local.cc @@ -47,7 +47,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 13311055950748663970, + "usr": 17941402366659878910, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", @@ -60,7 +60,7 @@ OUTPUT: "storage": 1 }, { "id": 1, - "usr": 14036425367303419504, + "usr": 11094102496276744608, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", diff --git a/index_tests/usage/var_usage_shadowed_parameter.cc b/index_tests/usage/var_usage_shadowed_parameter.cc index b33d417c..2d3194ef 100644 --- a/index_tests/usage/var_usage_shadowed_parameter.cc +++ b/index_tests/usage/var_usage_shadowed_parameter.cc @@ -60,7 +60,7 @@ OUTPUT: "storage": 1 }, { "id": 1, - "usr": 6997229590862003559, + "usr": 8011559936501990179, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", diff --git a/index_tests/vars/deduce_auto_type.cc b/index_tests/vars/deduce_auto_type.cc index 801a2203..cfe0d4fd 100644 --- a/index_tests/vars/deduce_auto_type.cc +++ b/index_tests/vars/deduce_auto_type.cc @@ -46,7 +46,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 10601729374837386290, + "usr": 9275666070987716270, "detailed_name": "Foo *x", "qual_name_offset": 5, "short_name": "x", @@ -59,7 +59,7 @@ OUTPUT: "storage": 1 }, { "id": 1, - "usr": 18422884837902130475, + "usr": 16202433437488621027, "detailed_name": "Foo *y", "qual_name_offset": 5, "short_name": "y", diff --git a/index_tests/vars/function_local.cc b/index_tests/vars/function_local.cc index 16e4995d..eef83fc4 100644 --- a/index_tests/vars/function_local.cc +++ b/index_tests/vars/function_local.cc @@ -44,7 +44,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 13198746475679542317, + "usr": 10782632605670042066, "detailed_name": "Foo *a", "qual_name_offset": 5, "short_name": "a", diff --git a/index_tests/vars/function_param.cc b/index_tests/vars/function_param.cc index cfd28001..df37bff6 100644 --- a/index_tests/vars/function_param.cc +++ b/index_tests/vars/function_param.cc @@ -42,7 +42,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 8730439006497971620, + "usr": 4580260577538694711, "detailed_name": "Foo *p0", "qual_name_offset": 5, "short_name": "p0", @@ -55,7 +55,7 @@ OUTPUT: "storage": 1 }, { "id": 1, - "usr": 2525014371090380500, + "usr": 12071725611268840435, "detailed_name": "Foo *p1", "qual_name_offset": 5, "short_name": "p1", diff --git a/index_tests/vars/function_shadow_local.cc b/index_tests/vars/function_shadow_local.cc index 53fa645e..a27f8169 100644 --- a/index_tests/vars/function_shadow_local.cc +++ b/index_tests/vars/function_shadow_local.cc @@ -47,7 +47,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 1894874819807168345, + "usr": 3440226937504376525, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", @@ -60,7 +60,7 @@ OUTPUT: "storage": 1 }, { "id": 1, - "usr": 4508045017817092115, + "usr": 14700715011944976607, "detailed_name": "int a", "qual_name_offset": 4, "short_name": "a", diff --git a/index_tests/vars/function_shadow_param.cc b/index_tests/vars/function_shadow_param.cc index cab3e40d..b4fdf18a 100644 --- a/index_tests/vars/function_shadow_param.cc +++ b/index_tests/vars/function_shadow_param.cc @@ -54,7 +54,7 @@ OUTPUT: "storage": 1 }, { "id": 1, - "usr": 11404600766177939811, + "usr": 2147918703972955240, "detailed_name": "int p", "qual_name_offset": 4, "short_name": "p", diff --git a/index_tests/vars/type_instance_on_using_type.cc b/index_tests/vars/type_instance_on_using_type.cc index f61dd2c1..654030b4 100644 --- a/index_tests/vars/type_instance_on_using_type.cc +++ b/index_tests/vars/type_instance_on_using_type.cc @@ -67,7 +67,7 @@ OUTPUT: }], "vars": [{ "id": 0, - "usr": 6975456769752895964, + "usr": 7730100248624586522, "detailed_name": "F a", "qual_name_offset": 2, "short_name": "a", diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 465df042..05a89ed8 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -1,6 +1,7 @@ #include "clang_complete.h" #include "clang_utils.h" +#include "filesystem.hh" #include "platform.h" #include "timer.h" @@ -27,6 +28,11 @@ unsigned Flags() { ; } +std::string StripFileType(const std::string& path) { + fs::path p(path); + return p.parent_path() / p.stem(); +} + unsigned GetCompletionPriority(const CXCompletionString& str, CXCursorKind result_kind, const std::optional& typedText) { @@ -671,12 +677,12 @@ ClangCompleteManager::ClangCompleteManager(Project* project, preloaded_sessions_(kMaxPreloadedSessions), completion_sessions_(kMaxCompletionSessions) { new std::thread([&]() { - SetCurrentThreadName("completequery"); + SetThreadName("completequery"); CompletionQueryMain(this); }); new std::thread([&]() { - SetCurrentThreadName("completeparse"); + SetThreadName("completeparse"); CompletionParseMain(this); }); } diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index 1167416d..b03ef730 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -2304,7 +2304,7 @@ std::vector> ParseWithTu( if (ls_diagnostic.severity != lsDiagnosticSeverity::Error) continue; ls_diagnostic.range = - lsRange(lsPosition(line, 10), lsPosition(line, 10)); + lsRange{lsPosition{line, 10}, lsPosition{line, 10}}; param.primary_file->diagnostics_.push_back(ls_diagnostic); break; } diff --git a/src/clang_utils.cc b/src/clang_utils.cc index 2a79b847..b9da4daf 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -15,8 +15,8 @@ lsRange GetLsRangeForFixIt(const CXSourceRange& range) { unsigned int end_line, end_column; clang_getSpellingLocation(end, nullptr, &end_line, &end_column, nullptr); - return lsRange(lsPosition(start_line - 1, start_column - 1) /*start*/, - lsPosition(end_line - 1, end_column) /*end*/); + return lsRange{lsPosition{int(start_line) - 1, int(start_column) - 1}, + lsPosition{int(end_line) - 1, int(end_column)}}; } } // namespace @@ -59,8 +59,8 @@ std::optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, // Build diagnostic. lsDiagnostic ls_diagnostic; - ls_diagnostic.range = lsRange(lsPosition(start_line - 1, start_column - 1), - lsPosition(end_line - 1, end_column - 1)); + ls_diagnostic.range = lsRange{{int(start_line) - 1, int(start_column) - 1}, + {int(end_line) - 1, int(end_column) - 1}}; ls_diagnostic.message = ToString(clang_getDiagnosticSpelling(diagnostic)); diff --git a/src/command_line.cc b/src/command_line.cc index 2cbc311e..6eb15596 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -31,9 +31,9 @@ #include #include #include -#include #include #include +#include #include #include @@ -76,8 +76,7 @@ bool ShouldDisplayMethodTiming(MethodType type) { } void PrintHelp() { - std::cout - << R"help(ccls is a C/C++/Objective-C language server. + printf("%s", R"help(ccls is a C/C++/Objective-C language server. Mode: --test-unit Run unit tests. @@ -101,7 +100,7 @@ Other command line options: out. See more on https://github.com/MaskRay/ccls/wiki -)help"; +)help"); } } // namespace @@ -214,7 +213,7 @@ void RunQueryDbThread(const std::string& bin_name, } // Run query db main loop. - SetCurrentThreadName("querydb"); + SetThreadName("querydb"); while (true) { bool did_work = QueryDbMainLoop( &db, querydb_waiter, &project, &file_consumer_shared, @@ -244,11 +243,8 @@ void RunQueryDbThread(const std::string& bin_name, // // |ipc| is connected to a server. void LaunchStdinLoop(std::unordered_map* request_times) { - // If flushing cin requires flushing cout there could be deadlocks in some - // clients. - std::cin.tie(nullptr); - - StartThread("stdin", [request_times]() { + new std::thread([request_times]() { + SetThreadName("stdin"); auto* queue = QueueManager::instance(); while (true) { std::unique_ptr message; @@ -288,7 +284,8 @@ void LaunchStdinLoop(std::unordered_map* request_times) { void LaunchStdoutThread(std::unordered_map* request_times, MultiQueueWaiter* waiter) { - StartThread("stdout", [=]() { + new std::thread([=]() { + SetThreadName("stdout"); auto* queue = QueueManager::instance(); while (true) { @@ -387,9 +384,8 @@ int main(int argc, char** argv) { rapidjson::Document reader; rapidjson::ParseResult ok = reader.Parse(g_init_options.c_str()); if (!ok) { - std::cerr << "Failed to parse --init as JSON: " - << rapidjson::GetParseError_En(ok.Code()) << " (" - << ok.Offset() << ")\n"; + fprintf(stderr, "Failed to parse --init as JSON: %s (%zd)\n", + rapidjson::GetParseError_En(ok.Code()), ok.Offset()); return 1; } JsonReader json_reader{&reader}; @@ -397,9 +393,9 @@ int main(int argc, char** argv) { Config config; Reflect(json_reader, config); } catch (std::invalid_argument& e) { - std::cerr << "Fail to parse --init " - << static_cast(json_reader).GetPath() - << ", expected " << e.what() << "\n"; + fprintf(stderr, "Failed to parse --init %s, expected %s\n", + static_cast(json_reader).GetPath().c_str(), + e.what()); return 1; } } diff --git a/src/filesystem.cc b/src/filesystem.cc new file mode 100644 index 00000000..be32b081 --- /dev/null +++ b/src/filesystem.cc @@ -0,0 +1,43 @@ +#include "filesystem.hh" + +#include "utils.h" + +#include +#include + +static void GetFilesInFolderHelper( + std::string folder, + bool recursive, + std::string output_prefix, + const std::function& handler) { + std::queue> q; + q.emplace(fs::path(folder), fs::path(output_prefix)); + while (!q.empty()) { + for (auto it = fs::directory_iterator(q.front().first); it != fs::directory_iterator(); ++it) { + auto path = it->path(); + std::string filename = path.filename(); + if (filename[0] != '.' || filename == ".ccls") { + fs::file_status status = it->symlink_status(); + if (fs::is_regular_file(status)) + handler(q.front().second / filename); + else if (fs::is_directory(status) || fs::is_symlink(status)) { + if (recursive) { + std::string child_dir = q.front().second / filename; + if (fs::is_directory(status)) + q.push(make_pair(path, child_dir)); + } + } + } + } + q.pop(); + } +} + +void GetFilesInFolder(std::string folder, + bool recursive, + bool add_folder_to_path, + const std::function& handler) { + EnsureEndsInSlash(folder); + GetFilesInFolderHelper(folder, recursive, add_folder_to_path ? folder : "", + handler); +} diff --git a/src/filesystem.hh b/src/filesystem.hh index 0608bd71..dedce15e 100644 --- a/src/filesystem.hh +++ b/src/filesystem.hh @@ -1,5 +1,12 @@ #pragma once #include +#include +#include namespace fs = std::experimental::filesystem; + +void GetFilesInFolder(std::string folder, + bool recursive, + bool add_folder_to_path, + const std::function& handler); diff --git a/src/include_complete.cc b/src/include_complete.cc index f9d55f92..f44bedcc 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -1,11 +1,14 @@ #include "include_complete.h" +#include "filesystem.hh" #include "match.h" #include "platform.h" #include "project.h" #include "standard_includes.h" #include "timer.h" +#include + namespace { struct CompletionCandidate { @@ -112,7 +115,8 @@ void IncludeComplete::Rescan() { g_config->completion.includeBlacklist); is_scanning = true; - StartThread("scan_includes", [this]() { + new std::thread([this]() { + SetThreadName("scan_includes"); Timer timer; InsertStlIncludes(); diff --git a/src/lex_utils.cc b/src/lex_utils.cc index deb6ece9..6045eb9d 100644 --- a/src/lex_utils.cc +++ b/src/lex_utils.cc @@ -69,21 +69,21 @@ std::pair CaseFoldingSubsequenceMatch(std::string_view search, TEST_SUITE("Offset") { TEST_CASE("past end") { std::string content = "foo"; - int offset = GetOffsetForPosition(lsPosition(10, 10), content); + int offset = GetOffsetForPosition(lsPosition{10, 10}, content); REQUIRE(offset <= content.size()); } TEST_CASE("in middle of content") { std::string content = "abcdefghijk"; for (int i = 0; i < content.size(); ++i) { - int offset = GetOffsetForPosition(lsPosition(0, i), content); + int offset = GetOffsetForPosition(lsPosition{0, i}, content); REQUIRE(i == offset); } } TEST_CASE("at end of content") { - REQUIRE(GetOffsetForPosition(lsPosition(0, 0), "") == 0); - REQUIRE(GetOffsetForPosition(lsPosition(0, 1), "a") == 1); + REQUIRE(GetOffsetForPosition(lsPosition{0, 0}, "") == 0); + REQUIRE(GetOffsetForPosition(lsPosition{0, 1}, "a") == 1); } } diff --git a/src/lsp.cc b/src/lsp.cc index 251a52d7..1c1c6673 100644 --- a/src/lsp.cc +++ b/src/lsp.cc @@ -269,46 +269,9 @@ std::string lsDocumentUri::GetPath() const { return ret; } -lsPosition::lsPosition() {} -lsPosition::lsPosition(int line, int character) - : line(line), character(character) {} - -bool lsPosition::operator==(const lsPosition& other) const { - return line == other.line && character == other.character; -} - -bool lsPosition::operator<(const lsPosition& other) const { - return line != other.line ? line < other.line : character < other.character; -} - std::string lsPosition::ToString() const { return std::to_string(line) + ":" + std::to_string(character); } -const lsPosition lsPosition::kZeroPosition = lsPosition(); - -lsRange::lsRange() {} -lsRange::lsRange(lsPosition start, lsPosition end) : start(start), end(end) {} - -bool lsRange::operator==(const lsRange& o) const { - return start == o.start && end == o.end; -} - -bool lsRange::operator<(const lsRange& o) const { - return !(start == o.start) ? start < o.start : end < o.end; -} - -lsLocation::lsLocation() {} -lsLocation::lsLocation(lsDocumentUri uri, lsRange range) - : uri(uri), range(range) {} - -bool lsLocation::operator==(const lsLocation& o) const { - return uri == o.uri && range == o.range; -} - -bool lsLocation::operator<(const lsLocation& o) const { - return std::make_tuple(uri.raw_uri, range) < - std::make_tuple(o.uri.raw_uri, o.range); -} bool lsTextEdit::operator==(const lsTextEdit& that) { return range == that.range && newText == that.newText; diff --git a/src/lsp.h b/src/lsp.h index 32692db3..e3fc6555 100644 --- a/src/lsp.h +++ b/src/lsp.h @@ -121,44 +121,42 @@ void Reflect(TVisitor& visitor, lsDocumentUri& value) { } struct lsPosition { - lsPosition(); - lsPosition(int line, int character); - - bool operator==(const lsPosition& other) const; - bool operator<(const lsPosition& other) const; - - std::string ToString() const; - - // Note: these are 0-based. int line = 0; int character = 0; - static const lsPosition kZeroPosition; + bool operator==(const lsPosition& o) const { + return line == o.line && character == o.character; + } + bool operator<(const lsPosition& o) const { + return line != o.line ? line < o.line : character < o.character; + } + std::string ToString() const; }; MAKE_HASHABLE(lsPosition, t.line, t.character); MAKE_REFLECT_STRUCT(lsPosition, line, character); struct lsRange { - lsRange(); - lsRange(lsPosition start, lsPosition end); - - bool operator==(const lsRange& other) const; - bool operator<(const lsRange& other) const; - lsPosition start; lsPosition end; + bool operator==(const lsRange& o) const { + return start == o.start && end == o.end; + } + bool operator<(const lsRange& o) const { + return !(start == o.start) ? start < o.start : end < o.end; + } }; MAKE_HASHABLE(lsRange, t.start, t.end); MAKE_REFLECT_STRUCT(lsRange, start, end); struct lsLocation { - lsLocation(); - lsLocation(lsDocumentUri uri, lsRange range); - - bool operator==(const lsLocation& other) const; - bool operator<(const lsLocation& o) const; - lsDocumentUri uri; lsRange range; + bool operator==(const lsLocation& o) const { + return uri == o.uri && range == o.range; + } + bool operator<(const lsLocation& o) const { + return !(uri.raw_uri == o.uri.raw_uri) ? uri.raw_uri < o.uri.raw_uri + : range < o.range; + } }; MAKE_HASHABLE(lsLocation, t.uri, t.range); MAKE_REFLECT_STRUCT(lsLocation, uri, range); diff --git a/src/message_handler.cc b/src/message_handler.cc index 78b32eec..7c0fd96e 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -332,8 +332,8 @@ void EmitSemanticHighlighting(QueryDatabase* db, // Attribute range [events[i-1].pos, events[i].pos) to events[top-1].symbol // . if (top && !(events[i - 1].pos == events[i].pos)) - events[top - 1].symbol->ranges.emplace_back(events[i - 1].pos, - events[i].pos); + events[top - 1].symbol->ranges.push_back( + lsRange{events[i - 1].pos, events[i].pos}); if (events[i].id >= 0) events[top++] = events[i]; else diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 37440fa9..d2aa5167 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -517,11 +517,12 @@ struct Handler_Initialize : BaseMessageHandler { std::max(int(std::thread::hardware_concurrency() * 0.8), 1); } LOG_S(INFO) << "Starting " << g_config->index.threads << " indexers"; - for (int i = 0; i < g_config->index.threads; ++i) { - StartThread("indexer" + std::to_string(i), [=]() { - Indexer_Main(diag_engine, file_consumer_shared, - timestamp_manager, import_manager, - import_pipeline_status, project, working_files, waiter); + for (int i = 0; i < g_config->index.threads; i++) { + new std::thread([=]() { + SetThreadName("indexer" + std::to_string(i)); + Indexer_Main(diag_engine, file_consumer_shared, timestamp_manager, + import_manager, import_pipeline_status, project, + working_files, waiter); }); } diff --git a/src/platform.h b/src/platform.h index e2903606..b8a36bf3 100644 --- a/src/platform.h +++ b/src/platform.h @@ -12,7 +12,7 @@ void PlatformInit(); std::string GetExecutablePath(); std::string NormalizePath(const std::string& path); -void SetCurrentThreadName(const std::string& thread_name); +void SetThreadName(const std::string& thread_name); std::optional GetLastModificationTime(const std::string& absolute_path); diff --git a/src/platform_posix.cc b/src/platform_posix.cc index ea9da8ca..6af30d70 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -155,7 +155,7 @@ std::string NormalizePath(const std::string& path) { return resolved ? *resolved : path; } -void SetCurrentThreadName(const std::string& thread_name) { +void SetThreadName(const std::string& thread_name) { loguru::set_thread_name(thread_name.c_str()); #if defined(__APPLE__) pthread_setname_np(thread_name.c_str()); diff --git a/src/platform_win.cc b/src/platform_win.cc index c6c4df3f..f4c71a95 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -15,7 +15,6 @@ #include #include -#include #include void PlatformInit() { @@ -60,7 +59,7 @@ typedef struct tagTHREADNAME_INFO { DWORD dwFlags; // Reserved for future use, must be zero. } THREADNAME_INFO; #pragma pack(pop) -void SetCurrentThreadName(const std::string& thread_name) { +void SetThreadName(const std::string& thread_name) { loguru::set_thread_name(thread_name.c_str()); THREADNAME_INFO info; diff --git a/src/project.cc b/src/project.cc index 74790c75..4ced67fb 100644 --- a/src/project.cc +++ b/src/project.cc @@ -21,6 +21,7 @@ #include #endif +#include #include #include #include @@ -47,7 +48,7 @@ struct ProjectConfig { std::unordered_set quote_dirs; std::unordered_set angle_dirs; std::vector extra_flags; - std::string project_dir; + fs::path project_dir; ProjectMode mode = ProjectMode::CompileCommandsJson; }; @@ -107,7 +108,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( const CompileCommandsEntry& entry) { Project::Entry result; result.filename = entry.file; - const std::string base_name = GetBaseName(entry.file); + const std::string base_name = fs::path(entry.file).filename(); // Expand %c %cpp %clang std::vector args; @@ -256,7 +257,8 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( std::vector ReadCompilerArgumentsFromFile( const std::string& path) { std::vector args; - for (std::string line : ReadFileLines(path)) { + std::ifstream fin(path); + for (std::string line; std::getline(fin, line);) { TrimInPlace(line); if (line.empty() || StartsWith(line, "#")) continue; @@ -268,7 +270,7 @@ std::vector ReadCompilerArgumentsFromFile( std::vector LoadFromDirectoryListing(ProjectConfig* config) { std::vector result; config->mode = ProjectMode::DotCcls; - LOG_IF_S(WARNING, !FileExists(config->project_dir + "/.ccls") && + LOG_IF_S(WARNING, !fs::exists(config->project_dir / ".ccls") && config->extra_flags.empty()) << "ccls has no clang arguments. Considering adding either a " "compile_commands.json or .ccls file. See the ccls README for " @@ -282,31 +284,31 @@ std::vector LoadFromDirectoryListing(ProjectConfig* config) { [&folder_args, &files](const std::string& path) { if (SourceFileLanguage(path) != LanguageId::Unknown) { files.push_back(path); - } else if (GetBaseName(path) == ".ccls") { + } else if (fs::path(path).filename() == ".ccls") { LOG_S(INFO) << "Using .ccls arguments from " << path; - folder_args.emplace(GetDirName(path), - ReadCompilerArgumentsFromFile(path)); + folder_args.emplace( + fs::path(path).parent_path().string(), + ReadCompilerArgumentsFromFile(path)); } }); - const auto& project_dir_args = folder_args[config->project_dir]; + const std::string project_dir = config->project_dir.string(); + const auto& project_dir_args = folder_args[project_dir]; LOG_IF_S(INFO, !project_dir_args.empty()) << "Using .ccls arguments " << StringJoin(project_dir_args); - auto GetCompilerArgumentForFile = [&config, - &folder_args](const std::string& path) { - for (std::string cur = GetDirName(path);; cur = GetDirName(cur)) { + auto GetCompilerArgumentForFile = [&project_dir, &folder_args](fs::path cur) { + while (!(cur = cur.parent_path()).empty()) { auto it = folder_args.find(cur); if (it != folder_args.end()) return it->second; std::string normalized = NormalizePath(cur); // Break if outside of the project root. - if (normalized.size() <= config->project_dir.size() || - normalized.compare(0, config->project_dir.size(), - config->project_dir) != 0) + if (normalized.size() <= project_dir.size() || + normalized.compare(0, project_dir.size(), project_dir) != 0) break; } - return folder_args[config->project_dir]; + return folder_args[project_dir]; }; for (const std::string& file : files) { @@ -327,7 +329,7 @@ std::vector LoadCompilationEntriesFromDirectory( ProjectConfig* project, const std::string& opt_compilation_db_dir) { // If there is a .ccls file always load using directory listing. - if (FileExists(project->project_dir + ".ccls")) + if (fs::exists(project->project_dir / ".ccls")) return LoadFromDirectoryListing(project); // If |compilationDatabaseCommand| is specified, execute it to get the compdb. @@ -335,7 +337,7 @@ std::vector LoadCompilationEntriesFromDirectory( if (g_config->compilationDatabaseCommand.empty()) { project->mode = ProjectMode::CompileCommandsJson; // Try to load compile_commands.json, but fallback to a project listing. - comp_db_dir = opt_compilation_db_dir.empty() ? project->project_dir + comp_db_dir = opt_compilation_db_dir.empty() ? project->project_dir.string() : opt_compilation_db_dir; } else { project->mode = ProjectMode::ExternalCommand; @@ -522,11 +524,14 @@ Project::Entry Project::FindCompilationEntryForFile( // |best_entry| probably has its own path in the arguments. We need to remap // that path to the new filename. - std::string best_entry_base_name = GetBaseName(best_entry->filename); + fs::path best_entry_base_name = fs::path(best_entry->filename).filename(); for (std::string& arg : result.args) { - if (arg == best_entry->filename || - GetBaseName(arg) == best_entry_base_name) { - arg = filename; + try { + if (arg == best_entry->filename || + fs::path(arg).filename() == best_entry_base_name) { + arg = filename; + } + } catch (...) { } } } @@ -669,7 +674,7 @@ TEST_SUITE("Project") { "--foobar", "-Ia_relative1", "--foobar", - "-I", + "-isystem", "a_relative2", "--foobar", "-iquote/q_absolute1", @@ -691,7 +696,8 @@ TEST_SUITE("Project") { "/a_absolute1", "/a_absolute2", "/base/a_relative1", "/base/a_relative2"}; std::unordered_set quote_expected{ - "/q_absolute1", "/q_absolute2", "/base/q_relative1", + "/a_absolute1", "/a_absolute2", "/base/a_relative1", + "/q_absolute1", "/q_absolute2", "/base/q_relative1", "/base/q_relative2"}; REQUIRE(config.angle_dirs == angle_expected); REQUIRE(config.quote_dirs == quote_expected); diff --git a/src/query_utils.cc b/src/query_utils.cc index a016fedc..bf61ba64 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -158,19 +158,19 @@ std::vector GetUsesForAllDerived(QueryDatabase* db, QueryFunc& root) { std::optional GetLsPosition(WorkingFile* working_file, const Position& position) { if (!working_file) - return lsPosition(position.line, position.column); + return lsPosition{position.line, position.column}; int column = position.column; if (std::optional start = working_file->GetBufferPosFromIndexPos(position.line, &column, false)) - return lsPosition(*start, column); + return lsPosition{*start, column}; return std::nullopt; } std::optional GetLsRange(WorkingFile* working_file, const Range& location) { if (!working_file) { - return lsRange(lsPosition(location.start.line, location.start.column), - lsPosition(location.end.line, location.end.column)); + return lsRange{lsPosition{location.start.line, location.start.column}, + lsPosition{location.end.line, location.end.column}}; } int start_column = location.start.column, end_column = location.end.column; @@ -192,8 +192,8 @@ std::optional GetLsRange(WorkingFile* working_file, const Range& locati if (*start == *end && start_column > end_column) end_column = start_column; - return lsRange(lsPosition(*start, start_column), - lsPosition(*end, end_column)); + return lsRange{lsPosition{*start, start_column}, + lsPosition{*end, end_column}}; } lsDocumentUri GetLsDocumentUri(QueryDatabase* db, @@ -227,7 +227,7 @@ std::optional GetLsLocation(QueryDatabase* db, GetLsRange(working_files->GetFileByFilename(path), use.range); if (!range) return std::nullopt; - return lsLocation(uri, *range); + return lsLocation{uri, *range}; } std::optional GetLsLocationEx(QueryDatabase* db, diff --git a/src/serializer.cc b/src/serializer.cc index 391a5999..978e2550 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -1,11 +1,11 @@ #include "serializer.h" +#include "filesystem.hh" #include "serializers/json.h" #include "serializers/msgpack.h" #include "indexer.h" -#include #include #include @@ -153,7 +153,7 @@ void Reflect(Writer& visitor, IndexInclude& value) { REFLECT_MEMBER_START(); REFLECT_MEMBER(line); if (gTestOutputMode) { - std::string basename = GetBaseName(value.resolved_path); + std::string basename = fs::path(value.resolved_path).filename(); if (!StartsWith(value.resolved_path, "&")) basename = "&" + basename; REFLECT_MEMBER2("resolved_path", basename); @@ -279,7 +279,7 @@ bool ReflectMemberStart(Writer& visitor, IndexFile& value) { assert(value.Resolve(it->second)->uses.size() == 0); } - DefaultReflectMemberStart(visitor); + visitor.StartObject(); return true; } template @@ -441,17 +441,3 @@ std::unique_ptr Deserialize( return file; } - -void SetTestOutputMode() { - gTestOutputMode = true; -} - -TEST_SUITE("Serializer utils") { - TEST_CASE("GetBaseName") { - REQUIRE(GetBaseName("foo.cc") == "foo.cc"); - REQUIRE(GetBaseName("foo/foo.cc") == "foo.cc"); - REQUIRE(GetBaseName("/foo.cc") == "foo.cc"); - REQUIRE(GetBaseName("///foo.cc") == "foo.cc"); - REQUIRE(GetBaseName("bar/") == "."); - } -} diff --git a/src/serializer.h b/src/serializer.h index b2b9b65c..5807a595 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -25,7 +25,6 @@ class Reader { virtual bool IsBool() = 0; virtual bool IsNull() = 0; - virtual bool IsArray() = 0; virtual bool IsInt() = 0; virtual bool IsInt64() = 0; virtual bool IsUint64() = 0; @@ -73,7 +72,6 @@ struct IndexFile; #define REFLECT_MEMBER_START() ReflectMemberStart(visitor, value) #define REFLECT_MEMBER_END() ReflectMemberEnd(visitor, value); -#define REFLECT_MEMBER_END1(value) ReflectMemberEnd(visitor, value); #define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name) #define REFLECT_MEMBER2(name, value) ReflectMember(visitor, name, value) @@ -315,11 +313,6 @@ void Reflect(Writer& visitor, std::vector& values) { // ReflectMember -inline void DefaultReflectMemberStart(Writer& visitor) { - visitor.StartObject(); -} -inline void DefaultReflectMemberStart(Reader& visitor) {} - template bool ReflectMemberStart(Reader& visitor, T& value) { return false; @@ -356,5 +349,3 @@ std::unique_ptr Deserialize( const std::string& serialized_index_content, const std::string& file_content, std::optional expected_version); - -void SetTestOutputMode(); diff --git a/src/serializers/json.h b/src/serializers/json.h index 47e3b035..aa9d5f0f 100644 --- a/src/serializers/json.h +++ b/src/serializers/json.h @@ -15,7 +15,6 @@ class JsonReader : public Reader { bool IsBool() override { return m_->IsBool(); } bool IsNull() override { return m_->IsNull(); } - bool IsArray() override { return m_->IsArray(); } bool IsInt() override { return m_->IsInt(); } bool IsInt64() override { return m_->IsInt64(); } bool IsUint64() override { return m_->IsUint64(); } diff --git a/src/serializers/msgpack.h b/src/serializers/msgpack.h index f9b1666b..83ea5983 100644 --- a/src/serializers/msgpack.h +++ b/src/serializers/msgpack.h @@ -23,7 +23,6 @@ class MessagePackReader : public Reader { bool IsBool() override { return oh_.get().type == msgpack::type::BOOLEAN; } bool IsNull() override { return oh_.get().is_nil(); } - bool IsArray() override { return oh_.get().type == msgpack::type::ARRAY; } bool IsInt() override { return oh_.get().type == msgpack::type::POSITIVE_INTEGER || oh_.get().type == msgpack::type::NEGATIVE_INTEGER; diff --git a/src/test.cc b/src/test.cc index f94e447e..a8075815 100644 --- a/src/test.cc +++ b/src/test.cc @@ -1,5 +1,6 @@ #include "test.h" +#include "filesystem.hh" #include "indexer.h" #include "platform.h" #include "serializer.h" @@ -15,7 +16,6 @@ #include #include #include -#include // The 'diff' utility is available and we can use dprintf(3). #if _POSIX_C_SOURCE >= 200809L @@ -23,6 +23,8 @@ #include #endif +extern bool gTestOutputMode; + std::string ToString(const rapidjson::Document& document) { rapidjson::StringBuffer buffer; rapidjson::PrettyWriter writer(buffer); @@ -35,6 +37,33 @@ std::string ToString(const rapidjson::Document& document) { return buffer.GetString(); } +struct TextReplacer { + struct Replacement { + std::string from; + std::string to; + }; + + std::vector replacements; + + std::string Apply(const std::string& content) { + std::string result = content; + + for (const Replacement& replacement : replacements) { + while (true) { + size_t idx = result.find(replacement.from); + if (idx == std::string::npos) + break; + + result.replace(result.begin() + idx, + result.begin() + idx + replacement.from.size(), + replacement.to); + } + } + + return result; + } +}; + void ParseTestExpectation( const std::string& filename, const std::vector& lines_with_endings, @@ -125,8 +154,7 @@ void DiffDocuments(std::string path, rapidjson::Document& actual) { std::string joined_actual_output = ToString(actual); std::string joined_expected_output = ToString(expected); - std::cout << "[FAILED] " << path << " (section " << path_section << ")" - << std::endl; + printf("[FAILED] %s (section %s)\n", path.c_str(), path_section.c_str()); #if _POSIX_C_SOURCE >= 200809L char expected_file[] = "/tmp/ccls.expected.XXXXXX"; @@ -156,13 +184,10 @@ void DiffDocuments(std::string path, std::vector expected_output = SplitString(joined_expected_output, "\n"); - std::cout << "Expected output for " << path << " (section " << path_section - << "):" << std::endl; - std::cout << joined_expected_output << std::endl; - std::cout << "Actual output for " << path << " (section " << path_section - << "):" << std::endl; - std::cout << joined_actual_output << std::endl; - std::cout << std::endl; + printf("Expected output for %s (section %s)\n:%s\n", path.c_str(), + path_section.c_str(), joined_expected_output.c_str()); + printf("Actual output for %s (section %s)\n:%s\n", path.c_str(), + path_section.c_str(), joined_actual_output.c_str()); } void VerifySerializeToFrom(IndexFile* file) { @@ -173,7 +198,7 @@ void VerifySerializeToFrom(IndexFile* file) { std::nullopt /*expected_version*/); std::string actual = result->ToString(); if (expected != actual) { - std::cerr << "Serialization failure" << std::endl; + fprintf(stderr, "Serialization failure\n"); assert(false); } } @@ -186,7 +211,7 @@ std::string FindExpectedOutputForFilename( return entry.second; } - std::cerr << "Couldn't find expected output for " << filename << std::endl; + fprintf(stderr, "Couldn't find expected output for %s\n", filename.c_str()); getchar(); getchar(); return "{}"; @@ -203,16 +228,17 @@ IndexFile* FindDbForPathEnding( } bool RunIndexTests(const std::string& filter_path, bool enable_update) { - SetTestOutputMode(); + gTestOutputMode = true; // Index tests change based on the version of clang used. - static constexpr const char* kRequiredClangVersion = + static const char kRequiredClangVersion[] = "clang version 6.0.0 (tags/RELEASE_600/final)"; if (GetClangVersion() != kRequiredClangVersion && GetClangVersion().find("trunk") == std::string::npos) { - std::cerr << "Index tests must be run using clang version \"" - << kRequiredClangVersion << "\" (ccls is running with \"" - << GetClangVersion() << "\")" << std::endl; + fprintf(stderr, + "Index tests must be run using clang version %s, ccls is running " + "with %s\n", + kRequiredClangVersion, GetClangVersion().c_str()); return false; } @@ -221,141 +247,141 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { // FIXME: show diagnostics in STL/headers when running tests. At the moment // this can be done by constructing ClangIndex index(1, 1); ClangIndex index; - for (std::string path : GetFilesInFolder("index_tests", true /*recursive*/, - true /*add_folder_to_path*/)) { - bool is_fail_allowed = false; + GetFilesInFolder( + "index_tests", true /*recursive*/, true /*add_folder_to_path*/, + [&](const std::string& path) { + bool is_fail_allowed = false; - if (EndsWithAny(path, {".m", ".mm"})) { + if (EndsWithAny(path, {".m", ".mm"})) { #ifndef __APPLE__ - std::cout << "Skipping \"" << path << "\" since this platform does not " - << "support running Objective-C tests." << std::endl; - continue; + return; #endif - // objective-c tests are often not updated right away. do not bring down - // CI if they fail. - if (!enable_update) - is_fail_allowed = true; - } - - if (path.find(filter_path) == std::string::npos) - continue; - - if (!filter_path.empty()) - std::cout << "Running " << path << std::endl; - - // Parse expected output from the test, parse it into JSON document. - std::vector lines_with_endings = ReadFileLines(path); - TextReplacer text_replacer; - std::vector flags; - std::unordered_map all_expected_output; - ParseTestExpectation(path, lines_with_endings, &text_replacer, &flags, - &all_expected_output); - - // Build flags. - bool had_extra_flags = !flags.empty(); - if (!AnyStartsWith(flags, "-x")) - flags.push_back("-xc++"); - flags.push_back("-resource-dir=" + GetDefaultResourceDirectory()); - if (had_extra_flags) { - std::cout << "For " << path << std::endl; - std::cout << " flags: " << StringJoin(flags) << std::endl; - } - flags.push_back(path); - - // Run test. - g_config = std::make_unique(); - FileConsumerSharedState file_consumer_shared; - PerformanceImportFile perf; - auto dbs = Parse(&file_consumer_shared, path, flags, {}, &perf, &index, - false /*dump_ast*/); - - for (const auto& entry : all_expected_output) { - const std::string& expected_path = entry.first; - std::string expected_output = text_replacer.Apply(entry.second); - - // FIXME: promote to utils, find and remove duplicates (ie, - // ccls_call_tree.cc, maybe something in project.cc). - auto basename = [](const std::string& path) -> std::string { - size_t last_index = path.find_last_of('/'); - if (last_index == std::string::npos) - return path; - return path.substr(last_index + 1); - }; - - auto severity_to_string = [](const lsDiagnosticSeverity& severity) { - switch (severity) { - case lsDiagnosticSeverity::Error: - return "error "; - case lsDiagnosticSeverity::Warning: - return "warning "; - case lsDiagnosticSeverity::Information: - return "information "; - case lsDiagnosticSeverity::Hint: - return "hint "; + // objective-c tests are often not updated right away. do not bring + // down + // CI if they fail. + if (!enable_update) + is_fail_allowed = true; } - assert(false && "not reached"); - return ""; - }; - // Get output from index operation. - IndexFile* db = FindDbForPathEnding(expected_path, dbs); - assert(db); - if (!db->diagnostics_.empty()) { - std::cout << "For " << path << std::endl; - for (const lsDiagnostic& diagnostic : db->diagnostics_) { - std::cout << " "; - if (diagnostic.severity) - std::cout << severity_to_string(*diagnostic.severity); - std::cout << basename(db->path) << ":" - << diagnostic.range.start.ToString() << "-" - << diagnostic.range.end.ToString() << ": " - << diagnostic.message << std::endl; + if (path.find(filter_path) == std::string::npos) + return; + + if (!filter_path.empty()) + printf("Running %s\n", path.c_str()); + + // Parse expected output from the test, parse it into JSON document. + std::vector lines_with_endings; + { + std::ifstream fin(path); + for (std::string line; std::getline(fin, line);) + lines_with_endings.push_back(line); } - } - std::string actual_output = "{}"; - if (db) { - VerifySerializeToFrom(db); - actual_output = db->ToString(); - } - actual_output = text_replacer.Apply(actual_output); + TextReplacer text_replacer; + std::vector flags; + std::unordered_map all_expected_output; + ParseTestExpectation(path, lines_with_endings, &text_replacer, &flags, + &all_expected_output); - // Compare output via rapidjson::Document to ignore any formatting - // differences. - rapidjson::Document actual; - actual.Parse(actual_output.c_str()); - rapidjson::Document expected; - expected.Parse(expected_output.c_str()); + // Build flags. + if (!AnyStartsWith(flags, "-x")) + flags.push_back("-xc++"); + flags.push_back("-resource-dir=" + GetDefaultResourceDirectory()); + flags.push_back(path); - if (actual == expected) { - // std::cout << "[PASSED] " << path << std::endl; - } else { - if (!is_fail_allowed) - success = false; - DiffDocuments(path, expected_path, expected, actual); - std::cout << std::endl; - std::cout << std::endl; - if (enable_update) { - std::cout - << "[Enter to continue - type u to update test, a to update all]"; - char c = 'u'; - if (!update_all) { - c = getchar(); - getchar(); + // Run test. + g_config = std::make_unique(); + FileConsumerSharedState file_consumer_shared; + PerformanceImportFile perf; + auto dbs = Parse(&file_consumer_shared, path, flags, {}, &perf, &index, + false /*dump_ast*/); + + for (const auto& entry : all_expected_output) { + const std::string& expected_path = entry.first; + std::string expected_output = text_replacer.Apply(entry.second); + + // FIXME: promote to utils, find and remove duplicates (ie, + // ccls_call_tree.cc, maybe something in project.cc). + auto basename = [](const std::string& path) -> std::string { + size_t last_index = path.find_last_of('/'); + if (last_index == std::string::npos) + return path; + return path.substr(last_index + 1); + }; + + // Get output from index operation. + IndexFile* db = FindDbForPathEnding(expected_path, dbs); + assert(db); + if (!db->diagnostics_.empty()) { + printf("For %s\n", path.c_str()); + for (const lsDiagnostic& diagnostic : db->diagnostics_) { + printf(" "); + if (diagnostic.severity) + switch (*diagnostic.severity) { + case lsDiagnosticSeverity::Error: + printf("error "); + break; + case lsDiagnosticSeverity::Warning: + printf("warning "); + break; + case lsDiagnosticSeverity::Information: + printf("information "); + break; + case lsDiagnosticSeverity::Hint: + printf("hint "); + break; + } + printf("%s:%s-%s:%s\n", basename(db->path).c_str(), + diagnostic.range.start.ToString().c_str(), + diagnostic.range.end.ToString().c_str(), + diagnostic.message.c_str()); + } } + std::string actual_output = "{}"; + if (db) { + VerifySerializeToFrom(db); + actual_output = db->ToString(); + } + actual_output = text_replacer.Apply(actual_output); - if (c == 'a') - update_all = true; + // Compare output via rapidjson::Document to ignore any formatting + // differences. + rapidjson::Document actual; + actual.Parse(actual_output.c_str()); + rapidjson::Document expected; + expected.Parse(expected_output.c_str()); - if (update_all || c == 'u') { - // Note: we use |entry.second| instead of |expected_output| because - // |expected_output| has had text replacements applied. - UpdateTestExpectation(path, entry.second, ToString(actual) + "\n"); + if (actual == expected) { + // std::cout << "[PASSED] " << path << std::endl; + } else { + if (!is_fail_allowed) + success = false; + DiffDocuments(path, expected_path, expected, actual); + puts("\n"); + if (enable_update) { + printf( + "[Enter to continue - type u to update test, a to update " + "all]"); + char c = 'u'; + if (!update_all) { + c = getchar(); + getchar(); + } + + if (c == 'a') + update_all = true; + + if (update_all || c == 'u') { + // Note: we use |entry.second| instead of |expected_output| + // because + // |expected_output| has had text replacements applied. + UpdateTestExpectation(path, entry.second, + ToString(actual) + "\n"); + } + } } } - } - } - } + }); return success; } diff --git a/src/utils.cc b/src/utils.cc index b993c8ef..eb8fb6a3 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -1,6 +1,5 @@ #include "utils.h" -#include "filesystem.hh" #include "platform.h" #include @@ -12,12 +11,7 @@ #include #include #include -#include #include -#include -#include -#include -#include #include using namespace std::placeholders; @@ -83,26 +77,6 @@ bool FindAnyPartial(const std::string& value, }); } -std::string GetDirName(std::string path) { - if (path.size() && path.back() == '/') - path.pop_back(); - size_t last_slash = path.find_last_of('/'); - if (last_slash == std::string::npos) - return "."; - if (last_slash == 0) - return "/"; - return path.substr(0, last_slash); -} - -std::string GetBaseName(const std::string& path) { - return fs::path(path).filename(); -} - -std::string StripFileType(const std::string& path) { - fs::path p(path); - return p.parent_path() / p.stem(); -} - std::vector SplitString(const std::string& str, const std::string& delimiter) { // http://stackoverflow.com/a/13172514 @@ -132,54 +106,6 @@ std::string LowerPathIfInsensitive(const std::string& path) { #endif } -static void GetFilesInFolderHelper( - std::string folder, - bool recursive, - std::string output_prefix, - const std::function& handler) { - std::queue> q; - q.emplace(fs::path(folder), fs::path(output_prefix)); - while (!q.empty()) { - for (auto it = fs::directory_iterator(q.front().first); it != fs::directory_iterator(); ++it) { - auto path = it->path(); - std::string filename = path.filename(); - if (filename[0] != '.' || filename == ".ccls") { - fs::file_status status = it->symlink_status(); - if (fs::is_regular_file(status)) - handler(q.front().second / filename); - else if (fs::is_directory(status) || fs::is_symlink(status)) { - if (recursive) { - std::string child_dir = q.front().second / filename; - if (fs::is_directory(status)) - q.push(make_pair(path, child_dir)); - } - } - } - } - q.pop(); - } -} - -std::vector GetFilesInFolder(std::string folder, - bool recursive, - bool add_folder_to_path) { - EnsureEndsInSlash(folder); - std::vector result; - GetFilesInFolderHelper( - folder, recursive, add_folder_to_path ? folder : "", - [&result](const std::string& path) { result.push_back(path); }); - return result; -} - -void GetFilesInFolder(std::string folder, - bool recursive, - bool add_folder_to_path, - const std::function& handler) { - EnsureEndsInSlash(folder); - GetFilesInFolderHelper(folder, recursive, add_folder_to_path ? folder : "", - handler); -} - void EnsureEndsInSlash(std::string& path) { if (path.empty() || path[path.size() - 1] != '/') path += '/'; @@ -195,10 +121,6 @@ std::string EscapeFileName(std::string path) { return path; } -bool FileExists(const std::string& filename) { - return fs::exists(filename); -} - std::optional ReadContent(const std::string& filename) { LOG_S(INFO) << "Reading " << filename; char buf[4096]; @@ -211,41 +133,6 @@ std::optional ReadContent(const std::string& filename) { return ret; } -std::vector ReadFileLines(std::string filename) { - std::vector result; - std::ifstream fin(filename); - for (std::string line; std::getline(fin, line);) - result.push_back(line); - return result; -} - -std::vector ToLines(const std::string& content) { - std::vector result; - std::istringstream lines(content); - std::string line; - while (getline(lines, line)) - result.push_back(line); - return result; -} - -std::string TextReplacer::Apply(const std::string& content) { - std::string result = content; - - for (const Replacement& replacement : replacements) { - while (true) { - size_t idx = result.find(replacement.from); - if (idx == std::string::npos) - break; - - result.replace(result.begin() + idx, - result.begin() + idx + replacement.from.size(), - replacement.to); - } - } - - return result; -} - void WriteToFile(const std::string& filename, const std::string& content) { FILE* f = fopen(filename.c_str(), "wb"); if (!f || fwrite(content.c_str(), content.size(), 1, f) != 1) { @@ -278,19 +165,3 @@ std::string GetDefaultResourceDirectory() { return NormalizePath(result); } - -void StartThread(const std::string& thread_name, std::function entry) { - new std::thread([thread_name, entry]() { - SetCurrentThreadName(thread_name); - entry(); - }); -} - -TEST_SUITE("StripFileType") { - TEST_CASE("all") { - REQUIRE(StripFileType("") == ""); - REQUIRE(StripFileType("bar") == "bar"); - REQUIRE(StripFileType("bar.cc") == "bar"); - REQUIRE(StripFileType("foo/bar.cc") == "foo/bar"); - } -} diff --git a/src/utils.h b/src/utils.h index baba2774..82755e71 100644 --- a/src/utils.h +++ b/src/utils.h @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -23,13 +22,6 @@ bool StartsWithAny(std::string_view s, const std::vector& ps); bool EndsWithAny(std::string_view s, const std::vector& ss); bool FindAnyPartial(const std::string& value, const std::vector& values); -// Returns the dirname of |path|, i.e. "foo/bar.cc" => "foo", "foo" => ".", -// "/foo" => "/". -std::string GetDirName(std::string path); -// Returns the basename of |path|, ie, "foo/bar.cc" => "bar.cc". -std::string GetBaseName(const std::string& path); -// Returns |path| without the filetype, ie, "foo/bar.cc" => "foo/bar". -std::string StripFileType(const std::string& path); std::vector SplitString(const std::string& str, const std::string& delimiter); @@ -62,15 +54,6 @@ bool ContainsValue(const TCollection& collection, const TValue& value) { return collection.find(value) != collection.end(); } -// Finds all files in the given folder. This is recursive. -std::vector GetFilesInFolder(std::string folder, - bool recursive, - bool add_folder_to_path); -void GetFilesInFolder(std::string folder, - bool recursive, - bool add_folder_to_path, - const std::function& handler); - // Ensures that |path| ends in a slash. void EnsureEndsInSlash(std::string& path); @@ -78,22 +61,7 @@ void EnsureEndsInSlash(std::string& path); // e.g. foo/bar.c => foo_bar.c std::string EscapeFileName(std::string path); -// FIXME: Move ReadContent into ICacheManager? -bool FileExists(const std::string& filename); std::optional ReadContent(const std::string& filename); -std::vector ReadFileLines(std::string filename); -std::vector ToLines(const std::string& content); - -struct TextReplacer { - struct Replacement { - std::string from; - std::string to; - }; - - std::vector replacements; - - std::string Apply(const std::string& content); -}; void WriteToFile(const std::string& filename, const std::string& content); @@ -149,5 +117,3 @@ inline void hash_combine(std::size_t& seed, const T& v, Rest... rest) { } std::string GetDefaultResourceDirectory(); - -void StartThread(const std::string& thread_name, std::function entry); diff --git a/src/working_files.cc b/src/working_files.cc index 478a6ff5..cdc5e5ef 100644 --- a/src/working_files.cc +++ b/src/working_files.cc @@ -9,6 +9,7 @@ #include #include #include +#include namespace { @@ -38,6 +39,15 @@ lsPosition GetPositionForOffset(const std::string& content, int offset) { return result; } +std::vector ToLines(const std::string& content) { + std::vector result; + std::istringstream lines(content); + std::string line; + while (getline(lines, line)) + result.push_back(line); + return result; +} + // Computes the edit distance of strings [a,a+la) and [b,b+lb) with Eugene W. // Myers' O(ND) diff algorithm. // Costs: insertion=1, deletion=1, no substitution.