2 from clang
.cindex
import Config
4 if "CLANG_LIBRARY_PATH" in os
.environ
:
5 Config
.set_library_path(os
.environ
["CLANG_LIBRARY_PATH"])
7 from clang
.cindex
import Cursor
8 from clang
.cindex
import File
9 from clang
.cindex
import SourceLocation
10 from clang
.cindex
import SourceRange
11 from clang
.cindex
import TranslationUnit
12 from .util
import get_cursor
13 from .util
import get_tu
18 baseInput
= "int one;\nint two;\n"
21 class TestLocation(unittest
.TestCase
):
22 def assert_location(self
, loc
, line
, column
, offset
):
23 self
.assertEqual(loc
.line
, line
)
24 self
.assertEqual(loc
.column
, column
)
25 self
.assertEqual(loc
.offset
, offset
)
27 def test_location(self
):
28 tu
= get_tu(baseInput
)
29 one
= get_cursor(tu
, "one")
30 two
= get_cursor(tu
, "two")
32 self
.assertIsNotNone(one
)
33 self
.assertIsNotNone(two
)
35 self
.assert_location(one
.location
, line
=1, column
=5, offset
=4)
36 self
.assert_location(two
.location
, line
=2, column
=5, offset
=13)
38 # adding a linebreak at top should keep columns same
39 tu
= get_tu("\n" + baseInput
)
40 one
= get_cursor(tu
, "one")
41 two
= get_cursor(tu
, "two")
43 self
.assertIsNotNone(one
)
44 self
.assertIsNotNone(two
)
46 self
.assert_location(one
.location
, line
=2, column
=5, offset
=5)
47 self
.assert_location(two
.location
, line
=3, column
=5, offset
=14)
49 # adding a space should affect column on first line only
50 tu
= get_tu(" " + baseInput
)
51 one
= get_cursor(tu
, "one")
52 two
= get_cursor(tu
, "two")
54 self
.assert_location(one
.location
, line
=1, column
=6, offset
=5)
55 self
.assert_location(two
.location
, line
=2, column
=5, offset
=14)
57 # define the expected location ourselves and see if it matches
58 # the returned location
59 tu
= get_tu(baseInput
)
61 file = File
.from_name(tu
, "t.c")
62 location
= SourceLocation
.from_position(tu
, file, 1, 5)
63 cursor
= Cursor
.from_location(tu
, location
)
65 one
= get_cursor(tu
, "one")
66 self
.assertIsNotNone(one
)
67 self
.assertEqual(one
, cursor
)
69 # Ensure locations referring to the same entity are equivalent.
70 location2
= SourceLocation
.from_position(tu
, file, 1, 5)
71 self
.assertEqual(location
, location2
)
72 location3
= SourceLocation
.from_position(tu
, file, 1, 4)
73 self
.assertNotEqual(location2
, location3
)
75 offset_location
= SourceLocation
.from_offset(tu
, file, 5)
76 cursor
= Cursor
.from_location(tu
, offset_location
)
78 for n
in [n
for n
in tu
.cursor
.get_children() if n
.spelling
== "one"]:
79 self
.assertEqual(n
, cursor
)
82 self
.assertTrue(verified
)
84 def test_extent(self
):
85 tu
= get_tu(baseInput
)
86 one
= get_cursor(tu
, "one")
87 two
= get_cursor(tu
, "two")
89 self
.assert_location(one
.extent
.start
, line
=1, column
=1, offset
=0)
90 self
.assert_location(one
.extent
.end
, line
=1, column
=8, offset
=7)
92 baseInput
[one
.extent
.start
.offset
: one
.extent
.end
.offset
], "int one"
95 self
.assert_location(two
.extent
.start
, line
=2, column
=1, offset
=9)
96 self
.assert_location(two
.extent
.end
, line
=2, column
=8, offset
=16)
98 baseInput
[two
.extent
.start
.offset
: two
.extent
.end
.offset
], "int two"
101 file = File
.from_name(tu
, "t.c")
102 location1
= SourceLocation
.from_position(tu
, file, 1, 1)
103 location2
= SourceLocation
.from_position(tu
, file, 1, 8)
105 range1
= SourceRange
.from_locations(location1
, location2
)
106 range2
= SourceRange
.from_locations(location1
, location2
)
107 self
.assertEqual(range1
, range2
)
109 location3
= SourceLocation
.from_position(tu
, file, 1, 6)
110 range3
= SourceRange
.from_locations(location1
, location3
)
111 self
.assertNotEqual(range1
, range3
)
113 def test_is_system_location(self
):
114 header
= os
.path
.normpath("./fake/fake.h")
115 tu
= TranslationUnit
.from_source(
117 [f
"-isystem{os.path.dirname(header)}"],
126 (header
, "int two();"),
129 one
= get_cursor(tu
, "one")
130 two
= get_cursor(tu
, "two")
131 self
.assertFalse(one
.location
.is_in_system_header
)
132 self
.assertTrue(two
.location
.is_in_system_header
)