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