1be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorcimport gc
2be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorcimport os
3651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesimport tempfile
4be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc
5fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorcfrom clang.cindex import CursorKind
6fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorcfrom clang.cindex import Cursor
70f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorcfrom clang.cindex import File
8fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorcfrom clang.cindex import Index
90f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorcfrom clang.cindex import SourceLocation
100f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorcfrom clang.cindex import SourceRange
11fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorcfrom clang.cindex import TranslationUnitSaveError
1211d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosserfrom clang.cindex import TranslationUnitLoadError
13fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorcfrom clang.cindex import TranslationUnit
14fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorcfrom .util import get_cursor
15fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorcfrom .util import get_tu
1630c0f2637c4ba5d8764ff6e1ee6cbc89b89c63dbDaniel Dunbar
1730c0f2637c4ba5d8764ff6e1ee6cbc89b89c63dbDaniel DunbarkInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS')
1830c0f2637c4ba5d8764ff6e1ee6cbc89b89c63dbDaniel Dunbar
1930c0f2637c4ba5d8764ff6e1ee6cbc89b89c63dbDaniel Dunbardef test_spelling():
2030c0f2637c4ba5d8764ff6e1ee6cbc89b89c63dbDaniel Dunbar    path = os.path.join(kInputsDir, 'hello.cpp')
21fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    tu = TranslationUnit.from_source(path)
22a33dca490ad55c6f4bfc38a911f41a66f508a482Daniel Dunbar    assert tu.spelling == path
231b945a7455e17fd792ef3bd3790dc88beea5faadDaniel Dunbar
241b945a7455e17fd792ef3bd3790dc88beea5faadDaniel Dunbardef test_cursor():
251b945a7455e17fd792ef3bd3790dc88beea5faadDaniel Dunbar    path = os.path.join(kInputsDir, 'hello.cpp')
26fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    tu = get_tu(path)
271b945a7455e17fd792ef3bd3790dc88beea5faadDaniel Dunbar    c = tu.cursor
281b945a7455e17fd792ef3bd3790dc88beea5faadDaniel Dunbar    assert isinstance(c, Cursor)
29a6a6499a904441fc9e82ba9dd4155b8bc33f38f9Daniel Dunbar    assert c.kind is CursorKind.TRANSLATION_UNIT
301f8d7f94c7c61c7bb45ebb07e6ce5461bf2a80d5Daniel Dunbar
311f8d7f94c7c61c7bb45ebb07e6ce5461bf2a80d5Daniel Dunbardef test_parse_arguments():
321f8d7f94c7c61c7bb45ebb07e6ce5461bf2a80d5Daniel Dunbar    path = os.path.join(kInputsDir, 'parse_arguments.c')
33fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    tu = TranslationUnit.from_source(path, ['-DDECL_ONE=hello', '-DDECL_TWO=hi'])
341f8d7f94c7c61c7bb45ebb07e6ce5461bf2a80d5Daniel Dunbar    spellings = [c.spelling for c in tu.cursor.get_children()]
351f8d7f94c7c61c7bb45ebb07e6ce5461bf2a80d5Daniel Dunbar    assert spellings[-2] == 'hello'
361f8d7f94c7c61c7bb45ebb07e6ce5461bf2a80d5Daniel Dunbar    assert spellings[-1] == 'hi'
375b534f67946eeb2cb29076288bfee9707f055f82Daniel Dunbar
38265e6b2d17ae348ce73961866979f574c65b56f4Tobias Grosserdef test_reparse_arguments():
39265e6b2d17ae348ce73961866979f574c65b56f4Tobias Grosser    path = os.path.join(kInputsDir, 'parse_arguments.c')
40fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    tu = TranslationUnit.from_source(path, ['-DDECL_ONE=hello', '-DDECL_TWO=hi'])
41265e6b2d17ae348ce73961866979f574c65b56f4Tobias Grosser    tu.reparse()
42265e6b2d17ae348ce73961866979f574c65b56f4Tobias Grosser    spellings = [c.spelling for c in tu.cursor.get_children()]
43265e6b2d17ae348ce73961866979f574c65b56f4Tobias Grosser    assert spellings[-2] == 'hello'
44265e6b2d17ae348ce73961866979f574c65b56f4Tobias Grosser    assert spellings[-1] == 'hi'
45265e6b2d17ae348ce73961866979f574c65b56f4Tobias Grosser
465b534f67946eeb2cb29076288bfee9707f055f82Daniel Dunbardef test_unsaved_files():
47fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    tu = TranslationUnit.from_source('fake.c', ['-I./'], unsaved_files = [
485b534f67946eeb2cb29076288bfee9707f055f82Daniel Dunbar            ('fake.c', """
4988f9c6ca6eb0d4c48687dfed4d94292209c5a919Tobias Grosser#include "fake.h"
505b534f67946eeb2cb29076288bfee9707f055f82Daniel Dunbarint x;
515b534f67946eeb2cb29076288bfee9707f055f82Daniel Dunbarint SOME_DEFINE;
525b534f67946eeb2cb29076288bfee9707f055f82Daniel Dunbar"""),
5388f9c6ca6eb0d4c48687dfed4d94292209c5a919Tobias Grosser            ('./fake.h', """
545b534f67946eeb2cb29076288bfee9707f055f82Daniel Dunbar#define SOME_DEFINE y
555b534f67946eeb2cb29076288bfee9707f055f82Daniel Dunbar""")
565b534f67946eeb2cb29076288bfee9707f055f82Daniel Dunbar            ])
575b534f67946eeb2cb29076288bfee9707f055f82Daniel Dunbar    spellings = [c.spelling for c in tu.cursor.get_children()]
585b534f67946eeb2cb29076288bfee9707f055f82Daniel Dunbar    assert spellings[-2] == 'x'
595b534f67946eeb2cb29076288bfee9707f055f82Daniel Dunbar    assert spellings[-1] == 'y'
60db59a7700e5e42e8b5f6f8e327067a969540ee14Daniel Dunbar
61db59a7700e5e42e8b5f6f8e327067a969540ee14Daniel Dunbardef test_unsaved_files_2():
62db59a7700e5e42e8b5f6f8e327067a969540ee14Daniel Dunbar    import StringIO
63fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    tu = TranslationUnit.from_source('fake.c', unsaved_files = [
64db59a7700e5e42e8b5f6f8e327067a969540ee14Daniel Dunbar            ('fake.c', StringIO.StringIO('int x;'))])
65db59a7700e5e42e8b5f6f8e327067a969540ee14Daniel Dunbar    spellings = [c.spelling for c in tu.cursor.get_children()]
66db59a7700e5e42e8b5f6f8e327067a969540ee14Daniel Dunbar    assert spellings[-1] == 'x'
67ef7f798c0921cde7e665935a5630578cc1065e0fDaniel Dunbar
688be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregordef normpaths_equal(path1, path2):
698be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregor    """ Compares two paths for equality after normalizing them with
708be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregor        os.path.normpath
718be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregor    """
728be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregor    return os.path.normpath(path1) == os.path.normpath(path2)
73ef7f798c0921cde7e665935a5630578cc1065e0fDaniel Dunbar
74ef7f798c0921cde7e665935a5630578cc1065e0fDaniel Dunbardef test_includes():
75ef7f798c0921cde7e665935a5630578cc1065e0fDaniel Dunbar    def eq(expected, actual):
76ef7f798c0921cde7e665935a5630578cc1065e0fDaniel Dunbar        if not actual.is_input_file:
778be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregor            return  normpaths_equal(expected[0], actual.source.name) and \
788be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregor                    normpaths_equal(expected[1], actual.include.name)
79ef7f798c0921cde7e665935a5630578cc1065e0fDaniel Dunbar        else:
808be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregor            return normpaths_equal(expected[1], actual.include.name)
81ef7f798c0921cde7e665935a5630578cc1065e0fDaniel Dunbar
82ef7f798c0921cde7e665935a5630578cc1065e0fDaniel Dunbar    src = os.path.join(kInputsDir, 'include.cpp')
83ef7f798c0921cde7e665935a5630578cc1065e0fDaniel Dunbar    h1 = os.path.join(kInputsDir, "header1.h")
84ef7f798c0921cde7e665935a5630578cc1065e0fDaniel Dunbar    h2 = os.path.join(kInputsDir, "header2.h")
85ef7f798c0921cde7e665935a5630578cc1065e0fDaniel Dunbar    h3 = os.path.join(kInputsDir, "header3.h")
868be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregor    inc = [(src, h1), (h1, h3), (src, h2), (h2, h3)]
87ef7f798c0921cde7e665935a5630578cc1065e0fDaniel Dunbar
88fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    tu = TranslationUnit.from_source(src)
89ef7f798c0921cde7e665935a5630578cc1065e0fDaniel Dunbar    for i in zip(inc, tu.get_includes()):
90ef7f798c0921cde7e665935a5630578cc1065e0fDaniel Dunbar        assert eq(i[0], i[1])
91fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
92fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorcdef save_tu(tu):
93fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    """Convenience API to save a TranslationUnit to a file.
94fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
95fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    Returns the filename it was saved to.
96fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    """
97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    _, path = tempfile.mkstemp()
98fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    tu.save(path)
99fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
100fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    return path
101fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
102fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorcdef test_save():
103fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    """Ensure TranslationUnit.save() works."""
104fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
105fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    tu = get_tu('int foo();')
106fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
107fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    path = save_tu(tu)
108fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    assert os.path.exists(path)
109fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    assert os.path.getsize(path) > 0
110fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    os.unlink(path)
111fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
112fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorcdef test_save_translation_errors():
113fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    """Ensure that saving to an invalid directory raises."""
114fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
115fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    tu = get_tu('int foo();')
116fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
117fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    path = '/does/not/exist/llvm-test.ast'
118fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    assert not os.path.exists(os.path.dirname(path))
119fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
120fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    try:
121fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc        tu.save(path)
122fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc        assert False
123fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    except TranslationUnitSaveError as ex:
124fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc        expected = TranslationUnitSaveError.ERROR_UNKNOWN
125fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc        assert ex.save_error == expected
126fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
127fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorcdef test_load():
128fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    """Ensure TranslationUnits can be constructed from saved files."""
129fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
130fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    tu = get_tu('int foo();')
131fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    assert len(tu.diagnostics) == 0
132fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    path = save_tu(tu)
133fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
134fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    assert os.path.exists(path)
135fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    assert os.path.getsize(path) > 0
136fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
137fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    tu2 = TranslationUnit.from_ast_file(filename=path)
138fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    assert len(tu2.diagnostics) == 0
139fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
140fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    foo = get_cursor(tu2, 'foo')
141fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    assert foo is not None
142fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
143fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    # Just in case there is an open file descriptor somewhere.
144fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    del tu2
145fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
146fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    os.unlink(path)
147fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc
148fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorcdef test_index_parse():
149fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    path = os.path.join(kInputsDir, 'hello.cpp')
150fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    index = Index.create()
151fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    tu = index.parse(path)
152fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    assert isinstance(tu, TranslationUnit)
1530f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc
1540f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorcdef test_get_file():
1550f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    """Ensure tu.get_file() works appropriately."""
1560f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc
1570f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    tu = get_tu('int foo();')
1580f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc
1590f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    f = tu.get_file('t.c')
1600f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert isinstance(f, File)
1610f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert f.name == 't.c'
1620f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc
1630f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    try:
1640f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc        f = tu.get_file('foobar.cpp')
1650f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    except:
1660f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc        pass
1670f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    else:
1680f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc        assert False
1690f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc
1700f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorcdef test_get_source_location():
1710f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    """Ensure tu.get_source_location() works."""
1720f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc
1730f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    tu = get_tu('int foo();')
1740f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc
1750f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    location = tu.get_location('t.c', 2)
1760f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert isinstance(location, SourceLocation)
1770f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert location.offset == 2
1780f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert location.file.name == 't.c'
1790f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc
1800f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    location = tu.get_location('t.c', (1, 3))
1810f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert isinstance(location, SourceLocation)
1820f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert location.line == 1
1830f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert location.column == 3
1840f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert location.file.name == 't.c'
1850f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc
1860f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorcdef test_get_source_range():
1870f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    """Ensure tu.get_source_range() works."""
1880f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc
1890f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    tu = get_tu('int foo();')
1900f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc
1910f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    r = tu.get_extent('t.c', (1,4))
1920f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert isinstance(r, SourceRange)
1930f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert r.start.offset == 1
1940f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert r.end.offset == 4
1950f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert r.start.file.name == 't.c'
1960f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert r.end.file.name == 't.c'
1970f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc
1980f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    r = tu.get_extent('t.c', ((1,2), (1,3)))
1990f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert isinstance(r, SourceRange)
2000f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert r.start.line == 1
2010f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert r.start.column == 2
2020f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert r.end.line == 1
2030f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert r.end.column == 3
2040f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert r.start.file.name == 't.c'
2050f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert r.end.file.name == 't.c'
2060f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc
2070f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    start = tu.get_location('t.c', 0)
2080f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    end = tu.get_location('t.c', 5)
2090f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc
2100f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    r = tu.get_extent('t.c', (start, end))
2110f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert isinstance(r, SourceRange)
2120f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert r.start.offset == 0
2130f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert r.end.offset == 5
2140f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert r.start.file.name == 't.c'
2150f1964a5c1627bcc3fd658cdd1f139e30b0ad612Gregory Szorc    assert r.end.file.name == 't.c'
216be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc
217be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorcdef test_get_tokens_gc():
218be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc    """Ensures get_tokens() works properly with garbage collection."""
219be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc
220be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc    tu = get_tu('int foo();')
221be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc    r = tu.get_extent('t.c', (0, 10))
222be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc    tokens = list(tu.get_tokens(extent=r))
223be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc
224be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc    assert tokens[0].spelling == 'int'
225be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc    gc.collect()
226be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc    assert tokens[0].spelling == 'int'
227be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc
228be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc    del tokens[1]
229be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc    gc.collect()
230be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc    assert tokens[0].spelling == 'int'
231be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc
232be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc    # May trigger segfault if we don't do our job properly.
233be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc    del tokens
234be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc    gc.collect()
235be51e43ba2c57b8032286af4e8713485b6dc78c3Gregory Szorc    gc.collect() # Just in case.
23611d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosser
23711d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosserdef test_fail_from_source():
23811d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosser    path = os.path.join(kInputsDir, 'non-existent.cpp')
23911d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosser    try:
24011d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosser        tu = TranslationUnit.from_source(path)
24111d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosser    except TranslationUnitLoadError:
24211d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosser        tu = None
24311d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosser    assert tu == None
24411d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosser
24511d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosserdef test_fail_from_ast_file():
24611d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosser    path = os.path.join(kInputsDir, 'non-existent.ast')
24711d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosser    try:
24811d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosser        tu = TranslationUnit.from_ast_file(path)
24911d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosser    except TranslationUnitLoadError:
25011d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosser        tu = None
25111d6cd318df1459ed57b26912d5c7a5cf2c2f091Tobias Grosser    assert tu == None
252