mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-25 17:11:59 +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/diagnostics_engine.cc
|
||||||
src/file_consumer.cc
|
src/file_consumer.cc
|
||||||
src/file_contents.cc
|
src/file_contents.cc
|
||||||
|
src/filesystem.cc
|
||||||
src/fuzzy_match.cc
|
src/fuzzy_match.cc
|
||||||
src/iindexer.cc
|
src/iindexer.cc
|
||||||
src/import_manager.cc
|
src/import_manager.cc
|
||||||
|
@ -67,7 +67,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 10983126130596230582,
|
"usr": 18410644574635149442,
|
||||||
"detailed_name": "Foo f",
|
"detailed_name": "Foo f",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "f",
|
"short_name": "f",
|
||||||
@ -80,7 +80,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 17165811951126099095,
|
"usr": 11468802633764653592,
|
||||||
"detailed_name": "Foo *f2",
|
"detailed_name": "Foo *f2",
|
||||||
"qual_name_offset": 5,
|
"qual_name_offset": 5,
|
||||||
"short_name": "f2",
|
"short_name": "f2",
|
||||||
|
@ -89,7 +89,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 1893354193220338759,
|
"usr": 9954632887635271906,
|
||||||
"detailed_name": "Foo f",
|
"detailed_name": "Foo f",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "f",
|
"short_name": "f",
|
||||||
|
@ -66,7 +66,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 449111627548814328,
|
"usr": 17348451315735351657,
|
||||||
"detailed_name": "Type foo0",
|
"detailed_name": "Type foo0",
|
||||||
"qual_name_offset": 5,
|
"qual_name_offset": 5,
|
||||||
"short_name": "foo0",
|
"short_name": "foo0",
|
||||||
@ -79,7 +79,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 17097499197730163115,
|
"usr": 3757978174345638825,
|
||||||
"detailed_name": "Type foo1",
|
"detailed_name": "Type foo1",
|
||||||
"qual_name_offset": 5,
|
"qual_name_offset": 5,
|
||||||
"short_name": "foo1",
|
"short_name": "foo1",
|
||||||
|
@ -143,7 +143,7 @@ OUTPUT: make_functions.cc
|
|||||||
"skipped_by_preprocessor": [],
|
"skipped_by_preprocessor": [],
|
||||||
"types": [{
|
"types": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 9281343527065946499,
|
"usr": 7902098450755788854,
|
||||||
"detailed_name": "T",
|
"detailed_name": "T",
|
||||||
"qual_name_offset": 0,
|
"qual_name_offset": 0,
|
||||||
"short_name": "T",
|
"short_name": "T",
|
||||||
@ -160,7 +160,7 @@ OUTPUT: make_functions.cc
|
|||||||
"uses": ["4:1-4:2|-1|1|4"]
|
"uses": ["4:1-4:2|-1|1|4"]
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 10771590811355716928,
|
"usr": 12533159752419999454,
|
||||||
"detailed_name": "Args",
|
"detailed_name": "Args",
|
||||||
"qual_name_offset": 0,
|
"qual_name_offset": 0,
|
||||||
"short_name": "Args",
|
"short_name": "Args",
|
||||||
@ -177,7 +177,7 @@ OUTPUT: make_functions.cc
|
|||||||
"uses": ["4:15-4:19|-1|1|4"]
|
"uses": ["4:15-4:19|-1|1|4"]
|
||||||
}, {
|
}, {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"usr": 11897454629873246477,
|
"usr": 18441628706991062891,
|
||||||
"detailed_name": "T",
|
"detailed_name": "T",
|
||||||
"qual_name_offset": 0,
|
"qual_name_offset": 0,
|
||||||
"short_name": "T",
|
"short_name": "T",
|
||||||
@ -194,7 +194,7 @@ OUTPUT: make_functions.cc
|
|||||||
"uses": ["9:1-9:2|-1|1|4"]
|
"uses": ["9:1-9:2|-1|1|4"]
|
||||||
}, {
|
}, {
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"usr": 3337128087216004141,
|
"usr": 9441341235704820385,
|
||||||
"detailed_name": "Args",
|
"detailed_name": "Args",
|
||||||
"qual_name_offset": 0,
|
"qual_name_offset": 0,
|
||||||
"short_name": "Args",
|
"short_name": "Args",
|
||||||
@ -347,7 +347,7 @@ OUTPUT: make_functions.cc
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 8463700030555379526,
|
"usr": 15288691366352169805,
|
||||||
"detailed_name": "Args &&... args",
|
"detailed_name": "Args &&... args",
|
||||||
"qual_name_offset": 11,
|
"qual_name_offset": 11,
|
||||||
"short_name": "args",
|
"short_name": "args",
|
||||||
@ -359,7 +359,7 @@ OUTPUT: make_functions.cc
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 3908732770590594660,
|
"usr": 12338908251430965107,
|
||||||
"detailed_name": "Args... args",
|
"detailed_name": "Args... args",
|
||||||
"qual_name_offset": 8,
|
"qual_name_offset": 8,
|
||||||
"short_name": "args",
|
"short_name": "args",
|
||||||
|
@ -53,7 +53,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 14555488990109936920,
|
"usr": 10480417713467708012,
|
||||||
"detailed_name": "int a",
|
"detailed_name": "int a",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "a",
|
"short_name": "a",
|
||||||
@ -66,7 +66,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 10963664335057337329,
|
"usr": 18099600680625658464,
|
||||||
"detailed_name": "int b",
|
"detailed_name": "int b",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "b",
|
"short_name": "b",
|
||||||
|
@ -102,7 +102,7 @@ OUTPUT:
|
|||||||
"uses": ["13:56-13:64|-1|1|4"]
|
"uses": ["13:56-13:64|-1|1|4"]
|
||||||
}, {
|
}, {
|
||||||
"id": 5,
|
"id": 5,
|
||||||
"usr": 7916588271848318236,
|
"usr": 780719166805015998,
|
||||||
"detailed_name": "T",
|
"detailed_name": "T",
|
||||||
"qual_name_offset": 0,
|
"qual_name_offset": 0,
|
||||||
"short_name": "T",
|
"short_name": "T",
|
||||||
@ -138,7 +138,7 @@ OUTPUT:
|
|||||||
"funcs": [],
|
"funcs": [],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 12990052348105569112,
|
"usr": 3880651725784125791,
|
||||||
"detailed_name": "unsigned int T",
|
"detailed_name": "unsigned int T",
|
||||||
"qual_name_offset": 13,
|
"qual_name_offset": 13,
|
||||||
"short_name": "T",
|
"short_name": "T",
|
||||||
|
@ -33,7 +33,7 @@ OUTPUT:
|
|||||||
"uses": []
|
"uses": []
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 14635009347499519042,
|
"usr": 1287417953265234030,
|
||||||
"detailed_name": "",
|
"detailed_name": "",
|
||||||
"qual_name_offset": 0,
|
"qual_name_offset": 0,
|
||||||
"short_name": "",
|
"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"]
|
"callees": ["9:14-9:15|1|3|32", "10:14-10:15|1|3|32", "11:14-11:15|1|3|32"]
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 17926497908620168464,
|
"usr": 1328781044864682611,
|
||||||
"detailed_name": "",
|
"detailed_name": "",
|
||||||
"qual_name_offset": 0,
|
"qual_name_offset": 0,
|
||||||
"short_name": "",
|
"short_name": "",
|
||||||
@ -80,7 +80,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 12666114896600231317,
|
"usr": 17270098654620601683,
|
||||||
"detailed_name": "int x",
|
"detailed_name": "int x",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "x",
|
"short_name": "x",
|
||||||
@ -93,7 +93,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 2981279427664991319,
|
"usr": 16806544259835773270,
|
||||||
"detailed_name": "lambda dosomething",
|
"detailed_name": "lambda dosomething",
|
||||||
"qual_name_offset": 7,
|
"qual_name_offset": 7,
|
||||||
"short_name": "dosomething",
|
"short_name": "dosomething",
|
||||||
@ -106,7 +106,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"usr": 12879188959314906706,
|
"usr": 2034725908368218782,
|
||||||
"detailed_name": "int y",
|
"detailed_name": "int y",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "y",
|
"short_name": "y",
|
||||||
|
@ -92,7 +92,7 @@ OUTPUT:
|
|||||||
"storage": 0
|
"storage": 0
|
||||||
}, {
|
}, {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"usr": 2056319845419860263,
|
"usr": 14946041066794678724,
|
||||||
"detailed_name": "DISALLOW",
|
"detailed_name": "DISALLOW",
|
||||||
"qual_name_offset": 0,
|
"qual_name_offset": 0,
|
||||||
"short_name": "DISALLOW",
|
"short_name": "DISALLOW",
|
||||||
|
@ -26,7 +26,7 @@ OUTPUT:
|
|||||||
"funcs": [{
|
"funcs": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 5010253035933134245,
|
"usr": 5010253035933134245,
|
||||||
"detailed_name": "void (anon)::foo()",
|
"detailed_name": "void (anon ns)::foo()",
|
||||||
"qual_name_offset": 5,
|
"qual_name_offset": 5,
|
||||||
"short_name": "foo",
|
"short_name": "foo",
|
||||||
"kind": 12,
|
"kind": 12,
|
||||||
|
@ -150,7 +150,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 6030927277961448585,
|
"usr": 107714981785063096,
|
||||||
"detailed_name": "int a",
|
"detailed_name": "int a",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "a",
|
"short_name": "a",
|
||||||
@ -164,7 +164,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"usr": 7657277353101371136,
|
"usr": 1200087780658383286,
|
||||||
"detailed_name": "int b",
|
"detailed_name": "int b",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "b",
|
"short_name": "b",
|
||||||
|
@ -111,7 +111,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 3649375698083002347,
|
"usr": 7976909968919750794,
|
||||||
"detailed_name": "int a",
|
"detailed_name": "int a",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "a",
|
"short_name": "a",
|
||||||
|
@ -187,7 +187,7 @@ OUTPUT: static_function_in_type.cc
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 13569879755236306838,
|
"usr": 9285345059965948351,
|
||||||
"detailed_name": "ns::Manager *m",
|
"detailed_name": "ns::Manager *m",
|
||||||
"qual_name_offset": 13,
|
"qual_name_offset": 13,
|
||||||
"short_name": "m",
|
"short_name": "m",
|
||||||
|
@ -12,7 +12,7 @@ OUTPUT:
|
|||||||
"funcs": [],
|
"funcs": [],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 11674328179498211370,
|
"usr": 13076155634261037336,
|
||||||
"detailed_name": "FOO",
|
"detailed_name": "FOO",
|
||||||
"qual_name_offset": 0,
|
"qual_name_offset": 0,
|
||||||
"short_name": "FOO",
|
"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"]
|
"uses": ["10:26-10:32|-1|1|4", "13:13-13:19|-1|1|4", "14:14-14:20|-1|1|4"]
|
||||||
}, {
|
}, {
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"usr": 2205716167465743256,
|
"usr": 14511917000226829276,
|
||||||
"detailed_name": "",
|
"detailed_name": "",
|
||||||
"qual_name_offset": 0,
|
"qual_name_offset": 0,
|
||||||
"short_name": "",
|
"short_name": "",
|
||||||
|
@ -83,7 +83,7 @@ OUTPUT:
|
|||||||
"uses": ["7:1-7:9|-1|1|4"]
|
"uses": ["7:1-7:9|-1|1|4"]
|
||||||
}, {
|
}, {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"usr": 9673599782548740467,
|
"usr": 10862637711685426953,
|
||||||
"detailed_name": "T",
|
"detailed_name": "T",
|
||||||
"qual_name_offset": 0,
|
"qual_name_offset": 0,
|
||||||
"short_name": "T",
|
"short_name": "T",
|
||||||
@ -100,7 +100,7 @@ OUTPUT:
|
|||||||
"uses": ["5:16-5:17|-1|1|4"]
|
"uses": ["5:16-5:17|-1|1|4"]
|
||||||
}, {
|
}, {
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"usr": 7143192229126273961,
|
"usr": 756188769017350739,
|
||||||
"detailed_name": "Args",
|
"detailed_name": "Args",
|
||||||
"qual_name_offset": 0,
|
"qual_name_offset": 0,
|
||||||
"short_name": "Args",
|
"short_name": "Args",
|
||||||
@ -166,7 +166,7 @@ OUTPUT:
|
|||||||
"uses": ["31:1-31:7|-1|1|4"]
|
"uses": ["31:1-31:7|-1|1|4"]
|
||||||
}, {
|
}, {
|
||||||
"id": 7,
|
"id": 7,
|
||||||
"usr": 8880262253425334092,
|
"usr": 3421332160420436276,
|
||||||
"detailed_name": "T",
|
"detailed_name": "T",
|
||||||
"qual_name_offset": 0,
|
"qual_name_offset": 0,
|
||||||
"short_name": "T",
|
"short_name": "T",
|
||||||
@ -251,7 +251,7 @@ OUTPUT:
|
|||||||
"uses": []
|
"uses": []
|
||||||
}, {
|
}, {
|
||||||
"id": 12,
|
"id": 12,
|
||||||
"usr": 14111105212951082474,
|
"usr": 2461355892344618654,
|
||||||
"detailed_name": "T",
|
"detailed_name": "T",
|
||||||
"qual_name_offset": 0,
|
"qual_name_offset": 0,
|
||||||
"short_name": "T",
|
"short_name": "T",
|
||||||
@ -433,7 +433,7 @@ OUTPUT:
|
|||||||
"storage": 0
|
"storage": 0
|
||||||
}, {
|
}, {
|
||||||
"id": 7,
|
"id": 7,
|
||||||
"usr": 17826688417349629938,
|
"usr": 10307767688451422448,
|
||||||
"detailed_name": "T Value",
|
"detailed_name": "T Value",
|
||||||
"qual_name_offset": 2,
|
"qual_name_offset": 2,
|
||||||
"short_name": "Value",
|
"short_name": "Value",
|
||||||
|
@ -71,7 +71,7 @@ OUTPUT:
|
|||||||
"uses": ["8:1-8:2|-1|1|4", "8:11-8:12|-1|1|4"]
|
"uses": ["8:1-8:2|-1|1|4", "8:11-8:12|-1|1|4"]
|
||||||
}, {
|
}, {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"usr": 11919899838872947844,
|
"usr": 8864163146308556810,
|
||||||
"detailed_name": "",
|
"detailed_name": "",
|
||||||
"qual_name_offset": 0,
|
"qual_name_offset": 0,
|
||||||
"short_name": "",
|
"short_name": "",
|
||||||
|
@ -64,7 +64,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 16088407831770615719,
|
"usr": 13681544683892648258,
|
||||||
"detailed_name": "void (*)() x",
|
"detailed_name": "void (*)() x",
|
||||||
"qual_name_offset": 11,
|
"qual_name_offset": 11,
|
||||||
"short_name": "x",
|
"short_name": "x",
|
||||||
|
@ -67,7 +67,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 4636142131003982569,
|
"usr": 8436636043513449412,
|
||||||
"detailed_name": "void (Foo::*)() x",
|
"detailed_name": "void (Foo::*)() x",
|
||||||
"qual_name_offset": 16,
|
"qual_name_offset": 16,
|
||||||
"short_name": "x",
|
"short_name": "x",
|
||||||
|
@ -67,7 +67,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 14045150712868309451,
|
"usr": 3014406561587537195,
|
||||||
"detailed_name": "Foo *f",
|
"detailed_name": "Foo *f",
|
||||||
"qual_name_offset": 5,
|
"qual_name_offset": 5,
|
||||||
"short_name": "f",
|
"short_name": "f",
|
||||||
|
@ -66,7 +66,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 16229832321010999607,
|
"usr": 12410753116854389823,
|
||||||
"detailed_name": "Foo *f",
|
"detailed_name": "Foo *f",
|
||||||
"qual_name_offset": 5,
|
"qual_name_offset": 5,
|
||||||
"short_name": "f",
|
"short_name": "f",
|
||||||
|
@ -95,7 +95,7 @@ OUTPUT:
|
|||||||
"storage": 3
|
"storage": 3
|
||||||
}, {
|
}, {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"usr": 3364438781074774169,
|
"usr": 2462000803278878465,
|
||||||
"detailed_name": "unique_ptr<S> *local",
|
"detailed_name": "unique_ptr<S> *local",
|
||||||
"qual_name_offset": 15,
|
"qual_name_offset": 15,
|
||||||
"short_name": "local",
|
"short_name": "local",
|
||||||
|
@ -228,7 +228,7 @@ OUTPUT:
|
|||||||
"storage": 2
|
"storage": 2
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 500112618220246,
|
"usr": 11547294959889394856,
|
||||||
"detailed_name": "unique_ptr<unique_ptr<S1, S2>, S2> *local",
|
"detailed_name": "unique_ptr<unique_ptr<S1, S2>, S2> *local",
|
||||||
"qual_name_offset": 36,
|
"qual_name_offset": 36,
|
||||||
"short_name": "local",
|
"short_name": "local",
|
||||||
|
@ -63,7 +63,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 16374832544037266261,
|
"usr": 11033478034711123650,
|
||||||
"detailed_name": "ForwardType *a",
|
"detailed_name": "ForwardType *a",
|
||||||
"qual_name_offset": 13,
|
"qual_name_offset": 13,
|
||||||
"short_name": "a",
|
"short_name": "a",
|
||||||
@ -76,7 +76,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 2580122838476012357,
|
"usr": 8949902309768550158,
|
||||||
"detailed_name": "ImplementedType b",
|
"detailed_name": "ImplementedType b",
|
||||||
"qual_name_offset": 16,
|
"qual_name_offset": 16,
|
||||||
"short_name": "b",
|
"short_name": "b",
|
||||||
|
@ -60,7 +60,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 13058491096576226774,
|
"usr": 2584795197111552890,
|
||||||
"detailed_name": "ForwardType *f",
|
"detailed_name": "ForwardType *f",
|
||||||
"qual_name_offset": 13,
|
"qual_name_offset": 13,
|
||||||
"short_name": "f",
|
"short_name": "f",
|
||||||
@ -73,7 +73,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 11055777568039014776,
|
"usr": 5136230284979460117,
|
||||||
"detailed_name": "ImplementedType a",
|
"detailed_name": "ImplementedType a",
|
||||||
"qual_name_offset": 16,
|
"qual_name_offset": 16,
|
||||||
"short_name": "a",
|
"short_name": "a",
|
||||||
|
@ -51,7 +51,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 13823260660189154978,
|
"usr": 2161866804398917919,
|
||||||
"detailed_name": "Foo *f",
|
"detailed_name": "Foo *f",
|
||||||
"qual_name_offset": 5,
|
"qual_name_offset": 5,
|
||||||
"short_name": "f",
|
"short_name": "f",
|
||||||
|
@ -48,7 +48,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 7997456978847868736,
|
"usr": 16414210592877294238,
|
||||||
"detailed_name": "Type &a0",
|
"detailed_name": "Type &a0",
|
||||||
"qual_name_offset": 6,
|
"qual_name_offset": 6,
|
||||||
"short_name": "a0",
|
"short_name": "a0",
|
||||||
@ -61,7 +61,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 17228576662112939520,
|
"usr": 11558141642862804306,
|
||||||
"detailed_name": "const Type &a1",
|
"detailed_name": "const Type &a1",
|
||||||
"qual_name_offset": 12,
|
"qual_name_offset": 12,
|
||||||
"short_name": "a1",
|
"short_name": "a1",
|
||||||
@ -74,7 +74,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"usr": 15429032129697337561,
|
"usr": 1536316608590232194,
|
||||||
"detailed_name": "Type a2",
|
"detailed_name": "Type a2",
|
||||||
"qual_name_offset": 5,
|
"qual_name_offset": 5,
|
||||||
"short_name": "a2",
|
"short_name": "a2",
|
||||||
@ -87,7 +87,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"usr": 6081981442495435784,
|
"usr": 316760354845869406,
|
||||||
"detailed_name": "Type *a3",
|
"detailed_name": "Type *a3",
|
||||||
"qual_name_offset": 6,
|
"qual_name_offset": 6,
|
||||||
"short_name": "a3",
|
"short_name": "a3",
|
||||||
@ -100,7 +100,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"usr": 5004072032239834773,
|
"usr": 12321730890779907974,
|
||||||
"detailed_name": "const Type *a4",
|
"detailed_name": "const Type *a4",
|
||||||
"qual_name_offset": 12,
|
"qual_name_offset": 12,
|
||||||
"short_name": "a4",
|
"short_name": "a4",
|
||||||
@ -113,7 +113,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 5,
|
"id": 5,
|
||||||
"usr": 14939253431683105646,
|
"usr": 4771437488905761633,
|
||||||
"detailed_name": "const Type *const a5",
|
"detailed_name": "const Type *const a5",
|
||||||
"qual_name_offset": 18,
|
"qual_name_offset": 18,
|
||||||
"short_name": "a5",
|
"short_name": "a5",
|
||||||
|
@ -55,7 +55,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 16380484338511689669,
|
"usr": 14873619387499024780,
|
||||||
"detailed_name": "Foo f",
|
"detailed_name": "Foo f",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "f",
|
"short_name": "f",
|
||||||
|
@ -132,7 +132,7 @@ OUTPUT:
|
|||||||
"storage": 0
|
"storage": 0
|
||||||
}, {
|
}, {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"usr": 8039186520399841081,
|
"usr": 13284113377394221067,
|
||||||
"detailed_name": "int a",
|
"detailed_name": "int a",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "a",
|
"short_name": "a",
|
||||||
|
@ -48,7 +48,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 9121974011454213596,
|
"usr": 3510529098767253033,
|
||||||
"detailed_name": "void (*)() x",
|
"detailed_name": "void (*)() x",
|
||||||
"qual_name_offset": 11,
|
"qual_name_offset": 11,
|
||||||
"short_name": "x",
|
"short_name": "x",
|
||||||
|
@ -134,7 +134,7 @@ OUTPUT:
|
|||||||
"storage": 0
|
"storage": 0
|
||||||
}, {
|
}, {
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"usr": 14669930844300034456,
|
"usr": 16303259148898744165,
|
||||||
"detailed_name": "Foo f",
|
"detailed_name": "Foo f",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "f",
|
"short_name": "f",
|
||||||
|
@ -42,7 +42,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 14014650769929566957,
|
"usr": 8534460107894911680,
|
||||||
"detailed_name": "int x",
|
"detailed_name": "int x",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "x",
|
"short_name": "x",
|
||||||
|
@ -47,7 +47,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 13311055950748663970,
|
"usr": 17941402366659878910,
|
||||||
"detailed_name": "int a",
|
"detailed_name": "int a",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "a",
|
"short_name": "a",
|
||||||
@ -60,7 +60,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 14036425367303419504,
|
"usr": 11094102496276744608,
|
||||||
"detailed_name": "int a",
|
"detailed_name": "int a",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "a",
|
"short_name": "a",
|
||||||
|
@ -60,7 +60,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 6997229590862003559,
|
"usr": 8011559936501990179,
|
||||||
"detailed_name": "int a",
|
"detailed_name": "int a",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "a",
|
"short_name": "a",
|
||||||
|
@ -46,7 +46,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 10601729374837386290,
|
"usr": 9275666070987716270,
|
||||||
"detailed_name": "Foo *x",
|
"detailed_name": "Foo *x",
|
||||||
"qual_name_offset": 5,
|
"qual_name_offset": 5,
|
||||||
"short_name": "x",
|
"short_name": "x",
|
||||||
@ -59,7 +59,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 18422884837902130475,
|
"usr": 16202433437488621027,
|
||||||
"detailed_name": "Foo *y",
|
"detailed_name": "Foo *y",
|
||||||
"qual_name_offset": 5,
|
"qual_name_offset": 5,
|
||||||
"short_name": "y",
|
"short_name": "y",
|
||||||
|
@ -44,7 +44,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 13198746475679542317,
|
"usr": 10782632605670042066,
|
||||||
"detailed_name": "Foo *a",
|
"detailed_name": "Foo *a",
|
||||||
"qual_name_offset": 5,
|
"qual_name_offset": 5,
|
||||||
"short_name": "a",
|
"short_name": "a",
|
||||||
|
@ -42,7 +42,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 8730439006497971620,
|
"usr": 4580260577538694711,
|
||||||
"detailed_name": "Foo *p0",
|
"detailed_name": "Foo *p0",
|
||||||
"qual_name_offset": 5,
|
"qual_name_offset": 5,
|
||||||
"short_name": "p0",
|
"short_name": "p0",
|
||||||
@ -55,7 +55,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 2525014371090380500,
|
"usr": 12071725611268840435,
|
||||||
"detailed_name": "Foo *p1",
|
"detailed_name": "Foo *p1",
|
||||||
"qual_name_offset": 5,
|
"qual_name_offset": 5,
|
||||||
"short_name": "p1",
|
"short_name": "p1",
|
||||||
|
@ -47,7 +47,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 1894874819807168345,
|
"usr": 3440226937504376525,
|
||||||
"detailed_name": "int a",
|
"detailed_name": "int a",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "a",
|
"short_name": "a",
|
||||||
@ -60,7 +60,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 4508045017817092115,
|
"usr": 14700715011944976607,
|
||||||
"detailed_name": "int a",
|
"detailed_name": "int a",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "a",
|
"short_name": "a",
|
||||||
|
@ -54,7 +54,7 @@ OUTPUT:
|
|||||||
"storage": 1
|
"storage": 1
|
||||||
}, {
|
}, {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"usr": 11404600766177939811,
|
"usr": 2147918703972955240,
|
||||||
"detailed_name": "int p",
|
"detailed_name": "int p",
|
||||||
"qual_name_offset": 4,
|
"qual_name_offset": 4,
|
||||||
"short_name": "p",
|
"short_name": "p",
|
||||||
|
@ -67,7 +67,7 @@ OUTPUT:
|
|||||||
}],
|
}],
|
||||||
"vars": [{
|
"vars": [{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"usr": 6975456769752895964,
|
"usr": 7730100248624586522,
|
||||||
"detailed_name": "F a",
|
"detailed_name": "F a",
|
||||||
"qual_name_offset": 2,
|
"qual_name_offset": 2,
|
||||||
"short_name": "a",
|
"short_name": "a",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "clang_complete.h"
|
#include "clang_complete.h"
|
||||||
|
|
||||||
#include "clang_utils.h"
|
#include "clang_utils.h"
|
||||||
|
#include "filesystem.hh"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "timer.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,
|
unsigned GetCompletionPriority(const CXCompletionString& str,
|
||||||
CXCursorKind result_kind,
|
CXCursorKind result_kind,
|
||||||
const std::optional<std::string>& typedText) {
|
const std::optional<std::string>& typedText) {
|
||||||
@ -671,12 +677,12 @@ ClangCompleteManager::ClangCompleteManager(Project* project,
|
|||||||
preloaded_sessions_(kMaxPreloadedSessions),
|
preloaded_sessions_(kMaxPreloadedSessions),
|
||||||
completion_sessions_(kMaxCompletionSessions) {
|
completion_sessions_(kMaxCompletionSessions) {
|
||||||
new std::thread([&]() {
|
new std::thread([&]() {
|
||||||
SetCurrentThreadName("completequery");
|
SetThreadName("completequery");
|
||||||
CompletionQueryMain(this);
|
CompletionQueryMain(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
new std::thread([&]() {
|
new std::thread([&]() {
|
||||||
SetCurrentThreadName("completeparse");
|
SetThreadName("completeparse");
|
||||||
CompletionParseMain(this);
|
CompletionParseMain(this);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2304,7 +2304,7 @@ std::vector<std::unique_ptr<IndexFile>> ParseWithTu(
|
|||||||
if (ls_diagnostic.severity != lsDiagnosticSeverity::Error)
|
if (ls_diagnostic.severity != lsDiagnosticSeverity::Error)
|
||||||
continue;
|
continue;
|
||||||
ls_diagnostic.range =
|
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);
|
param.primary_file->diagnostics_.push_back(ls_diagnostic);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@ lsRange GetLsRangeForFixIt(const CXSourceRange& range) {
|
|||||||
unsigned int end_line, end_column;
|
unsigned int end_line, end_column;
|
||||||
clang_getSpellingLocation(end, nullptr, &end_line, &end_column, nullptr);
|
clang_getSpellingLocation(end, nullptr, &end_line, &end_column, nullptr);
|
||||||
|
|
||||||
return lsRange(lsPosition(start_line - 1, start_column - 1) /*start*/,
|
return lsRange{lsPosition{int(start_line) - 1, int(start_column) - 1},
|
||||||
lsPosition(end_line - 1, end_column) /*end*/);
|
lsPosition{int(end_line) - 1, int(end_column)}};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -59,8 +59,8 @@ std::optional<lsDiagnostic> BuildAndDisposeDiagnostic(CXDiagnostic diagnostic,
|
|||||||
|
|
||||||
// Build diagnostic.
|
// Build diagnostic.
|
||||||
lsDiagnostic ls_diagnostic;
|
lsDiagnostic ls_diagnostic;
|
||||||
ls_diagnostic.range = lsRange(lsPosition(start_line - 1, start_column - 1),
|
ls_diagnostic.range = lsRange{{int(start_line) - 1, int(start_column) - 1},
|
||||||
lsPosition(end_line - 1, end_column - 1));
|
{int(end_line) - 1, int(end_column) - 1}};
|
||||||
|
|
||||||
ls_diagnostic.message = ToString(clang_getDiagnosticSpelling(diagnostic));
|
ls_diagnostic.message = ToString(clang_getDiagnosticSpelling(diagnostic));
|
||||||
|
|
||||||
|
@ -31,9 +31,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iostream>
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -76,8 +76,7 @@ bool ShouldDisplayMethodTiming(MethodType type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PrintHelp() {
|
void PrintHelp() {
|
||||||
std::cout
|
printf("%s", R"help(ccls is a C/C++/Objective-C language server.
|
||||||
<< R"help(ccls is a C/C++/Objective-C language server.
|
|
||||||
|
|
||||||
Mode:
|
Mode:
|
||||||
--test-unit Run unit tests.
|
--test-unit Run unit tests.
|
||||||
@ -101,7 +100,7 @@ Other command line options:
|
|||||||
out.
|
out.
|
||||||
|
|
||||||
See more on https://github.com/MaskRay/ccls/wiki
|
See more on https://github.com/MaskRay/ccls/wiki
|
||||||
)help";
|
)help");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -214,7 +213,7 @@ void RunQueryDbThread(const std::string& bin_name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run query db main loop.
|
// Run query db main loop.
|
||||||
SetCurrentThreadName("querydb");
|
SetThreadName("querydb");
|
||||||
while (true) {
|
while (true) {
|
||||||
bool did_work = QueryDbMainLoop(
|
bool did_work = QueryDbMainLoop(
|
||||||
&db, querydb_waiter, &project, &file_consumer_shared,
|
&db, querydb_waiter, &project, &file_consumer_shared,
|
||||||
@ -244,11 +243,8 @@ void RunQueryDbThread(const std::string& bin_name,
|
|||||||
//
|
//
|
||||||
// |ipc| is connected to a server.
|
// |ipc| is connected to a server.
|
||||||
void LaunchStdinLoop(std::unordered_map<MethodType, Timer>* request_times) {
|
void LaunchStdinLoop(std::unordered_map<MethodType, Timer>* request_times) {
|
||||||
// If flushing cin requires flushing cout there could be deadlocks in some
|
new std::thread([request_times]() {
|
||||||
// clients.
|
SetThreadName("stdin");
|
||||||
std::cin.tie(nullptr);
|
|
||||||
|
|
||||||
StartThread("stdin", [request_times]() {
|
|
||||||
auto* queue = QueueManager::instance();
|
auto* queue = QueueManager::instance();
|
||||||
while (true) {
|
while (true) {
|
||||||
std::unique_ptr<InMessage> message;
|
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,
|
void LaunchStdoutThread(std::unordered_map<MethodType, Timer>* request_times,
|
||||||
MultiQueueWaiter* waiter) {
|
MultiQueueWaiter* waiter) {
|
||||||
StartThread("stdout", [=]() {
|
new std::thread([=]() {
|
||||||
|
SetThreadName("stdout");
|
||||||
auto* queue = QueueManager::instance();
|
auto* queue = QueueManager::instance();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -387,9 +384,8 @@ int main(int argc, char** argv) {
|
|||||||
rapidjson::Document reader;
|
rapidjson::Document reader;
|
||||||
rapidjson::ParseResult ok = reader.Parse(g_init_options.c_str());
|
rapidjson::ParseResult ok = reader.Parse(g_init_options.c_str());
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
std::cerr << "Failed to parse --init as JSON: "
|
fprintf(stderr, "Failed to parse --init as JSON: %s (%zd)\n",
|
||||||
<< rapidjson::GetParseError_En(ok.Code()) << " ("
|
rapidjson::GetParseError_En(ok.Code()), ok.Offset());
|
||||||
<< ok.Offset() << ")\n";
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
JsonReader json_reader{&reader};
|
JsonReader json_reader{&reader};
|
||||||
@ -397,9 +393,9 @@ int main(int argc, char** argv) {
|
|||||||
Config config;
|
Config config;
|
||||||
Reflect(json_reader, config);
|
Reflect(json_reader, config);
|
||||||
} catch (std::invalid_argument& e) {
|
} catch (std::invalid_argument& e) {
|
||||||
std::cerr << "Fail to parse --init "
|
fprintf(stderr, "Failed to parse --init %s, expected %s\n",
|
||||||
<< static_cast<JsonReader&>(json_reader).GetPath()
|
static_cast<JsonReader&>(json_reader).GetPath().c_str(),
|
||||||
<< ", expected " << e.what() << "\n";
|
e.what());
|
||||||
return 1;
|
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
|
#pragma once
|
||||||
|
|
||||||
#include <experimental/filesystem>
|
#include <experimental/filesystem>
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace fs = std::experimental::filesystem;
|
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 "include_complete.h"
|
||||||
|
|
||||||
|
#include "filesystem.hh"
|
||||||
#include "match.h"
|
#include "match.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "standard_includes.h"
|
#include "standard_includes.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct CompletionCandidate {
|
struct CompletionCandidate {
|
||||||
@ -112,7 +115,8 @@ void IncludeComplete::Rescan() {
|
|||||||
g_config->completion.includeBlacklist);
|
g_config->completion.includeBlacklist);
|
||||||
|
|
||||||
is_scanning = true;
|
is_scanning = true;
|
||||||
StartThread("scan_includes", [this]() {
|
new std::thread([this]() {
|
||||||
|
SetThreadName("scan_includes");
|
||||||
Timer timer;
|
Timer timer;
|
||||||
|
|
||||||
InsertStlIncludes();
|
InsertStlIncludes();
|
||||||
|
@ -69,21 +69,21 @@ std::pair<bool, int> CaseFoldingSubsequenceMatch(std::string_view search,
|
|||||||
TEST_SUITE("Offset") {
|
TEST_SUITE("Offset") {
|
||||||
TEST_CASE("past end") {
|
TEST_CASE("past end") {
|
||||||
std::string content = "foo";
|
std::string content = "foo";
|
||||||
int offset = GetOffsetForPosition(lsPosition(10, 10), content);
|
int offset = GetOffsetForPosition(lsPosition{10, 10}, content);
|
||||||
REQUIRE(offset <= content.size());
|
REQUIRE(offset <= content.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("in middle of content") {
|
TEST_CASE("in middle of content") {
|
||||||
std::string content = "abcdefghijk";
|
std::string content = "abcdefghijk";
|
||||||
for (int i = 0; i < content.size(); ++i) {
|
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);
|
REQUIRE(i == offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("at end of content") {
|
TEST_CASE("at end of content") {
|
||||||
REQUIRE(GetOffsetForPosition(lsPosition(0, 0), "") == 0);
|
REQUIRE(GetOffsetForPosition(lsPosition{0, 0}, "") == 0);
|
||||||
REQUIRE(GetOffsetForPosition(lsPosition(0, 1), "a") == 1);
|
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;
|
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 {
|
std::string lsPosition::ToString() const {
|
||||||
return std::to_string(line) + ":" + std::to_string(character);
|
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) {
|
bool lsTextEdit::operator==(const lsTextEdit& that) {
|
||||||
return range == that.range && newText == that.newText;
|
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 {
|
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 line = 0;
|
||||||
int character = 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_HASHABLE(lsPosition, t.line, t.character);
|
||||||
MAKE_REFLECT_STRUCT(lsPosition, line, character);
|
MAKE_REFLECT_STRUCT(lsPosition, line, character);
|
||||||
|
|
||||||
struct lsRange {
|
struct lsRange {
|
||||||
lsRange();
|
|
||||||
lsRange(lsPosition start, lsPosition end);
|
|
||||||
|
|
||||||
bool operator==(const lsRange& other) const;
|
|
||||||
bool operator<(const lsRange& other) const;
|
|
||||||
|
|
||||||
lsPosition start;
|
lsPosition start;
|
||||||
lsPosition end;
|
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_HASHABLE(lsRange, t.start, t.end);
|
||||||
MAKE_REFLECT_STRUCT(lsRange, start, end);
|
MAKE_REFLECT_STRUCT(lsRange, start, end);
|
||||||
|
|
||||||
struct lsLocation {
|
struct lsLocation {
|
||||||
lsLocation();
|
|
||||||
lsLocation(lsDocumentUri uri, lsRange range);
|
|
||||||
|
|
||||||
bool operator==(const lsLocation& other) const;
|
|
||||||
bool operator<(const lsLocation& o) const;
|
|
||||||
|
|
||||||
lsDocumentUri uri;
|
lsDocumentUri uri;
|
||||||
lsRange range;
|
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_HASHABLE(lsLocation, t.uri, t.range);
|
||||||
MAKE_REFLECT_STRUCT(lsLocation, uri, 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
|
// Attribute range [events[i-1].pos, events[i].pos) to events[top-1].symbol
|
||||||
// .
|
// .
|
||||||
if (top && !(events[i - 1].pos == events[i].pos))
|
if (top && !(events[i - 1].pos == events[i].pos))
|
||||||
events[top - 1].symbol->ranges.emplace_back(events[i - 1].pos,
|
events[top - 1].symbol->ranges.push_back(
|
||||||
events[i].pos);
|
lsRange{events[i - 1].pos, events[i].pos});
|
||||||
if (events[i].id >= 0)
|
if (events[i].id >= 0)
|
||||||
events[top++] = events[i];
|
events[top++] = events[i];
|
||||||
else
|
else
|
||||||
|
@ -517,11 +517,12 @@ struct Handler_Initialize : BaseMessageHandler<In_InitializeRequest> {
|
|||||||
std::max(int(std::thread::hardware_concurrency() * 0.8), 1);
|
std::max(int(std::thread::hardware_concurrency() * 0.8), 1);
|
||||||
}
|
}
|
||||||
LOG_S(INFO) << "Starting " << g_config->index.threads << " indexers";
|
LOG_S(INFO) << "Starting " << g_config->index.threads << " indexers";
|
||||||
for (int i = 0; i < g_config->index.threads; ++i) {
|
for (int i = 0; i < g_config->index.threads; i++) {
|
||||||
StartThread("indexer" + std::to_string(i), [=]() {
|
new std::thread([=]() {
|
||||||
Indexer_Main(diag_engine, file_consumer_shared,
|
SetThreadName("indexer" + std::to_string(i));
|
||||||
timestamp_manager, import_manager,
|
Indexer_Main(diag_engine, file_consumer_shared, timestamp_manager,
|
||||||
import_pipeline_status, project, working_files, waiter);
|
import_manager, import_pipeline_status, project,
|
||||||
|
working_files, waiter);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ void PlatformInit();
|
|||||||
std::string GetExecutablePath();
|
std::string GetExecutablePath();
|
||||||
std::string NormalizePath(const std::string& path);
|
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);
|
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;
|
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());
|
loguru::set_thread_name(thread_name.c_str());
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
pthread_setname_np(thread_name.c_str());
|
pthread_setname_np(thread_name.c_str());
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
void PlatformInit() {
|
void PlatformInit() {
|
||||||
@ -60,7 +59,7 @@ typedef struct tagTHREADNAME_INFO {
|
|||||||
DWORD dwFlags; // Reserved for future use, must be zero.
|
DWORD dwFlags; // Reserved for future use, must be zero.
|
||||||
} THREADNAME_INFO;
|
} THREADNAME_INFO;
|
||||||
#pragma pack(pop)
|
#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());
|
loguru::set_thread_name(thread_name.c_str());
|
||||||
|
|
||||||
THREADNAME_INFO info;
|
THREADNAME_INFO info;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -47,7 +48,7 @@ struct ProjectConfig {
|
|||||||
std::unordered_set<std::string> quote_dirs;
|
std::unordered_set<std::string> quote_dirs;
|
||||||
std::unordered_set<std::string> angle_dirs;
|
std::unordered_set<std::string> angle_dirs;
|
||||||
std::vector<std::string> extra_flags;
|
std::vector<std::string> extra_flags;
|
||||||
std::string project_dir;
|
fs::path project_dir;
|
||||||
ProjectMode mode = ProjectMode::CompileCommandsJson;
|
ProjectMode mode = ProjectMode::CompileCommandsJson;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -107,7 +108,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
|
|||||||
const CompileCommandsEntry& entry) {
|
const CompileCommandsEntry& entry) {
|
||||||
Project::Entry result;
|
Project::Entry result;
|
||||||
result.filename = entry.file;
|
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
|
// Expand %c %cpp %clang
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
@ -256,7 +257,8 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
|
|||||||
std::vector<std::string> ReadCompilerArgumentsFromFile(
|
std::vector<std::string> ReadCompilerArgumentsFromFile(
|
||||||
const std::string& path) {
|
const std::string& path) {
|
||||||
std::vector<std::string> args;
|
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);
|
TrimInPlace(line);
|
||||||
if (line.empty() || StartsWith(line, "#"))
|
if (line.empty() || StartsWith(line, "#"))
|
||||||
continue;
|
continue;
|
||||||
@ -268,7 +270,7 @@ std::vector<std::string> ReadCompilerArgumentsFromFile(
|
|||||||
std::vector<Project::Entry> LoadFromDirectoryListing(ProjectConfig* config) {
|
std::vector<Project::Entry> LoadFromDirectoryListing(ProjectConfig* config) {
|
||||||
std::vector<Project::Entry> result;
|
std::vector<Project::Entry> result;
|
||||||
config->mode = ProjectMode::DotCcls;
|
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())
|
config->extra_flags.empty())
|
||||||
<< "ccls has no clang arguments. Considering adding either a "
|
<< "ccls has no clang arguments. Considering adding either a "
|
||||||
"compile_commands.json or .ccls file. See the ccls README for "
|
"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) {
|
[&folder_args, &files](const std::string& path) {
|
||||||
if (SourceFileLanguage(path) != LanguageId::Unknown) {
|
if (SourceFileLanguage(path) != LanguageId::Unknown) {
|
||||||
files.push_back(path);
|
files.push_back(path);
|
||||||
} else if (GetBaseName(path) == ".ccls") {
|
} else if (fs::path(path).filename() == ".ccls") {
|
||||||
LOG_S(INFO) << "Using .ccls arguments from " << path;
|
LOG_S(INFO) << "Using .ccls arguments from " << path;
|
||||||
folder_args.emplace(GetDirName(path),
|
folder_args.emplace(
|
||||||
ReadCompilerArgumentsFromFile(path));
|
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())
|
LOG_IF_S(INFO, !project_dir_args.empty())
|
||||||
<< "Using .ccls arguments " << StringJoin(project_dir_args);
|
<< "Using .ccls arguments " << StringJoin(project_dir_args);
|
||||||
|
|
||||||
auto GetCompilerArgumentForFile = [&config,
|
auto GetCompilerArgumentForFile = [&project_dir, &folder_args](fs::path cur) {
|
||||||
&folder_args](const std::string& path) {
|
while (!(cur = cur.parent_path()).empty()) {
|
||||||
for (std::string cur = GetDirName(path);; cur = GetDirName(cur)) {
|
|
||||||
auto it = folder_args.find(cur);
|
auto it = folder_args.find(cur);
|
||||||
if (it != folder_args.end())
|
if (it != folder_args.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
std::string normalized = NormalizePath(cur);
|
std::string normalized = NormalizePath(cur);
|
||||||
// Break if outside of the project root.
|
// Break if outside of the project root.
|
||||||
if (normalized.size() <= config->project_dir.size() ||
|
if (normalized.size() <= project_dir.size() ||
|
||||||
normalized.compare(0, config->project_dir.size(),
|
normalized.compare(0, project_dir.size(), project_dir) != 0)
|
||||||
config->project_dir) != 0)
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return folder_args[config->project_dir];
|
return folder_args[project_dir];
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const std::string& file : files) {
|
for (const std::string& file : files) {
|
||||||
@ -327,7 +329,7 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
|
|||||||
ProjectConfig* project,
|
ProjectConfig* project,
|
||||||
const std::string& opt_compilation_db_dir) {
|
const std::string& opt_compilation_db_dir) {
|
||||||
// If there is a .ccls file always load using directory listing.
|
// 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);
|
return LoadFromDirectoryListing(project);
|
||||||
|
|
||||||
// If |compilationDatabaseCommand| is specified, execute it to get the compdb.
|
// If |compilationDatabaseCommand| is specified, execute it to get the compdb.
|
||||||
@ -335,7 +337,7 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
|
|||||||
if (g_config->compilationDatabaseCommand.empty()) {
|
if (g_config->compilationDatabaseCommand.empty()) {
|
||||||
project->mode = ProjectMode::CompileCommandsJson;
|
project->mode = ProjectMode::CompileCommandsJson;
|
||||||
// Try to load compile_commands.json, but fallback to a project listing.
|
// 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;
|
: opt_compilation_db_dir;
|
||||||
} else {
|
} else {
|
||||||
project->mode = ProjectMode::ExternalCommand;
|
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
|
// |best_entry| probably has its own path in the arguments. We need to remap
|
||||||
// that path to the new filename.
|
// 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) {
|
for (std::string& arg : result.args) {
|
||||||
if (arg == best_entry->filename ||
|
try {
|
||||||
GetBaseName(arg) == best_entry_base_name) {
|
if (arg == best_entry->filename ||
|
||||||
arg = filename;
|
fs::path(arg).filename() == best_entry_base_name) {
|
||||||
|
arg = filename;
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -669,7 +674,7 @@ TEST_SUITE("Project") {
|
|||||||
"--foobar",
|
"--foobar",
|
||||||
"-Ia_relative1",
|
"-Ia_relative1",
|
||||||
"--foobar",
|
"--foobar",
|
||||||
"-I",
|
"-isystem",
|
||||||
"a_relative2",
|
"a_relative2",
|
||||||
"--foobar",
|
"--foobar",
|
||||||
"-iquote/q_absolute1",
|
"-iquote/q_absolute1",
|
||||||
@ -691,7 +696,8 @@ TEST_SUITE("Project") {
|
|||||||
"/a_absolute1", "/a_absolute2", "/base/a_relative1",
|
"/a_absolute1", "/a_absolute2", "/base/a_relative1",
|
||||||
"/base/a_relative2"};
|
"/base/a_relative2"};
|
||||||
std::unordered_set<std::string> quote_expected{
|
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"};
|
"/base/q_relative2"};
|
||||||
REQUIRE(config.angle_dirs == angle_expected);
|
REQUIRE(config.angle_dirs == angle_expected);
|
||||||
REQUIRE(config.quote_dirs == quote_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,
|
std::optional<lsPosition> GetLsPosition(WorkingFile* working_file,
|
||||||
const Position& position) {
|
const Position& position) {
|
||||||
if (!working_file)
|
if (!working_file)
|
||||||
return lsPosition(position.line, position.column);
|
return lsPosition{position.line, position.column};
|
||||||
|
|
||||||
int column = position.column;
|
int column = position.column;
|
||||||
if (std::optional<int> start =
|
if (std::optional<int> start =
|
||||||
working_file->GetBufferPosFromIndexPos(position.line, &column, false))
|
working_file->GetBufferPosFromIndexPos(position.line, &column, false))
|
||||||
return lsPosition(*start, column);
|
return lsPosition{*start, column};
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<lsRange> GetLsRange(WorkingFile* working_file, const Range& location) {
|
std::optional<lsRange> GetLsRange(WorkingFile* working_file, const Range& location) {
|
||||||
if (!working_file) {
|
if (!working_file) {
|
||||||
return lsRange(lsPosition(location.start.line, location.start.column),
|
return lsRange{lsPosition{location.start.line, location.start.column},
|
||||||
lsPosition(location.end.line, location.end.column));
|
lsPosition{location.end.line, location.end.column}};
|
||||||
}
|
}
|
||||||
|
|
||||||
int start_column = location.start.column, end_column = 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)
|
if (*start == *end && start_column > end_column)
|
||||||
end_column = start_column;
|
end_column = start_column;
|
||||||
|
|
||||||
return lsRange(lsPosition(*start, start_column),
|
return lsRange{lsPosition{*start, start_column},
|
||||||
lsPosition(*end, end_column));
|
lsPosition{*end, end_column}};
|
||||||
}
|
}
|
||||||
|
|
||||||
lsDocumentUri GetLsDocumentUri(QueryDatabase* db,
|
lsDocumentUri GetLsDocumentUri(QueryDatabase* db,
|
||||||
@ -227,7 +227,7 @@ std::optional<lsLocation> GetLsLocation(QueryDatabase* db,
|
|||||||
GetLsRange(working_files->GetFileByFilename(path), use.range);
|
GetLsRange(working_files->GetFileByFilename(path), use.range);
|
||||||
if (!range)
|
if (!range)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
return lsLocation(uri, *range);
|
return lsLocation{uri, *range};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<lsLocationEx> GetLsLocationEx(QueryDatabase* db,
|
std::optional<lsLocationEx> GetLsLocationEx(QueryDatabase* db,
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
|
|
||||||
|
#include "filesystem.hh"
|
||||||
#include "serializers/json.h"
|
#include "serializers/json.h"
|
||||||
#include "serializers/msgpack.h"
|
#include "serializers/msgpack.h"
|
||||||
|
|
||||||
#include "indexer.h"
|
#include "indexer.h"
|
||||||
|
|
||||||
#include <doctest/doctest.h>
|
|
||||||
#include <loguru.hpp>
|
#include <loguru.hpp>
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@ -153,7 +153,7 @@ void Reflect(Writer& visitor, IndexInclude& value) {
|
|||||||
REFLECT_MEMBER_START();
|
REFLECT_MEMBER_START();
|
||||||
REFLECT_MEMBER(line);
|
REFLECT_MEMBER(line);
|
||||||
if (gTestOutputMode) {
|
if (gTestOutputMode) {
|
||||||
std::string basename = GetBaseName(value.resolved_path);
|
std::string basename = fs::path(value.resolved_path).filename();
|
||||||
if (!StartsWith(value.resolved_path, "&"))
|
if (!StartsWith(value.resolved_path, "&"))
|
||||||
basename = "&" + basename;
|
basename = "&" + basename;
|
||||||
REFLECT_MEMBER2("resolved_path", basename);
|
REFLECT_MEMBER2("resolved_path", basename);
|
||||||
@ -279,7 +279,7 @@ bool ReflectMemberStart(Writer& visitor, IndexFile& value) {
|
|||||||
assert(value.Resolve(it->second)->uses.size() == 0);
|
assert(value.Resolve(it->second)->uses.size() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultReflectMemberStart(visitor);
|
visitor.StartObject();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template <typename TVisitor>
|
template <typename TVisitor>
|
||||||
@ -441,17 +441,3 @@ std::unique_ptr<IndexFile> Deserialize(
|
|||||||
|
|
||||||
return file;
|
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 IsBool() = 0;
|
||||||
virtual bool IsNull() = 0;
|
virtual bool IsNull() = 0;
|
||||||
virtual bool IsArray() = 0;
|
|
||||||
virtual bool IsInt() = 0;
|
virtual bool IsInt() = 0;
|
||||||
virtual bool IsInt64() = 0;
|
virtual bool IsInt64() = 0;
|
||||||
virtual bool IsUint64() = 0;
|
virtual bool IsUint64() = 0;
|
||||||
@ -73,7 +72,6 @@ struct IndexFile;
|
|||||||
|
|
||||||
#define REFLECT_MEMBER_START() ReflectMemberStart(visitor, value)
|
#define REFLECT_MEMBER_START() ReflectMemberStart(visitor, value)
|
||||||
#define REFLECT_MEMBER_END() ReflectMemberEnd(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_MEMBER(name) ReflectMember(visitor, #name, value.name)
|
||||||
#define REFLECT_MEMBER2(name, value) ReflectMember(visitor, name, value)
|
#define REFLECT_MEMBER2(name, value) ReflectMember(visitor, name, value)
|
||||||
|
|
||||||
@ -315,11 +313,6 @@ void Reflect(Writer& visitor, std::vector<T>& values) {
|
|||||||
|
|
||||||
// ReflectMember
|
// ReflectMember
|
||||||
|
|
||||||
inline void DefaultReflectMemberStart(Writer& visitor) {
|
|
||||||
visitor.StartObject();
|
|
||||||
}
|
|
||||||
inline void DefaultReflectMemberStart(Reader& visitor) {}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool ReflectMemberStart(Reader& visitor, T& value) {
|
bool ReflectMemberStart(Reader& visitor, T& value) {
|
||||||
return false;
|
return false;
|
||||||
@ -356,5 +349,3 @@ std::unique_ptr<IndexFile> Deserialize(
|
|||||||
const std::string& serialized_index_content,
|
const std::string& serialized_index_content,
|
||||||
const std::string& file_content,
|
const std::string& file_content,
|
||||||
std::optional<int> expected_version);
|
std::optional<int> expected_version);
|
||||||
|
|
||||||
void SetTestOutputMode();
|
|
||||||
|
@ -15,7 +15,6 @@ class JsonReader : public Reader {
|
|||||||
|
|
||||||
bool IsBool() override { return m_->IsBool(); }
|
bool IsBool() override { return m_->IsBool(); }
|
||||||
bool IsNull() override { return m_->IsNull(); }
|
bool IsNull() override { return m_->IsNull(); }
|
||||||
bool IsArray() override { return m_->IsArray(); }
|
|
||||||
bool IsInt() override { return m_->IsInt(); }
|
bool IsInt() override { return m_->IsInt(); }
|
||||||
bool IsInt64() override { return m_->IsInt64(); }
|
bool IsInt64() override { return m_->IsInt64(); }
|
||||||
bool IsUint64() override { return m_->IsUint64(); }
|
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 IsBool() override { return oh_.get().type == msgpack::type::BOOLEAN; }
|
||||||
bool IsNull() override { return oh_.get().is_nil(); }
|
bool IsNull() override { return oh_.get().is_nil(); }
|
||||||
bool IsArray() override { return oh_.get().type == msgpack::type::ARRAY; }
|
|
||||||
bool IsInt() override {
|
bool IsInt() override {
|
||||||
return oh_.get().type == msgpack::type::POSITIVE_INTEGER ||
|
return oh_.get().type == msgpack::type::POSITIVE_INTEGER ||
|
||||||
oh_.get().type == msgpack::type::NEGATIVE_INTEGER;
|
oh_.get().type == msgpack::type::NEGATIVE_INTEGER;
|
||||||
|
302
src/test.cc
302
src/test.cc
@ -1,5 +1,6 @@
|
|||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
|
#include "filesystem.hh"
|
||||||
#include "indexer.h"
|
#include "indexer.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
@ -15,7 +16,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
// The 'diff' utility is available and we can use dprintf(3).
|
// The 'diff' utility is available and we can use dprintf(3).
|
||||||
#if _POSIX_C_SOURCE >= 200809L
|
#if _POSIX_C_SOURCE >= 200809L
|
||||||
@ -23,6 +23,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern bool gTestOutputMode;
|
||||||
|
|
||||||
std::string ToString(const rapidjson::Document& document) {
|
std::string ToString(const rapidjson::Document& document) {
|
||||||
rapidjson::StringBuffer buffer;
|
rapidjson::StringBuffer buffer;
|
||||||
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
|
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
|
||||||
@ -35,6 +37,33 @@ std::string ToString(const rapidjson::Document& document) {
|
|||||||
return buffer.GetString();
|
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(
|
void ParseTestExpectation(
|
||||||
const std::string& filename,
|
const std::string& filename,
|
||||||
const std::vector<std::string>& lines_with_endings,
|
const std::vector<std::string>& lines_with_endings,
|
||||||
@ -125,8 +154,7 @@ void DiffDocuments(std::string path,
|
|||||||
rapidjson::Document& actual) {
|
rapidjson::Document& actual) {
|
||||||
std::string joined_actual_output = ToString(actual);
|
std::string joined_actual_output = ToString(actual);
|
||||||
std::string joined_expected_output = ToString(expected);
|
std::string joined_expected_output = ToString(expected);
|
||||||
std::cout << "[FAILED] " << path << " (section " << path_section << ")"
|
printf("[FAILED] %s (section %s)\n", path.c_str(), path_section.c_str());
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
#if _POSIX_C_SOURCE >= 200809L
|
#if _POSIX_C_SOURCE >= 200809L
|
||||||
char expected_file[] = "/tmp/ccls.expected.XXXXXX";
|
char expected_file[] = "/tmp/ccls.expected.XXXXXX";
|
||||||
@ -156,13 +184,10 @@ void DiffDocuments(std::string path,
|
|||||||
std::vector<std::string> expected_output =
|
std::vector<std::string> expected_output =
|
||||||
SplitString(joined_expected_output, "\n");
|
SplitString(joined_expected_output, "\n");
|
||||||
|
|
||||||
std::cout << "Expected output for " << path << " (section " << path_section
|
printf("Expected output for %s (section %s)\n:%s\n", path.c_str(),
|
||||||
<< "):" << std::endl;
|
path_section.c_str(), joined_expected_output.c_str());
|
||||||
std::cout << joined_expected_output << std::endl;
|
printf("Actual output for %s (section %s)\n:%s\n", path.c_str(),
|
||||||
std::cout << "Actual output for " << path << " (section " << path_section
|
path_section.c_str(), joined_actual_output.c_str());
|
||||||
<< "):" << std::endl;
|
|
||||||
std::cout << joined_actual_output << std::endl;
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerifySerializeToFrom(IndexFile* file) {
|
void VerifySerializeToFrom(IndexFile* file) {
|
||||||
@ -173,7 +198,7 @@ void VerifySerializeToFrom(IndexFile* file) {
|
|||||||
std::nullopt /*expected_version*/);
|
std::nullopt /*expected_version*/);
|
||||||
std::string actual = result->ToString();
|
std::string actual = result->ToString();
|
||||||
if (expected != actual) {
|
if (expected != actual) {
|
||||||
std::cerr << "Serialization failure" << std::endl;
|
fprintf(stderr, "Serialization failure\n");
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,7 +211,7 @@ std::string FindExpectedOutputForFilename(
|
|||||||
return entry.second;
|
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();
|
||||||
getchar();
|
getchar();
|
||||||
return "{}";
|
return "{}";
|
||||||
@ -203,16 +228,17 @@ IndexFile* FindDbForPathEnding(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RunIndexTests(const std::string& filter_path, bool enable_update) {
|
bool RunIndexTests(const std::string& filter_path, bool enable_update) {
|
||||||
SetTestOutputMode();
|
gTestOutputMode = true;
|
||||||
|
|
||||||
// Index tests change based on the version of clang used.
|
// 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)";
|
"clang version 6.0.0 (tags/RELEASE_600/final)";
|
||||||
if (GetClangVersion() != kRequiredClangVersion &&
|
if (GetClangVersion() != kRequiredClangVersion &&
|
||||||
GetClangVersion().find("trunk") == std::string::npos) {
|
GetClangVersion().find("trunk") == std::string::npos) {
|
||||||
std::cerr << "Index tests must be run using clang version \""
|
fprintf(stderr,
|
||||||
<< kRequiredClangVersion << "\" (ccls is running with \""
|
"Index tests must be run using clang version %s, ccls is running "
|
||||||
<< GetClangVersion() << "\")" << std::endl;
|
"with %s\n",
|
||||||
|
kRequiredClangVersion, GetClangVersion().c_str());
|
||||||
return false;
|
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
|
// FIXME: show diagnostics in STL/headers when running tests. At the moment
|
||||||
// this can be done by constructing ClangIndex index(1, 1);
|
// this can be done by constructing ClangIndex index(1, 1);
|
||||||
ClangIndex index;
|
ClangIndex index;
|
||||||
for (std::string path : GetFilesInFolder("index_tests", true /*recursive*/,
|
GetFilesInFolder(
|
||||||
true /*add_folder_to_path*/)) {
|
"index_tests", true /*recursive*/, true /*add_folder_to_path*/,
|
||||||
bool is_fail_allowed = false;
|
[&](const std::string& path) {
|
||||||
|
bool is_fail_allowed = false;
|
||||||
|
|
||||||
if (EndsWithAny(path, {".m", ".mm"})) {
|
if (EndsWithAny(path, {".m", ".mm"})) {
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
std::cout << "Skipping \"" << path << "\" since this platform does not "
|
return;
|
||||||
<< "support running Objective-C tests." << std::endl;
|
|
||||||
continue;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// objective-c tests are often not updated right away. do not bring down
|
// objective-c tests are often not updated right away. do not bring
|
||||||
// CI if they fail.
|
// down
|
||||||
if (!enable_update)
|
// CI if they fail.
|
||||||
is_fail_allowed = true;
|
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 ";
|
|
||||||
}
|
}
|
||||||
assert(false && "not reached");
|
|
||||||
return "";
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get output from index operation.
|
if (path.find(filter_path) == std::string::npos)
|
||||||
IndexFile* db = FindDbForPathEnding(expected_path, dbs);
|
return;
|
||||||
assert(db);
|
|
||||||
if (!db->diagnostics_.empty()) {
|
if (!filter_path.empty())
|
||||||
std::cout << "For " << path << std::endl;
|
printf("Running %s\n", path.c_str());
|
||||||
for (const lsDiagnostic& diagnostic : db->diagnostics_) {
|
|
||||||
std::cout << " ";
|
// Parse expected output from the test, parse it into JSON document.
|
||||||
if (diagnostic.severity)
|
std::vector<std::string> lines_with_endings;
|
||||||
std::cout << severity_to_string(*diagnostic.severity);
|
{
|
||||||
std::cout << basename(db->path) << ":"
|
std::ifstream fin(path);
|
||||||
<< diagnostic.range.start.ToString() << "-"
|
for (std::string line; std::getline(fin, line);)
|
||||||
<< diagnostic.range.end.ToString() << ": "
|
lines_with_endings.push_back(line);
|
||||||
<< diagnostic.message << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
TextReplacer text_replacer;
|
||||||
std::string actual_output = "{}";
|
std::vector<std::string> flags;
|
||||||
if (db) {
|
std::unordered_map<std::string, std::string> all_expected_output;
|
||||||
VerifySerializeToFrom(db);
|
ParseTestExpectation(path, lines_with_endings, &text_replacer, &flags,
|
||||||
actual_output = db->ToString();
|
&all_expected_output);
|
||||||
}
|
|
||||||
actual_output = text_replacer.Apply(actual_output);
|
|
||||||
|
|
||||||
// Compare output via rapidjson::Document to ignore any formatting
|
// Build flags.
|
||||||
// differences.
|
if (!AnyStartsWith(flags, "-x"))
|
||||||
rapidjson::Document actual;
|
flags.push_back("-xc++");
|
||||||
actual.Parse(actual_output.c_str());
|
flags.push_back("-resource-dir=" + GetDefaultResourceDirectory());
|
||||||
rapidjson::Document expected;
|
flags.push_back(path);
|
||||||
expected.Parse(expected_output.c_str());
|
|
||||||
|
|
||||||
if (actual == expected) {
|
// Run test.
|
||||||
// std::cout << "[PASSED] " << path << std::endl;
|
g_config = std::make_unique<Config>();
|
||||||
} else {
|
FileConsumerSharedState file_consumer_shared;
|
||||||
if (!is_fail_allowed)
|
PerformanceImportFile perf;
|
||||||
success = false;
|
auto dbs = Parse(&file_consumer_shared, path, flags, {}, &perf, &index,
|
||||||
DiffDocuments(path, expected_path, expected, actual);
|
false /*dump_ast*/);
|
||||||
std::cout << std::endl;
|
|
||||||
std::cout << std::endl;
|
for (const auto& entry : all_expected_output) {
|
||||||
if (enable_update) {
|
const std::string& expected_path = entry.first;
|
||||||
std::cout
|
std::string expected_output = text_replacer.Apply(entry.second);
|
||||||
<< "[Enter to continue - type u to update test, a to update all]";
|
|
||||||
char c = 'u';
|
// FIXME: promote to utils, find and remove duplicates (ie,
|
||||||
if (!update_all) {
|
// ccls_call_tree.cc, maybe something in project.cc).
|
||||||
c = getchar();
|
auto basename = [](const std::string& path) -> std::string {
|
||||||
getchar();
|
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')
|
// Compare output via rapidjson::Document to ignore any formatting
|
||||||
update_all = true;
|
// differences.
|
||||||
|
rapidjson::Document actual;
|
||||||
|
actual.Parse(actual_output.c_str());
|
||||||
|
rapidjson::Document expected;
|
||||||
|
expected.Parse(expected_output.c_str());
|
||||||
|
|
||||||
if (update_all || c == 'u') {
|
if (actual == expected) {
|
||||||
// Note: we use |entry.second| instead of |expected_output| because
|
// std::cout << "[PASSED] " << path << std::endl;
|
||||||
// |expected_output| has had text replacements applied.
|
} else {
|
||||||
UpdateTestExpectation(path, entry.second, ToString(actual) + "\n");
|
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;
|
return success;
|
||||||
}
|
}
|
||||||
|
129
src/utils.cc
129
src/utils.cc
@ -1,6 +1,5 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#include "filesystem.hh"
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
|
||||||
#include <doctest/doctest.h>
|
#include <doctest/doctest.h>
|
||||||
@ -12,12 +11,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <fstream>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <queue>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
#include <thread>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
using namespace std::placeholders;
|
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,
|
std::vector<std::string> SplitString(const std::string& str,
|
||||||
const std::string& delimiter) {
|
const std::string& delimiter) {
|
||||||
// http://stackoverflow.com/a/13172514
|
// http://stackoverflow.com/a/13172514
|
||||||
@ -132,54 +106,6 @@ std::string LowerPathIfInsensitive(const std::string& path) {
|
|||||||
#endif
|
#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) {
|
void EnsureEndsInSlash(std::string& path) {
|
||||||
if (path.empty() || path[path.size() - 1] != '/')
|
if (path.empty() || path[path.size() - 1] != '/')
|
||||||
path += '/';
|
path += '/';
|
||||||
@ -195,10 +121,6 @@ std::string EscapeFileName(std::string path) {
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileExists(const std::string& filename) {
|
|
||||||
return fs::exists(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<std::string> ReadContent(const std::string& filename) {
|
std::optional<std::string> ReadContent(const std::string& filename) {
|
||||||
LOG_S(INFO) << "Reading " << filename;
|
LOG_S(INFO) << "Reading " << filename;
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
@ -211,41 +133,6 @@ std::optional<std::string> ReadContent(const std::string& filename) {
|
|||||||
return ret;
|
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) {
|
void WriteToFile(const std::string& filename, const std::string& content) {
|
||||||
FILE* f = fopen(filename.c_str(), "wb");
|
FILE* f = fopen(filename.c_str(), "wb");
|
||||||
if (!f || fwrite(content.c_str(), content.size(), 1, f) != 1) {
|
if (!f || fwrite(content.c_str(), content.size(), 1, f) != 1) {
|
||||||
@ -278,19 +165,3 @@ std::string GetDefaultResourceDirectory() {
|
|||||||
|
|
||||||
return NormalizePath(result);
|
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 <string_view>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#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 EndsWithAny(std::string_view s, const std::vector<std::string>& ss);
|
||||||
bool FindAnyPartial(const std::string& value,
|
bool FindAnyPartial(const std::string& value,
|
||||||
const std::vector<std::string>& values);
|
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,
|
std::vector<std::string> SplitString(const std::string& str,
|
||||||
const std::string& delimiter);
|
const std::string& delimiter);
|
||||||
@ -62,15 +54,6 @@ bool ContainsValue(const TCollection& collection, const TValue& value) {
|
|||||||
return collection.find(value) != collection.end();
|
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.
|
// Ensures that |path| ends in a slash.
|
||||||
void EnsureEndsInSlash(std::string& path);
|
void EnsureEndsInSlash(std::string& path);
|
||||||
|
|
||||||
@ -78,22 +61,7 @@ void EnsureEndsInSlash(std::string& path);
|
|||||||
// e.g. foo/bar.c => foo_bar.c
|
// e.g. foo/bar.c => foo_bar.c
|
||||||
std::string EscapeFileName(std::string path);
|
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::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);
|
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();
|
std::string GetDefaultResourceDirectory();
|
||||||
|
|
||||||
void StartThread(const std::string& thread_name, std::function<void()> entry);
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -38,6 +39,15 @@ lsPosition GetPositionForOffset(const std::string& content, int offset) {
|
|||||||
return result;
|
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.
|
// Computes the edit distance of strings [a,a+la) and [b,b+lb) with Eugene W.
|
||||||
// Myers' O(ND) diff algorithm.
|
// Myers' O(ND) diff algorithm.
|
||||||
// Costs: insertion=1, deletion=1, no substitution.
|
// Costs: insertion=1, deletion=1, no substitution.
|
||||||
|
Loading…
Reference in New Issue
Block a user