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 Cursor 7*e5dd7070Spatrickfrom clang.cindex import File 8*e5dd7070Spatrickfrom clang.cindex import SourceLocation 9*e5dd7070Spatrickfrom clang.cindex import SourceRange 10*e5dd7070Spatrickfrom .util import get_cursor 11*e5dd7070Spatrickfrom .util import get_tu 12*e5dd7070Spatrick 13*e5dd7070Spatrickimport unittest 14*e5dd7070Spatrick 15*e5dd7070Spatrick 16*e5dd7070SpatrickbaseInput="int one;\nint two;\n" 17*e5dd7070Spatrick 18*e5dd7070Spatrick 19*e5dd7070Spatrickclass TestLocation(unittest.TestCase): 20*e5dd7070Spatrick def assert_location(self, loc, line, column, offset): 21*e5dd7070Spatrick self.assertEqual(loc.line, line) 22*e5dd7070Spatrick self.assertEqual(loc.column, column) 23*e5dd7070Spatrick self.assertEqual(loc.offset, offset) 24*e5dd7070Spatrick 25*e5dd7070Spatrick def test_location(self): 26*e5dd7070Spatrick tu = get_tu(baseInput) 27*e5dd7070Spatrick one = get_cursor(tu, 'one') 28*e5dd7070Spatrick two = get_cursor(tu, 'two') 29*e5dd7070Spatrick 30*e5dd7070Spatrick self.assertIsNotNone(one) 31*e5dd7070Spatrick self.assertIsNotNone(two) 32*e5dd7070Spatrick 33*e5dd7070Spatrick self.assert_location(one.location,line=1,column=5,offset=4) 34*e5dd7070Spatrick self.assert_location(two.location,line=2,column=5,offset=13) 35*e5dd7070Spatrick 36*e5dd7070Spatrick # adding a linebreak at top should keep columns same 37*e5dd7070Spatrick tu = get_tu('\n' + baseInput) 38*e5dd7070Spatrick one = get_cursor(tu, 'one') 39*e5dd7070Spatrick two = get_cursor(tu, 'two') 40*e5dd7070Spatrick 41*e5dd7070Spatrick self.assertIsNotNone(one) 42*e5dd7070Spatrick self.assertIsNotNone(two) 43*e5dd7070Spatrick 44*e5dd7070Spatrick self.assert_location(one.location,line=2,column=5,offset=5) 45*e5dd7070Spatrick self.assert_location(two.location,line=3,column=5,offset=14) 46*e5dd7070Spatrick 47*e5dd7070Spatrick # adding a space should affect column on first line only 48*e5dd7070Spatrick tu = get_tu(' ' + baseInput) 49*e5dd7070Spatrick one = get_cursor(tu, 'one') 50*e5dd7070Spatrick two = get_cursor(tu, 'two') 51*e5dd7070Spatrick 52*e5dd7070Spatrick self.assert_location(one.location,line=1,column=6,offset=5) 53*e5dd7070Spatrick self.assert_location(two.location,line=2,column=5,offset=14) 54*e5dd7070Spatrick 55*e5dd7070Spatrick # define the expected location ourselves and see if it matches 56*e5dd7070Spatrick # the returned location 57*e5dd7070Spatrick tu = get_tu(baseInput) 58*e5dd7070Spatrick 59*e5dd7070Spatrick file = File.from_name(tu, 't.c') 60*e5dd7070Spatrick location = SourceLocation.from_position(tu, file, 1, 5) 61*e5dd7070Spatrick cursor = Cursor.from_location(tu, location) 62*e5dd7070Spatrick 63*e5dd7070Spatrick one = get_cursor(tu, 'one') 64*e5dd7070Spatrick self.assertIsNotNone(one) 65*e5dd7070Spatrick self.assertEqual(one, cursor) 66*e5dd7070Spatrick 67*e5dd7070Spatrick # Ensure locations referring to the same entity are equivalent. 68*e5dd7070Spatrick location2 = SourceLocation.from_position(tu, file, 1, 5) 69*e5dd7070Spatrick self.assertEqual(location, location2) 70*e5dd7070Spatrick location3 = SourceLocation.from_position(tu, file, 1, 4) 71*e5dd7070Spatrick self.assertNotEqual(location2, location3) 72*e5dd7070Spatrick 73*e5dd7070Spatrick offset_location = SourceLocation.from_offset(tu, file, 5) 74*e5dd7070Spatrick cursor = Cursor.from_location(tu, offset_location) 75*e5dd7070Spatrick verified = False 76*e5dd7070Spatrick for n in [n for n in tu.cursor.get_children() if n.spelling == 'one']: 77*e5dd7070Spatrick self.assertEqual(n, cursor) 78*e5dd7070Spatrick verified = True 79*e5dd7070Spatrick 80*e5dd7070Spatrick self.assertTrue(verified) 81*e5dd7070Spatrick 82*e5dd7070Spatrick def test_extent(self): 83*e5dd7070Spatrick tu = get_tu(baseInput) 84*e5dd7070Spatrick one = get_cursor(tu, 'one') 85*e5dd7070Spatrick two = get_cursor(tu, 'two') 86*e5dd7070Spatrick 87*e5dd7070Spatrick self.assert_location(one.extent.start,line=1,column=1,offset=0) 88*e5dd7070Spatrick self.assert_location(one.extent.end,line=1,column=8,offset=7) 89*e5dd7070Spatrick self.assertEqual(baseInput[one.extent.start.offset:one.extent.end.offset], "int one") 90*e5dd7070Spatrick 91*e5dd7070Spatrick self.assert_location(two.extent.start,line=2,column=1,offset=9) 92*e5dd7070Spatrick self.assert_location(two.extent.end,line=2,column=8,offset=16) 93*e5dd7070Spatrick self.assertEqual(baseInput[two.extent.start.offset:two.extent.end.offset], "int two") 94*e5dd7070Spatrick 95*e5dd7070Spatrick file = File.from_name(tu, 't.c') 96*e5dd7070Spatrick location1 = SourceLocation.from_position(tu, file, 1, 1) 97*e5dd7070Spatrick location2 = SourceLocation.from_position(tu, file, 1, 8) 98*e5dd7070Spatrick 99*e5dd7070Spatrick range1 = SourceRange.from_locations(location1, location2) 100*e5dd7070Spatrick range2 = SourceRange.from_locations(location1, location2) 101*e5dd7070Spatrick self.assertEqual(range1, range2) 102*e5dd7070Spatrick 103*e5dd7070Spatrick location3 = SourceLocation.from_position(tu, file, 1, 6) 104*e5dd7070Spatrick range3 = SourceRange.from_locations(location1, location3) 105*e5dd7070Spatrick self.assertNotEqual(range1, range3) 106