1from clang.cindex import Index, File, SourceLocation, SourceRange, Cursor
2
3baseInput="int one;\nint two;\n"
4
5def assert_location(loc, line, column, offset):
6    assert loc.line == line
7    assert loc.column == column
8    assert loc.offset == offset
9
10def test_location():
11    index = Index.create()
12    tu = index.parse('t.c', unsaved_files = [('t.c',baseInput)])
13
14    for n in tu.cursor.get_children():
15        if n.spelling == 'one':
16            assert_location(n.location,line=1,column=5,offset=4)
17        if n.spelling == 'two':
18            assert_location(n.location,line=2,column=5,offset=13)
19
20    # adding a linebreak at top should keep columns same
21    tu = index.parse('t.c', unsaved_files = [('t.c',"\n"+baseInput)])
22
23    for n in tu.cursor.get_children():
24        if n.spelling == 'one':
25            assert_location(n.location,line=2,column=5,offset=5)
26        if n.spelling == 'two':
27            assert_location(n.location,line=3,column=5,offset=14)
28
29    # adding a space should affect column on first line only
30    tu = index.parse('t.c', unsaved_files = [('t.c'," "+baseInput)])
31
32    for n in tu.cursor.get_children():
33        if n.spelling == 'one':
34            assert_location(n.location,line=1,column=6,offset=5)
35        if n.spelling == 'two':
36            assert_location(n.location,line=2,column=5,offset=14)
37
38    # define the expected location ourselves and see if it matches
39    # the returned location
40    tu = index.parse('t.c', unsaved_files = [('t.c',baseInput)])
41
42    file = File.from_name(tu, 't.c')
43    location = SourceLocation.from_position(tu, file, 1, 5)
44    cursor = Cursor.from_location(tu, location)
45
46    for n in tu.cursor.get_children():
47        if n.spelling == 'one':
48            assert n == cursor
49
50    # Ensure locations referring to the same entity are equivalent.
51    location2 = SourceLocation.from_position(tu, file, 1, 5)
52    assert location == location2
53    location3 = SourceLocation.from_position(tu, file, 1, 4)
54    assert location2 != location3
55
56def test_extent():
57    index = Index.create()
58    tu = index.parse('t.c', unsaved_files = [('t.c',baseInput)])
59
60    for n in tu.cursor.get_children():
61        if n.spelling == 'one':
62            assert_location(n.extent.start,line=1,column=1,offset=0)
63            assert_location(n.extent.end,line=1,column=8,offset=7)
64            assert baseInput[n.extent.start.offset:n.extent.end.offset] == "int one"
65        if n.spelling == 'two':
66            assert_location(n.extent.start,line=2,column=1,offset=9)
67            assert_location(n.extent.end,line=2,column=8,offset=16)
68            assert baseInput[n.extent.start.offset:n.extent.end.offset] == "int two"
69
70    file = File.from_name(tu, 't.c')
71    location1 = SourceLocation.from_position(tu, file, 1, 1)
72    location2 = SourceLocation.from_position(tu, file, 1, 8)
73
74    range1 = SourceRange.from_locations(location1, location2)
75    range2 = SourceRange.from_locations(location1, location2)
76    assert range1 == range2
77
78    location3 = SourceLocation.from_position(tu, file, 1, 6)
79    range3 = SourceRange.from_locations(location1, location3)
80    assert range1 != range3
81