mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 07:35:08 +00:00
Simplify
This commit is contained in:
parent
3fbfb99e1b
commit
b872faa160
@ -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
|
||||
|
@ -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",
|
||||
|
@ -89,7 +89,7 @@ OUTPUT:
|
||||
}],
|
||||
"vars": [{
|
||||
"id": 0,
|
||||
"usr": 1893354193220338759,
|
||||
"usr": 9954632887635271906,
|
||||
"detailed_name": "Foo f",
|
||||
"qual_name_offset": 4,
|
||||
"short_name": "f",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -92,7 +92,7 @@ OUTPUT:
|
||||
"storage": 0
|
||||
}, {
|
||||
"id": 2,
|
||||
"usr": 2056319845419860263,
|
||||
"usr": 14946041066794678724,
|
||||
"detailed_name": "DISALLOW",
|
||||
"qual_name_offset": 0,
|
||||
"short_name": "DISALLOW",
|
||||
|
@ -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,
|
||||
|
@ -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",
|
||||
|
@ -111,7 +111,7 @@ OUTPUT:
|
||||
"storage": 1
|
||||
}, {
|
||||
"id": 1,
|
||||
"usr": 3649375698083002347,
|
||||
"usr": 7976909968919750794,
|
||||
"detailed_name": "int a",
|
||||
"qual_name_offset": 4,
|
||||
"short_name": "a",
|
||||
|
@ -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",
|
||||
|
@ -12,7 +12,7 @@ OUTPUT:
|
||||
"funcs": [],
|
||||
"vars": [{
|
||||
"id": 0,
|
||||
"usr": 11674328179498211370,
|
||||
"usr": 13076155634261037336,
|
||||
"detailed_name": "FOO",
|
||||
"qual_name_offset": 0,
|
||||
"short_name": "FOO",
|
||||
|
@ -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": "",
|
||||
|
@ -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",
|
||||
|
@ -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": "",
|
||||
|
@ -64,7 +64,7 @@ OUTPUT:
|
||||
}],
|
||||
"vars": [{
|
||||
"id": 0,
|
||||
"usr": 16088407831770615719,
|
||||
"usr": 13681544683892648258,
|
||||
"detailed_name": "void (*)() x",
|
||||
"qual_name_offset": 11,
|
||||
"short_name": "x",
|
||||
|
@ -67,7 +67,7 @@ OUTPUT:
|
||||
}],
|
||||
"vars": [{
|
||||
"id": 0,
|
||||
"usr": 4636142131003982569,
|
||||
"usr": 8436636043513449412,
|
||||
"detailed_name": "void (Foo::*)() x",
|
||||
"qual_name_offset": 16,
|
||||
"short_name": "x",
|
||||
|
@ -67,7 +67,7 @@ OUTPUT:
|
||||
}],
|
||||
"vars": [{
|
||||
"id": 0,
|
||||
"usr": 14045150712868309451,
|
||||
"usr": 3014406561587537195,
|
||||
"detailed_name": "Foo *f",
|
||||
"qual_name_offset": 5,
|
||||
"short_name": "f",
|
||||
|
@ -66,7 +66,7 @@ OUTPUT:
|
||||
}],
|
||||
"vars": [{
|
||||
"id": 0,
|
||||
"usr": 16229832321010999607,
|
||||
"usr": 12410753116854389823,
|
||||
"detailed_name": "Foo *f",
|
||||
"qual_name_offset": 5,
|
||||
"short_name": "f",
|
||||
|
@ -95,7 +95,7 @@ OUTPUT:
|
||||
"storage": 3
|
||||
}, {
|
||||
"id": 2,
|
||||
"usr": 3364438781074774169,
|
||||
"usr": 2462000803278878465,
|
||||
"detailed_name": "unique_ptr<S> *local",
|
||||
"qual_name_offset": 15,
|
||||
"short_name": "local",
|
||||
|
@ -228,7 +228,7 @@ OUTPUT:
|
||||
"storage": 2
|
||||
}, {
|
||||
"id": 1,
|
||||
"usr": 500112618220246,
|
||||
"usr": 11547294959889394856,
|
||||
"detailed_name": "unique_ptr<unique_ptr<S1, S2>, S2> *local",
|
||||
"qual_name_offset": 36,
|
||||
"short_name": "local",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -51,7 +51,7 @@ OUTPUT:
|
||||
}],
|
||||
"vars": [{
|
||||
"id": 0,
|
||||
"usr": 13823260660189154978,
|
||||
"usr": 2161866804398917919,
|
||||
"detailed_name": "Foo *f",
|
||||
"qual_name_offset": 5,
|
||||
"short_name": "f",
|
||||
|
@ -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",
|
||||
|
@ -55,7 +55,7 @@ OUTPUT:
|
||||
}],
|
||||
"vars": [{
|
||||
"id": 0,
|
||||
"usr": 16380484338511689669,
|
||||
"usr": 14873619387499024780,
|
||||
"detailed_name": "Foo f",
|
||||
"qual_name_offset": 4,
|
||||
"short_name": "f",
|
||||
|
@ -132,7 +132,7 @@ OUTPUT:
|
||||
"storage": 0
|
||||
}, {
|
||||
"id": 2,
|
||||
"usr": 8039186520399841081,
|
||||
"usr": 13284113377394221067,
|
||||
"detailed_name": "int a",
|
||||
"qual_name_offset": 4,
|
||||
"short_name": "a",
|
||||
|
@ -48,7 +48,7 @@ OUTPUT:
|
||||
}],
|
||||
"vars": [{
|
||||
"id": 0,
|
||||
"usr": 9121974011454213596,
|
||||
"usr": 3510529098767253033,
|
||||
"detailed_name": "void (*)() x",
|
||||
"qual_name_offset": 11,
|
||||
"short_name": "x",
|
||||
|
@ -134,7 +134,7 @@ OUTPUT:
|
||||
"storage": 0
|
||||
}, {
|
||||
"id": 2,
|
||||
"usr": 14669930844300034456,
|
||||
"usr": 16303259148898744165,
|
||||
"detailed_name": "Foo f",
|
||||
"qual_name_offset": 4,
|
||||
"short_name": "f",
|
||||
|
@ -42,7 +42,7 @@ OUTPUT:
|
||||
}],
|
||||
"vars": [{
|
||||
"id": 0,
|
||||
"usr": 14014650769929566957,
|
||||
"usr": 8534460107894911680,
|
||||
"detailed_name": "int x",
|
||||
"qual_name_offset": 4,
|
||||
"short_name": "x",
|
||||
|
@ -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",
|
||||
|
@ -60,7 +60,7 @@ OUTPUT:
|
||||
"storage": 1
|
||||
}, {
|
||||
"id": 1,
|
||||
"usr": 6997229590862003559,
|
||||
"usr": 8011559936501990179,
|
||||
"detailed_name": "int a",
|
||||
"qual_name_offset": 4,
|
||||
"short_name": "a",
|
||||
|
@ -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",
|
||||
|
@ -44,7 +44,7 @@ OUTPUT:
|
||||
}],
|
||||
"vars": [{
|
||||
"id": 0,
|
||||
"usr": 13198746475679542317,
|
||||
"usr": 10782632605670042066,
|
||||
"detailed_name": "Foo *a",
|
||||
"qual_name_offset": 5,
|
||||
"short_name": "a",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -54,7 +54,7 @@ OUTPUT:
|
||||
"storage": 1
|
||||
}, {
|
||||
"id": 1,
|
||||
"usr": 11404600766177939811,
|
||||
"usr": 2147918703972955240,
|
||||
"detailed_name": "int p",
|
||||
"qual_name_offset": 4,
|
||||
"short_name": "p",
|
||||
|
@ -67,7 +67,7 @@ OUTPUT:
|
||||
}],
|
||||
"vars": [{
|
||||
"id": 0,
|
||||
"usr": 6975456769752895964,
|
||||
"usr": 7730100248624586522,
|
||||
"detailed_name": "F a",
|
||||
"qual_name_offset": 2,
|
||||
"short_name": "a",
|
||||
|
@ -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<std::string>& 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);
|
||||
});
|
||||
}
|
||||
|
@ -2304,7 +2304,7 @@ std::vector<std::unique_ptr<IndexFile>> 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;
|
||||
}
|
||||
|
@ -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<lsDiagnostic> 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));
|
||||
|
||||
|
@ -31,9 +31,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
@ -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<MethodType, Timer>* 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<InMessage> message;
|
||||
@ -288,7 +284,8 @@ void LaunchStdinLoop(std::unordered_map<MethodType, Timer>* request_times) {
|
||||
|
||||
void LaunchStdoutThread(std::unordered_map<MethodType, Timer>* 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<JsonReader&>(json_reader).GetPath()
|
||||
<< ", expected " << e.what() << "\n";
|
||||
fprintf(stderr, "Failed to parse --init %s, expected %s\n",
|
||||
static_cast<JsonReader&>(json_reader).GetPath().c_str(),
|
||||
e.what());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
43
src/filesystem.cc
Normal file
43
src/filesystem.cc
Normal file
@ -0,0 +1,43 @@
|
||||
#include "filesystem.hh"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <queue>
|
||||
#include <utility>
|
||||
|
||||
static void GetFilesInFolderHelper(
|
||||
std::string folder,
|
||||
bool recursive,
|
||||
std::string output_prefix,
|
||||
const std::function<void(const std::string&)>& handler) {
|
||||
std::queue<std::pair<fs::path, fs::path>> 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<void(const std::string&)>& handler) {
|
||||
EnsureEndsInSlash(folder);
|
||||
GetFilesInFolderHelper(folder, recursive, add_folder_to_path ? folder : "",
|
||||
handler);
|
||||
}
|
@ -1,5 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <experimental/filesystem>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
void GetFilesInFolder(std::string folder,
|
||||
bool recursive,
|
||||
bool add_folder_to_path,
|
||||
const std::function<void(const std::string&)>& handler);
|
||||
|
@ -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 <thread>
|
||||
|
||||
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();
|
||||
|
@ -69,21 +69,21 @@ std::pair<bool, int> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
37
src/lsp.cc
37
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;
|
||||
|
42
src/lsp.h
42
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);
|
||||
|
@ -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
|
||||
|
@ -517,11 +517,12 @@ struct Handler_Initialize : BaseMessageHandler<In_InitializeRequest> {
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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<int64_t> GetLastModificationTime(const std::string& absolute_path);
|
||||
|
||||
|
@ -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());
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
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;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
@ -47,7 +48,7 @@ struct ProjectConfig {
|
||||
std::unordered_set<std::string> quote_dirs;
|
||||
std::unordered_set<std::string> angle_dirs;
|
||||
std::vector<std::string> 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<std::string> args;
|
||||
@ -256,7 +257,8 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
|
||||
std::vector<std::string> ReadCompilerArgumentsFromFile(
|
||||
const std::string& path) {
|
||||
std::vector<std::string> 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<std::string> ReadCompilerArgumentsFromFile(
|
||||
std::vector<Project::Entry> LoadFromDirectoryListing(ProjectConfig* config) {
|
||||
std::vector<Project::Entry> 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<Project::Entry> 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<Project::Entry> 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<Project::Entry> 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<std::string> 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);
|
||||
|
@ -158,19 +158,19 @@ std::vector<Use> GetUsesForAllDerived(QueryDatabase* db, QueryFunc& root) {
|
||||
std::optional<lsPosition> 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<int> start =
|
||||
working_file->GetBufferPosFromIndexPos(position.line, &column, false))
|
||||
return lsPosition(*start, column);
|
||||
return lsPosition{*start, column};
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<lsRange> 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<lsRange> 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<lsLocation> 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<lsLocationEx> GetLsLocationEx(QueryDatabase* db,
|
||||
|
@ -1,11 +1,11 @@
|
||||
#include "serializer.h"
|
||||
|
||||
#include "filesystem.hh"
|
||||
#include "serializers/json.h"
|
||||
#include "serializers/msgpack.h"
|
||||
|
||||
#include "indexer.h"
|
||||
|
||||
#include <doctest/doctest.h>
|
||||
#include <loguru.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
@ -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 <typename TVisitor>
|
||||
@ -441,17 +441,3 @@ std::unique_ptr<IndexFile> 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/") == ".");
|
||||
}
|
||||
}
|
||||
|
@ -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<T>& values) {
|
||||
|
||||
// ReflectMember
|
||||
|
||||
inline void DefaultReflectMemberStart(Writer& visitor) {
|
||||
visitor.StartObject();
|
||||
}
|
||||
inline void DefaultReflectMemberStart(Reader& visitor) {}
|
||||
|
||||
template <typename T>
|
||||
bool ReflectMemberStart(Reader& visitor, T& value) {
|
||||
return false;
|
||||
@ -356,5 +349,3 @@ std::unique_ptr<IndexFile> Deserialize(
|
||||
const std::string& serialized_index_content,
|
||||
const std::string& file_content,
|
||||
std::optional<int> expected_version);
|
||||
|
||||
void SetTestOutputMode();
|
||||
|
@ -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(); }
|
||||
|
@ -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;
|
||||
|
302
src/test.cc
302
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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
// The 'diff' utility is available and we can use dprintf(3).
|
||||
#if _POSIX_C_SOURCE >= 200809L
|
||||
@ -23,6 +23,8 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
extern bool gTestOutputMode;
|
||||
|
||||
std::string ToString(const rapidjson::Document& document) {
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::PrettyWriter<rapidjson::StringBuffer> 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<Replacement> 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<std::string>& 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<std::string> 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<std::string> lines_with_endings = ReadFileLines(path);
|
||||
TextReplacer text_replacer;
|
||||
std::vector<std::string> flags;
|
||||
std::unordered_map<std::string, std::string> 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<Config>();
|
||||
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<std::string> 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<std::string> flags;
|
||||
std::unordered_map<std::string, std::string> 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<Config>();
|
||||
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;
|
||||
}
|
||||
|
129
src/utils.cc
129
src/utils.cc
@ -1,6 +1,5 @@
|
||||
#include "utils.h"
|
||||
|
||||
#include "filesystem.hh"
|
||||
#include "platform.h"
|
||||
|
||||
#include <doctest/doctest.h>
|
||||
@ -12,12 +11,7 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
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<std::string> 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<void(const std::string&)>& handler) {
|
||||
std::queue<std::pair<fs::path, fs::path>> 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<std::string> GetFilesInFolder(std::string folder,
|
||||
bool recursive,
|
||||
bool add_folder_to_path) {
|
||||
EnsureEndsInSlash(folder);
|
||||
std::vector<std::string> 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<void(const std::string&)>& 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<std::string> ReadContent(const std::string& filename) {
|
||||
LOG_S(INFO) << "Reading " << filename;
|
||||
char buf[4096];
|
||||
@ -211,41 +133,6 @@ std::optional<std::string> ReadContent(const std::string& filename) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<std::string> ReadFileLines(std::string filename) {
|
||||
std::vector<std::string> result;
|
||||
std::ifstream fin(filename);
|
||||
for (std::string line; std::getline(fin, line);)
|
||||
result.push_back(line);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> ToLines(const std::string& content) {
|
||||
std::vector<std::string> 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<void()> 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");
|
||||
}
|
||||
}
|
||||
|
34
src/utils.h
34
src/utils.h
@ -4,7 +4,6 @@
|
||||
#include <string_view>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@ -23,13 +22,6 @@ bool StartsWithAny(std::string_view s, const std::vector<std::string>& ps);
|
||||
bool EndsWithAny(std::string_view s, const std::vector<std::string>& ss);
|
||||
bool FindAnyPartial(const std::string& value,
|
||||
const std::vector<std::string>& 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<std::string> 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<std::string> 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<void(const std::string&)>& 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<std::string> ReadContent(const std::string& filename);
|
||||
std::vector<std::string> ReadFileLines(std::string filename);
|
||||
std::vector<std::string> ToLines(const std::string& content);
|
||||
|
||||
struct TextReplacer {
|
||||
struct Replacement {
|
||||
std::string from;
|
||||
std::string to;
|
||||
};
|
||||
|
||||
std::vector<Replacement> 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<void()> entry);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
#include <numeric>
|
||||
#include <sstream>
|
||||
|
||||
namespace {
|
||||
|
||||
@ -38,6 +39,15 @@ lsPosition GetPositionForOffset(const std::string& content, int offset) {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> ToLines(const std::string& content) {
|
||||
std::vector<std::string> 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.
|
||||
|
Loading…
Reference in New Issue
Block a user