xref: /openbsd-src/gnu/llvm/clang/bindings/python/tests/cindex/test_location.py (revision e5dd70708596ae51455a0ffa086a00c5b29f8583)
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