1*e5dd7070Spatrickimport os 2*e5dd7070Spatrickfrom clang.cindex import Config 3*e5dd7070Spatrickif 'CLANG_LIBRARY_PATH' in os.environ: 4*e5dd7070Spatrick Config.set_library_path(os.environ['CLANG_LIBRARY_PATH']) 5*e5dd7070Spatrick 6*e5dd7070Spatrickfrom clang.cindex import TranslationUnit 7*e5dd7070Spatrick 8*e5dd7070Spatrickimport unittest 9*e5dd7070Spatrickfrom .util import skip_if_no_fspath 10*e5dd7070Spatrickfrom .util import str_to_path 11*e5dd7070Spatrick 12*e5dd7070Spatrick 13*e5dd7070Spatrickclass TestCodeCompletion(unittest.TestCase): 14*e5dd7070Spatrick def check_completion_results(self, cr, expected): 15*e5dd7070Spatrick self.assertIsNotNone(cr) 16*e5dd7070Spatrick self.assertEqual(len(cr.diagnostics), 0) 17*e5dd7070Spatrick 18*e5dd7070Spatrick completions = [str(c) for c in cr.results] 19*e5dd7070Spatrick 20*e5dd7070Spatrick for c in expected: 21*e5dd7070Spatrick self.assertIn(c, completions) 22*e5dd7070Spatrick 23*e5dd7070Spatrick def test_code_complete(self): 24*e5dd7070Spatrick files = [('fake.c', """ 25*e5dd7070Spatrick/// Aaa. 26*e5dd7070Spatrickint test1; 27*e5dd7070Spatrick 28*e5dd7070Spatrick/// Bbb. 29*e5dd7070Spatrickvoid test2(void); 30*e5dd7070Spatrick 31*e5dd7070Spatrickvoid f() { 32*e5dd7070Spatrick 33*e5dd7070Spatrick} 34*e5dd7070Spatrick""")] 35*e5dd7070Spatrick 36*e5dd7070Spatrick tu = TranslationUnit.from_source('fake.c', ['-std=c99'], unsaved_files=files, 37*e5dd7070Spatrick options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION) 38*e5dd7070Spatrick 39*e5dd7070Spatrick cr = tu.codeComplete('fake.c', 9, 1, unsaved_files=files, include_brief_comments=True) 40*e5dd7070Spatrick 41*e5dd7070Spatrick expected = [ 42*e5dd7070Spatrick "{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.", 43*e5dd7070Spatrick "{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.", 44*e5dd7070Spatrick "{'return', TypedText} | {';', SemiColon} || Priority: 40 || Availability: Available || Brief comment: None" 45*e5dd7070Spatrick ] 46*e5dd7070Spatrick self.check_completion_results(cr, expected) 47*e5dd7070Spatrick 48*e5dd7070Spatrick @skip_if_no_fspath 49*e5dd7070Spatrick def test_code_complete_pathlike(self): 50*e5dd7070Spatrick files = [(str_to_path('fake.c'), """ 51*e5dd7070Spatrick/// Aaa. 52*e5dd7070Spatrickint test1; 53*e5dd7070Spatrick 54*e5dd7070Spatrick/// Bbb. 55*e5dd7070Spatrickvoid test2(void); 56*e5dd7070Spatrick 57*e5dd7070Spatrickvoid f() { 58*e5dd7070Spatrick 59*e5dd7070Spatrick} 60*e5dd7070Spatrick""")] 61*e5dd7070Spatrick 62*e5dd7070Spatrick tu = TranslationUnit.from_source(str_to_path('fake.c'), ['-std=c99'], unsaved_files=files, 63*e5dd7070Spatrick options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION) 64*e5dd7070Spatrick 65*e5dd7070Spatrick cr = tu.codeComplete(str_to_path('fake.c'), 9, 1, unsaved_files=files, include_brief_comments=True) 66*e5dd7070Spatrick 67*e5dd7070Spatrick expected = [ 68*e5dd7070Spatrick "{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.", 69*e5dd7070Spatrick "{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.", 70*e5dd7070Spatrick "{'return', TypedText} | {';', SemiColon} || Priority: 40 || Availability: Available || Brief comment: None" 71*e5dd7070Spatrick ] 72*e5dd7070Spatrick self.check_completion_results(cr, expected) 73*e5dd7070Spatrick 74*e5dd7070Spatrick def test_code_complete_availability(self): 75*e5dd7070Spatrick files = [('fake.cpp', """ 76*e5dd7070Spatrickclass P { 77*e5dd7070Spatrickprotected: 78*e5dd7070Spatrick int member; 79*e5dd7070Spatrick}; 80*e5dd7070Spatrick 81*e5dd7070Spatrickclass Q : public P { 82*e5dd7070Spatrickpublic: 83*e5dd7070Spatrick using P::member; 84*e5dd7070Spatrick}; 85*e5dd7070Spatrick 86*e5dd7070Spatrickvoid f(P x, Q y) { 87*e5dd7070Spatrick x.; // member is inaccessible 88*e5dd7070Spatrick y.; // member is accessible 89*e5dd7070Spatrick} 90*e5dd7070Spatrick""")] 91*e5dd7070Spatrick 92*e5dd7070Spatrick tu = TranslationUnit.from_source('fake.cpp', ['-std=c++98'], unsaved_files=files) 93*e5dd7070Spatrick 94*e5dd7070Spatrick cr = tu.codeComplete('fake.cpp', 12, 5, unsaved_files=files) 95*e5dd7070Spatrick 96*e5dd7070Spatrick expected = [ 97*e5dd7070Spatrick "{'const', TypedText} || Priority: 50 || Availability: Available || Brief comment: None", 98*e5dd7070Spatrick "{'volatile', TypedText} || Priority: 50 || Availability: Available || Brief comment: None", 99*e5dd7070Spatrick "{'operator', TypedText} || Priority: 40 || Availability: Available || Brief comment: None", 100*e5dd7070Spatrick "{'P', TypedText} || Priority: 50 || Availability: Available || Brief comment: None", 101*e5dd7070Spatrick "{'Q', TypedText} || Priority: 50 || Availability: Available || Brief comment: None" 102*e5dd7070Spatrick ] 103*e5dd7070Spatrick self.check_completion_results(cr, expected) 104*e5dd7070Spatrick 105*e5dd7070Spatrick cr = tu.codeComplete('fake.cpp', 13, 5, unsaved_files=files) 106*e5dd7070Spatrick expected = [ 107*e5dd7070Spatrick "{'P', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: None", 108*e5dd7070Spatrick "{'P &', ResultType} | {'operator=', TypedText} | {'(', LeftParen} | {'const P &', Placeholder} | {')', RightParen} || Priority: 79 || Availability: Available || Brief comment: None", 109*e5dd7070Spatrick "{'int', ResultType} | {'member', TypedText} || Priority: 35 || Availability: NotAccessible || Brief comment: None", 110*e5dd7070Spatrick "{'void', ResultType} | {'~P', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 79 || Availability: Available || Brief comment: None" 111*e5dd7070Spatrick ] 112*e5dd7070Spatrick self.check_completion_results(cr, expected) 113