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