diff options
Diffstat (limited to 'bindings/python/tests/cindex/test_cursor.py')
-rw-r--r-- | bindings/python/tests/cindex/test_cursor.py | 958 |
1 files changed, 481 insertions, 477 deletions
diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py index 8ff0695154..41ef62757a 100644 --- a/bindings/python/tests/cindex/test_cursor.py +++ b/bindings/python/tests/cindex/test_cursor.py @@ -1,5 +1,6 @@ import ctypes import gc +import unittest from clang.cindex import AvailabilityKind from clang.cindex import CursorKind @@ -10,6 +11,7 @@ from .util import get_cursor from .util import get_cursors from .util import get_tu + kInput = """\ struct s0 { int a; @@ -30,257 +32,6 @@ void f0(int a0, int a1) { } """ -def test_get_children(): - tu = get_tu(kInput) - - it = tu.cursor.get_children() - tu_nodes = list(it) - - assert len(tu_nodes) == 3 - for cursor in tu_nodes: - assert cursor.translation_unit is not None - - assert tu_nodes[0] != tu_nodes[1] - assert tu_nodes[0].kind == CursorKind.STRUCT_DECL - assert tu_nodes[0].spelling == 's0' - assert tu_nodes[0].is_definition() == True - assert tu_nodes[0].location.file.name == 't.c' - assert tu_nodes[0].location.line == 1 - assert tu_nodes[0].location.column == 8 - assert tu_nodes[0].hash > 0 - assert tu_nodes[0].translation_unit is not None - - s0_nodes = list(tu_nodes[0].get_children()) - assert len(s0_nodes) == 2 - assert s0_nodes[0].kind == CursorKind.FIELD_DECL - assert s0_nodes[0].spelling == 'a' - assert s0_nodes[0].type.kind == TypeKind.INT - assert s0_nodes[1].kind == CursorKind.FIELD_DECL - assert s0_nodes[1].spelling == 'b' - assert s0_nodes[1].type.kind == TypeKind.INT - - assert tu_nodes[1].kind == CursorKind.STRUCT_DECL - assert tu_nodes[1].spelling == 's1' - assert tu_nodes[1].displayname == 's1' - assert tu_nodes[1].is_definition() == False - - assert tu_nodes[2].kind == CursorKind.FUNCTION_DECL - assert tu_nodes[2].spelling == 'f0' - assert tu_nodes[2].displayname == 'f0(int, int)' - assert tu_nodes[2].is_definition() == True - -def test_references(): - """Ensure that references to TranslationUnit are kept.""" - tu = get_tu('int x;') - cursors = list(tu.cursor.get_children()) - assert len(cursors) > 0 - - cursor = cursors[0] - assert isinstance(cursor.translation_unit, TranslationUnit) - - # Delete reference to TU and perform a full GC. - del tu - gc.collect() - assert isinstance(cursor.translation_unit, TranslationUnit) - - # If the TU was destroyed, this should cause a segfault. - parent = cursor.semantic_parent - -def test_canonical(): - source = 'struct X; struct X; struct X { int member; };' - tu = get_tu(source) - - cursors = [] - for cursor in tu.cursor.get_children(): - if cursor.spelling == 'X': - cursors.append(cursor) - - assert len(cursors) == 3 - assert cursors[1].canonical == cursors[2].canonical - -def test_is_const_method(): - """Ensure Cursor.is_const_method works.""" - source = 'class X { void foo() const; void bar(); };' - tu = get_tu(source, lang='cpp') - - cls = get_cursor(tu, 'X') - foo = get_cursor(tu, 'foo') - bar = get_cursor(tu, 'bar') - assert cls is not None - assert foo is not None - assert bar is not None - - assert foo.is_const_method() - assert not bar.is_const_method() - -def test_is_converting_constructor(): - """Ensure Cursor.is_converting_constructor works.""" - source = 'class X { explicit X(int); X(double); X(); };' - tu = get_tu(source, lang='cpp') - - xs = get_cursors(tu, 'X') - - assert len(xs) == 4 - assert xs[0].kind == CursorKind.CLASS_DECL - cs = xs[1:] - assert cs[0].kind == CursorKind.CONSTRUCTOR - assert cs[1].kind == CursorKind.CONSTRUCTOR - assert cs[2].kind == CursorKind.CONSTRUCTOR - - assert not cs[0].is_converting_constructor() - assert cs[1].is_converting_constructor() - assert not cs[2].is_converting_constructor() - - -def test_is_copy_constructor(): - """Ensure Cursor.is_copy_constructor works.""" - source = 'class X { X(); X(const X&); X(X&&); };' - tu = get_tu(source, lang='cpp') - - xs = get_cursors(tu, 'X') - assert xs[0].kind == CursorKind.CLASS_DECL - cs = xs[1:] - assert cs[0].kind == CursorKind.CONSTRUCTOR - assert cs[1].kind == CursorKind.CONSTRUCTOR - assert cs[2].kind == CursorKind.CONSTRUCTOR - - assert not cs[0].is_copy_constructor() - assert cs[1].is_copy_constructor() - assert not cs[2].is_copy_constructor() - -def test_is_default_constructor(): - """Ensure Cursor.is_default_constructor works.""" - source = 'class X { X(); X(int); };' - tu = get_tu(source, lang='cpp') - - xs = get_cursors(tu, 'X') - assert xs[0].kind == CursorKind.CLASS_DECL - cs = xs[1:] - assert cs[0].kind == CursorKind.CONSTRUCTOR - assert cs[1].kind == CursorKind.CONSTRUCTOR - - assert cs[0].is_default_constructor() - assert not cs[1].is_default_constructor() - -def test_is_move_constructor(): - """Ensure Cursor.is_move_constructor works.""" - source = 'class X { X(); X(const X&); X(X&&); };' - tu = get_tu(source, lang='cpp') - - xs = get_cursors(tu, 'X') - assert xs[0].kind == CursorKind.CLASS_DECL - cs = xs[1:] - assert cs[0].kind == CursorKind.CONSTRUCTOR - assert cs[1].kind == CursorKind.CONSTRUCTOR - assert cs[2].kind == CursorKind.CONSTRUCTOR - - assert not cs[0].is_move_constructor() - assert not cs[1].is_move_constructor() - assert cs[2].is_move_constructor() - -def test_is_default_method(): - """Ensure Cursor.is_default_method works.""" - source = 'class X { X() = default; }; class Y { Y(); };' - tu = get_tu(source, lang='cpp') - - xs = get_cursors(tu, 'X') - ys = get_cursors(tu, 'Y') - - assert len(xs) == 2 - assert len(ys) == 2 - - xc = xs[1] - yc = ys[1] - - assert xc.is_default_method() - assert not yc.is_default_method() - -def test_is_mutable_field(): - """Ensure Cursor.is_mutable_field works.""" - source = 'class X { int x_; mutable int y_; };' - tu = get_tu(source, lang='cpp') - - cls = get_cursor(tu, 'X') - x_ = get_cursor(tu, 'x_') - y_ = get_cursor(tu, 'y_') - assert cls is not None - assert x_ is not None - assert y_ is not None - - assert not x_.is_mutable_field() - assert y_.is_mutable_field() - -def test_is_static_method(): - """Ensure Cursor.is_static_method works.""" - - source = 'class X { static void foo(); void bar(); };' - tu = get_tu(source, lang='cpp') - - cls = get_cursor(tu, 'X') - foo = get_cursor(tu, 'foo') - bar = get_cursor(tu, 'bar') - assert cls is not None - assert foo is not None - assert bar is not None - - assert foo.is_static_method() - assert not bar.is_static_method() - -def test_is_pure_virtual_method(): - """Ensure Cursor.is_pure_virtual_method works.""" - source = 'class X { virtual void foo() = 0; virtual void bar(); };' - tu = get_tu(source, lang='cpp') - - cls = get_cursor(tu, 'X') - foo = get_cursor(tu, 'foo') - bar = get_cursor(tu, 'bar') - assert cls is not None - assert foo is not None - assert bar is not None - - assert foo.is_pure_virtual_method() - assert not bar.is_pure_virtual_method() - -def test_is_virtual_method(): - """Ensure Cursor.is_virtual_method works.""" - source = 'class X { virtual void foo(); void bar(); };' - tu = get_tu(source, lang='cpp') - - cls = get_cursor(tu, 'X') - foo = get_cursor(tu, 'foo') - bar = get_cursor(tu, 'bar') - assert cls is not None - assert foo is not None - assert bar is not None - - assert foo.is_virtual_method() - assert not bar.is_virtual_method() - -def test_is_scoped_enum(): - """Ensure Cursor.is_scoped_enum works.""" - source = 'class X {}; enum RegularEnum {}; enum class ScopedEnum {};' - tu = get_tu(source, lang='cpp') - - cls = get_cursor(tu, 'X') - regular_enum = get_cursor(tu, 'RegularEnum') - scoped_enum = get_cursor(tu, 'ScopedEnum') - assert cls is not None - assert regular_enum is not None - assert scoped_enum is not None - - assert not cls.is_scoped_enum() - assert not regular_enum.is_scoped_enum() - assert scoped_enum.is_scoped_enum() - -def test_underlying_type(): - tu = get_tu('typedef int foo;') - typedef = get_cursor(tu, 'foo') - assert typedef is not None - - assert typedef.kind.is_declaration() - underlying = typedef.underlying_typedef_type - assert underlying.kind == TypeKind.INT - kParentTest = """\ class C { void f(); @@ -288,250 +39,503 @@ kParentTest = """\ void C::f() { } """ -def test_semantic_parent(): - tu = get_tu(kParentTest, 'cpp') - curs = get_cursors(tu, 'f') - decl = get_cursor(tu, 'C') - assert(len(curs) == 2) - assert(curs[0].semantic_parent == curs[1].semantic_parent) - assert(curs[0].semantic_parent == decl) - -def test_lexical_parent(): - tu = get_tu(kParentTest, 'cpp') - curs = get_cursors(tu, 'f') - decl = get_cursor(tu, 'C') - assert(len(curs) == 2) - assert(curs[0].lexical_parent != curs[1].lexical_parent) - assert(curs[0].lexical_parent == decl) - assert(curs[1].lexical_parent == tu.cursor) - -def test_enum_type(): - tu = get_tu('enum TEST { FOO=1, BAR=2 };') - enum = get_cursor(tu, 'TEST') - assert enum is not None - - assert enum.kind == CursorKind.ENUM_DECL - enum_type = enum.enum_type - assert enum_type.kind == TypeKind.UINT - -def test_enum_type_cpp(): - tu = get_tu('enum TEST : long long { FOO=1, BAR=2 };', lang="cpp") - enum = get_cursor(tu, 'TEST') - assert enum is not None - - assert enum.kind == CursorKind.ENUM_DECL - assert enum.enum_type.kind == TypeKind.LONGLONG - -def test_objc_type_encoding(): - tu = get_tu('int i;', lang='objc') - i = get_cursor(tu, 'i') - - assert i is not None - assert i.objc_type_encoding == 'i' - -def test_enum_values(): - tu = get_tu('enum TEST { SPAM=1, EGG, HAM = EGG * 20};') - enum = get_cursor(tu, 'TEST') - assert enum is not None - - assert enum.kind == CursorKind.ENUM_DECL - - enum_constants = list(enum.get_children()) - assert len(enum_constants) == 3 - - spam, egg, ham = enum_constants - - assert spam.kind == CursorKind.ENUM_CONSTANT_DECL - assert spam.enum_value == 1 - assert egg.kind == CursorKind.ENUM_CONSTANT_DECL - assert egg.enum_value == 2 - assert ham.kind == CursorKind.ENUM_CONSTANT_DECL - assert ham.enum_value == 40 - -def test_enum_values_cpp(): - tu = get_tu('enum TEST : long long { SPAM = -1, HAM = 0x10000000000};', lang="cpp") - enum = get_cursor(tu, 'TEST') - assert enum is not None - - assert enum.kind == CursorKind.ENUM_DECL - - enum_constants = list(enum.get_children()) - assert len(enum_constants) == 2 - - spam, ham = enum_constants - - assert spam.kind == CursorKind.ENUM_CONSTANT_DECL - assert spam.enum_value == -1 - assert ham.kind == CursorKind.ENUM_CONSTANT_DECL - assert ham.enum_value == 0x10000000000 - -def test_annotation_attribute(): - tu = get_tu('int foo (void) __attribute__ ((annotate("here be annotation attribute")));') - - foo = get_cursor(tu, 'foo') - assert foo is not None - - for c in foo.get_children(): - if c.kind == CursorKind.ANNOTATE_ATTR: - assert c.displayname == "here be annotation attribute" - break - else: - assert False, "Couldn't find annotation" - -def test_annotation_template(): - annotation = '__attribute__ ((annotate("annotation")))' - for source, kind in [ - ('int foo (T value) %s;', CursorKind.FUNCTION_TEMPLATE), - ('class %s foo {};', CursorKind.CLASS_TEMPLATE), - ]: - source = 'template<typename T> ' + (source % annotation) - tu = get_tu(source, lang="cpp") +kTemplateArgTest = """\ + template <int kInt, typename T, bool kBool> + void foo(); + + template<> + void foo<-7, float, true>(); + """ + +class TestCursor(unittest.TestCase): + def test_get_children(self): + tu = get_tu(kInput) + + it = tu.cursor.get_children() + tu_nodes = list(it) + + self.assertEqual(len(tu_nodes), 3) + for cursor in tu_nodes: + self.assertIsNotNone(cursor.translation_unit) + + self.assertNotEqual(tu_nodes[0], tu_nodes[1]) + self.assertEqual(tu_nodes[0].kind, CursorKind.STRUCT_DECL) + self.assertEqual(tu_nodes[0].spelling, 's0') + self.assertEqual(tu_nodes[0].is_definition(), True) + self.assertEqual(tu_nodes[0].location.file.name, 't.c') + self.assertEqual(tu_nodes[0].location.line, 1) + self.assertEqual(tu_nodes[0].location.column, 8) + self.assertGreater(tu_nodes[0].hash, 0) + self.assertIsNotNone(tu_nodes[0].translation_unit) + + s0_nodes = list(tu_nodes[0].get_children()) + self.assertEqual(len(s0_nodes), 2) + self.assertEqual(s0_nodes[0].kind, CursorKind.FIELD_DECL) + self.assertEqual(s0_nodes[0].spelling, 'a') + self.assertEqual(s0_nodes[0].type.kind, TypeKind.INT) + self.assertEqual(s0_nodes[1].kind, CursorKind.FIELD_DECL) + self.assertEqual(s0_nodes[1].spelling, 'b') + self.assertEqual(s0_nodes[1].type.kind, TypeKind.INT) + + self.assertEqual(tu_nodes[1].kind, CursorKind.STRUCT_DECL) + self.assertEqual(tu_nodes[1].spelling, 's1') + self.assertEqual(tu_nodes[1].displayname, 's1') + self.assertEqual(tu_nodes[1].is_definition(), False) + + self.assertEqual(tu_nodes[2].kind, CursorKind.FUNCTION_DECL) + self.assertEqual(tu_nodes[2].spelling, 'f0') + self.assertEqual(tu_nodes[2].displayname, 'f0(int, int)') + self.assertEqual(tu_nodes[2].is_definition(), True) + + def test_references(self): + """Ensure that references to TranslationUnit are kept.""" + tu = get_tu('int x;') + cursors = list(tu.cursor.get_children()) + self.assertGreater(len(cursors), 0) + + cursor = cursors[0] + self.assertIsInstance(cursor.translation_unit, TranslationUnit) + + # Delete reference to TU and perform a full GC. + del tu + gc.collect() + self.assertIsInstance(cursor.translation_unit, TranslationUnit) + + # If the TU was destroyed, this should cause a segfault. + parent = cursor.semantic_parent + + def test_canonical(self): + source = 'struct X; struct X; struct X { int member; };' + tu = get_tu(source) + + cursors = [] + for cursor in tu.cursor.get_children(): + if cursor.spelling == 'X': + cursors.append(cursor) + + self.assertEqual(len(cursors), 3) + self.assertEqual(cursors[1].canonical, cursors[2].canonical) + + def test_is_const_method(self): + """Ensure Cursor.is_const_method works.""" + source = 'class X { void foo() const; void bar(); };' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') foo = get_cursor(tu, 'foo') - assert foo is not None - assert foo.kind == kind + bar = get_cursor(tu, 'bar') + self.assertIsNotNone(cls) + self.assertIsNotNone(foo) + self.assertIsNotNone(bar) + + self.assertTrue(foo.is_const_method()) + self.assertFalse(bar.is_const_method()) + + def test_is_converting_constructor(self): + """Ensure Cursor.is_converting_constructor works.""" + source = 'class X { explicit X(int); X(double); X(); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + + self.assertEqual(len(xs), 4) + self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL) + cs = xs[1:] + self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR) + self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR) + self.assertEqual(cs[2].kind, CursorKind.CONSTRUCTOR) + + self.assertFalse(cs[0].is_converting_constructor()) + self.assertTrue(cs[1].is_converting_constructor()) + self.assertFalse(cs[2].is_converting_constructor()) + + + def test_is_copy_constructor(self): + """Ensure Cursor.is_copy_constructor works.""" + source = 'class X { X(); X(const X&); X(X&&); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL) + cs = xs[1:] + self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR) + self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR) + self.assertEqual(cs[2].kind, CursorKind.CONSTRUCTOR) + + self.assertFalse(cs[0].is_copy_constructor()) + self.assertTrue(cs[1].is_copy_constructor()) + self.assertFalse(cs[2].is_copy_constructor()) + + def test_is_default_constructor(self): + """Ensure Cursor.is_default_constructor works.""" + source = 'class X { X(); X(int); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL) + cs = xs[1:] + self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR) + self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR) + + self.assertTrue(cs[0].is_default_constructor()) + self.assertFalse(cs[1].is_default_constructor()) + + def test_is_move_constructor(self): + """Ensure Cursor.is_move_constructor works.""" + source = 'class X { X(); X(const X&); X(X&&); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL) + cs = xs[1:] + self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR) + self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR) + self.assertEqual(cs[2].kind, CursorKind.CONSTRUCTOR) + + self.assertFalse(cs[0].is_move_constructor()) + self.assertFalse(cs[1].is_move_constructor()) + self.assertTrue(cs[2].is_move_constructor()) + + def test_is_default_method(self): + """Ensure Cursor.is_default_method works.""" + source = 'class X { X() = default; }; class Y { Y(); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + ys = get_cursors(tu, 'Y') + + self.assertEqual(len(xs), 2) + self.assertEqual(len(ys), 2) + + xc = xs[1] + yc = ys[1] + + self.assertTrue(xc.is_default_method()) + self.assertFalse(yc.is_default_method()) + + def test_is_mutable_field(self): + """Ensure Cursor.is_mutable_field works.""" + source = 'class X { int x_; mutable int y_; };' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + x_ = get_cursor(tu, 'x_') + y_ = get_cursor(tu, 'y_') + self.assertIsNotNone(cls) + self.assertIsNotNone(x_) + self.assertIsNotNone(y_) + + self.assertFalse(x_.is_mutable_field()) + self.assertTrue(y_.is_mutable_field()) + + def test_is_static_method(self): + """Ensure Cursor.is_static_method works.""" + + source = 'class X { static void foo(); void bar(); };' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + foo = get_cursor(tu, 'foo') + bar = get_cursor(tu, 'bar') + self.assertIsNotNone(cls) + self.assertIsNotNone(foo) + self.assertIsNotNone(bar) + + self.assertTrue(foo.is_static_method()) + self.assertFalse(bar.is_static_method()) + + def test_is_pure_virtual_method(self): + """Ensure Cursor.is_pure_virtual_method works.""" + source = 'class X { virtual void foo() = 0; virtual void bar(); };' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + foo = get_cursor(tu, 'foo') + bar = get_cursor(tu, 'bar') + self.assertIsNotNone(cls) + self.assertIsNotNone(foo) + self.assertIsNotNone(bar) + + self.assertTrue(foo.is_pure_virtual_method()) + self.assertFalse(bar.is_pure_virtual_method()) + + def test_is_virtual_method(self): + """Ensure Cursor.is_virtual_method works.""" + source = 'class X { virtual void foo(); void bar(); };' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + foo = get_cursor(tu, 'foo') + bar = get_cursor(tu, 'bar') + self.assertIsNotNone(cls) + self.assertIsNotNone(foo) + self.assertIsNotNone(bar) + + self.assertTrue(foo.is_virtual_method()) + self.assertFalse(bar.is_virtual_method()) + + def test_is_scoped_enum(self): + """Ensure Cursor.is_scoped_enum works.""" + source = 'class X {}; enum RegularEnum {}; enum class ScopedEnum {};' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + regular_enum = get_cursor(tu, 'RegularEnum') + scoped_enum = get_cursor(tu, 'ScopedEnum') + self.assertIsNotNone(cls) + self.assertIsNotNone(regular_enum) + self.assertIsNotNone(scoped_enum) + + self.assertFalse(cls.is_scoped_enum()) + self.assertFalse(regular_enum.is_scoped_enum()) + self.assertTrue(scoped_enum.is_scoped_enum()) + + def test_underlying_type(self): + tu = get_tu('typedef int foo;') + typedef = get_cursor(tu, 'foo') + self.assertIsNotNone(typedef) + + self.assertTrue(typedef.kind.is_declaration()) + underlying = typedef.underlying_typedef_type + self.assertEqual(underlying.kind, TypeKind.INT) + + def test_semantic_parent(self): + tu = get_tu(kParentTest, 'cpp') + curs = get_cursors(tu, 'f') + decl = get_cursor(tu, 'C') + self.assertEqual(len(curs), 2) + self.assertEqual(curs[0].semantic_parent, curs[1].semantic_parent) + self.assertEqual(curs[0].semantic_parent, decl) + + def test_lexical_parent(self): + tu = get_tu(kParentTest, 'cpp') + curs = get_cursors(tu, 'f') + decl = get_cursor(tu, 'C') + self.assertEqual(len(curs), 2) + self.assertNotEqual(curs[0].lexical_parent, curs[1].lexical_parent) + self.assertEqual(curs[0].lexical_parent, decl) + self.assertEqual(curs[1].lexical_parent, tu.cursor) + + def test_enum_type(self): + tu = get_tu('enum TEST { FOO=1, BAR=2 };') + enum = get_cursor(tu, 'TEST') + self.assertIsNotNone(enum) + + self.assertEqual(enum.kind, CursorKind.ENUM_DECL) + enum_type = enum.enum_type + self.assertEqual(enum_type.kind, TypeKind.UINT) + + def test_enum_type_cpp(self): + tu = get_tu('enum TEST : long long { FOO=1, BAR=2 };', lang="cpp") + enum = get_cursor(tu, 'TEST') + self.assertIsNotNone(enum) + + self.assertEqual(enum.kind, CursorKind.ENUM_DECL) + self.assertEqual(enum.enum_type.kind, TypeKind.LONGLONG) + + def test_objc_type_encoding(self): + tu = get_tu('int i;', lang='objc') + i = get_cursor(tu, 'i') + + self.assertIsNotNone(i) + self.assertEqual(i.objc_type_encoding, 'i') + + def test_enum_values(self): + tu = get_tu('enum TEST { SPAM=1, EGG, HAM = EGG * 20};') + enum = get_cursor(tu, 'TEST') + self.assertIsNotNone(enum) + + self.assertEqual(enum.kind, CursorKind.ENUM_DECL) + + enum_constants = list(enum.get_children()) + self.assertEqual(len(enum_constants), 3) + + spam, egg, ham = enum_constants + + self.assertEqual(spam.kind, CursorKind.ENUM_CONSTANT_DECL) + self.assertEqual(spam.enum_value, 1) + self.assertEqual(egg.kind, CursorKind.ENUM_CONSTANT_DECL) + self.assertEqual(egg.enum_value, 2) + self.assertEqual(ham.kind, CursorKind.ENUM_CONSTANT_DECL) + self.assertEqual(ham.enum_value, 40) + + def test_enum_values_cpp(self): + tu = get_tu('enum TEST : long long { SPAM = -1, HAM = 0x10000000000};', lang="cpp") + enum = get_cursor(tu, 'TEST') + self.assertIsNotNone(enum) + + self.assertEqual(enum.kind, CursorKind.ENUM_DECL) + + enum_constants = list(enum.get_children()) + self.assertEqual(len(enum_constants), 2) + + spam, ham = enum_constants + + self.assertEqual(spam.kind, CursorKind.ENUM_CONSTANT_DECL) + self.assertEqual(spam.enum_value, -1) + self.assertEqual(ham.kind, CursorKind.ENUM_CONSTANT_DECL) + self.assertEqual(ham.enum_value, 0x10000000000) + + def test_annotation_attribute(self): + tu = get_tu('int foo (void) __attribute__ ((annotate("here be annotation attribute")));') + + foo = get_cursor(tu, 'foo') + self.assertIsNotNone(foo) for c in foo.get_children(): if c.kind == CursorKind.ANNOTATE_ATTR: - assert c.displayname == "annotation" + self.assertEqual(c.displayname, "here be annotation attribute") break else: - assert False, "Couldn't find annotation for {}".format(kind) - -def test_result_type(): - tu = get_tu('int foo();') - foo = get_cursor(tu, 'foo') - - assert foo is not None - t = foo.result_type - assert t.kind == TypeKind.INT - -def test_availability(): - tu = get_tu('class A { A(A const&) = delete; };', lang='cpp') - - # AvailabilityKind.AVAILABLE - cursor = get_cursor(tu, 'A') - assert cursor.kind == CursorKind.CLASS_DECL - assert cursor.availability == AvailabilityKind.AVAILABLE - - # AvailabilityKind.NOT_AVAILABLE - cursors = get_cursors(tu, 'A') - for c in cursors: - if c.kind == CursorKind.CONSTRUCTOR: - assert c.availability == AvailabilityKind.NOT_AVAILABLE - break - else: - assert False, "Could not find cursor for deleted constructor" - - # AvailabilityKind.DEPRECATED - tu = get_tu('void test() __attribute__((deprecated));', lang='cpp') - cursor = get_cursor(tu, 'test') - assert cursor.availability == AvailabilityKind.DEPRECATED - - # AvailabilityKind.NOT_ACCESSIBLE is only used in the code completion results - -def test_get_tokens(): - """Ensure we can map cursors back to tokens.""" - tu = get_tu('int foo(int i);') - foo = get_cursor(tu, 'foo') - - tokens = list(foo.get_tokens()) - assert len(tokens) == 6 - assert tokens[0].spelling == 'int' - assert tokens[1].spelling == 'foo' - -def test_get_token_cursor(): - """Ensure we can map tokens to cursors.""" - tu = get_tu('class A {}; int foo(A var = A());', lang='cpp') - foo = get_cursor(tu, 'foo') - - for cursor in foo.walk_preorder(): - if cursor.kind.is_expression() and not cursor.kind.is_statement(): - break - else: - assert False, "Could not find default value expression" - - tokens = list(cursor.get_tokens()) - assert len(tokens) == 4, [t.spelling for t in tokens] - assert tokens[0].spelling == '=' - assert tokens[1].spelling == 'A' - assert tokens[2].spelling == '(' - assert tokens[3].spelling == ')' - t_cursor = tokens[1].cursor - assert t_cursor.kind == CursorKind.TYPE_REF - r_cursor = t_cursor.referenced # should not raise an exception - assert r_cursor.kind == CursorKind.CLASS_DECL - -def test_get_arguments(): - tu = get_tu('void foo(int i, int j);') - foo = get_cursor(tu, 'foo') - arguments = list(foo.get_arguments()) - - assert len(arguments) == 2 - assert arguments[0].spelling == "i" - assert arguments[1].spelling == "j" + self.fail("Couldn't find annotation") + + def test_annotation_template(self): + annotation = '__attribute__ ((annotate("annotation")))' + for source, kind in [ + ('int foo (T value) %s;', CursorKind.FUNCTION_TEMPLATE), + ('class %s foo {};', CursorKind.CLASS_TEMPLATE), + ]: + source = 'template<typename T> ' + (source % annotation) + tu = get_tu(source, lang="cpp") + + foo = get_cursor(tu, 'foo') + self.assertIsNotNone(foo) + self.assertEqual(foo.kind, kind) + + for c in foo.get_children(): + if c.kind == CursorKind.ANNOTATE_ATTR: + self.assertEqual(c.displayname, "annotation") + break + else: + self.fail("Couldn't find annotation for {}".format(kind)) + + def test_result_type(self): + tu = get_tu('int foo();') + foo = get_cursor(tu, 'foo') -kTemplateArgTest = """\ - template <int kInt, typename T, bool kBool> - void foo(); + self.assertIsNotNone(foo) + t = foo.result_type + self.assertEqual(t.kind, TypeKind.INT) - template<> - void foo<-7, float, true>(); - """ + def test_availability(self): + tu = get_tu('class A { A(A const&) = delete; };', lang='cpp') -def test_get_num_template_arguments(): - tu = get_tu(kTemplateArgTest, lang='cpp') - foos = get_cursors(tu, 'foo') + # AvailabilityKind.AVAILABLE + cursor = get_cursor(tu, 'A') + self.assertEqual(cursor.kind, CursorKind.CLASS_DECL) + self.assertEqual(cursor.availability, AvailabilityKind.AVAILABLE) + + # AvailabilityKind.NOT_AVAILABLE + cursors = get_cursors(tu, 'A') + for c in cursors: + if c.kind == CursorKind.CONSTRUCTOR: + self.assertEqual(c.availability, AvailabilityKind.NOT_AVAILABLE) + break + else: + self.fail("Could not find cursor for deleted constructor") - assert foos[1].get_num_template_arguments() == 3 + # AvailabilityKind.DEPRECATED + tu = get_tu('void test() __attribute__((deprecated));', lang='cpp') + cursor = get_cursor(tu, 'test') + self.assertEqual(cursor.availability, AvailabilityKind.DEPRECATED) -def test_get_template_argument_kind(): - tu = get_tu(kTemplateArgTest, lang='cpp') - foos = get_cursors(tu, 'foo') + # AvailabilityKind.NOT_ACCESSIBLE is only used in the code completion results - assert foos[1].get_template_argument_kind(0) == TemplateArgumentKind.INTEGRAL - assert foos[1].get_template_argument_kind(1) == TemplateArgumentKind.TYPE - assert foos[1].get_template_argument_kind(2) == TemplateArgumentKind.INTEGRAL + def test_get_tokens(self): + """Ensure we can map cursors back to tokens.""" + tu = get_tu('int foo(int i);') + foo = get_cursor(tu, 'foo') -def test_get_template_argument_type(): - tu = get_tu(kTemplateArgTest, lang='cpp') - foos = get_cursors(tu, 'foo') + tokens = list(foo.get_tokens()) + self.assertEqual(len(tokens), 6) + self.assertEqual(tokens[0].spelling, 'int') + self.assertEqual(tokens[1].spelling, 'foo') - assert foos[1].get_template_argument_type(1).kind == TypeKind.FLOAT + def test_get_token_cursor(self): + """Ensure we can map tokens to cursors.""" + tu = get_tu('class A {}; int foo(A var = A());', lang='cpp') + foo = get_cursor(tu, 'foo') -def test_get_template_argument_value(): - tu = get_tu(kTemplateArgTest, lang='cpp') - foos = get_cursors(tu, 'foo') + for cursor in foo.walk_preorder(): + if cursor.kind.is_expression() and not cursor.kind.is_statement(): + break + else: + self.fail("Could not find default value expression") + + tokens = list(cursor.get_tokens()) + self.assertEqual(len(tokens), 4, [t.spelling for t in tokens]) + self.assertEqual(tokens[0].spelling, '=') + self.assertEqual(tokens[1].spelling, 'A') + self.assertEqual(tokens[2].spelling, '(') + self.assertEqual(tokens[3].spelling, ')') + t_cursor = tokens[1].cursor + self.assertEqual(t_cursor.kind, CursorKind.TYPE_REF) + r_cursor = t_cursor.referenced # should not raise an exception + self.assertEqual(r_cursor.kind, CursorKind.CLASS_DECL) + + def test_get_arguments(self): + tu = get_tu('void foo(int i, int j);') + foo = get_cursor(tu, 'foo') + arguments = list(foo.get_arguments()) - assert foos[1].get_template_argument_value(0) == -7 - assert foos[1].get_template_argument_value(2) == True + self.assertEqual(len(arguments), 2) + self.assertEqual(arguments[0].spelling, "i") + self.assertEqual(arguments[1].spelling, "j") -def test_get_template_argument_unsigned_value(): - tu = get_tu(kTemplateArgTest, lang='cpp') - foos = get_cursors(tu, 'foo') + def test_get_num_template_arguments(self): + tu = get_tu(kTemplateArgTest, lang='cpp') + foos = get_cursors(tu, 'foo') - assert foos[1].get_template_argument_unsigned_value(0) == 2 ** 32 - 7 - assert foos[1].get_template_argument_unsigned_value(2) == True + self.assertEqual(foos[1].get_num_template_arguments(), 3) -def test_referenced(): - tu = get_tu('void foo(); void bar() { foo(); }') - foo = get_cursor(tu, 'foo') - bar = get_cursor(tu, 'bar') - for c in bar.get_children(): - if c.kind == CursorKind.CALL_EXPR: - assert c.referenced.spelling == foo.spelling - break + def test_get_template_argument_kind(self): + tu = get_tu(kTemplateArgTest, lang='cpp') + foos = get_cursors(tu, 'foo') -def test_mangled_name(): - kInputForMangling = """\ - int foo(int, int); - """ - tu = get_tu(kInputForMangling, lang='cpp') - foo = get_cursor(tu, 'foo') - - # Since libclang does not link in targets, we cannot pass a triple to it - # and force the target. To enable this test to pass on all platforms, accept - # all valid manglings. - # [c-index-test handles this by running the source through clang, emitting - # an AST file and running libclang on that AST file] - assert foo.mangled_name in ('_Z3fooii', '__Z3fooii', '?foo@@YAHHH') + self.assertEqual(foos[1].get_template_argument_kind(0), TemplateArgumentKind.INTEGRAL) + self.assertEqual(foos[1].get_template_argument_kind(1), TemplateArgumentKind.TYPE) + self.assertEqual(foos[1].get_template_argument_kind(2), TemplateArgumentKind.INTEGRAL) + + def test_get_template_argument_type(self): + tu = get_tu(kTemplateArgTest, lang='cpp') + foos = get_cursors(tu, 'foo') + + self.assertEqual(foos[1].get_template_argument_type(1).kind, TypeKind.FLOAT) + + def test_get_template_argument_value(self): + tu = get_tu(kTemplateArgTest, lang='cpp') + foos = get_cursors(tu, 'foo') + + self.assertEqual(foos[1].get_template_argument_value(0), -7) + self.assertEqual(foos[1].get_template_argument_value(2), True) + + def test_get_template_argument_unsigned_value(self): + tu = get_tu(kTemplateArgTest, lang='cpp') + foos = get_cursors(tu, 'foo') + + self.assertEqual(foos[1].get_template_argument_unsigned_value(0), 2 ** 32 - 7) + self.assertEqual(foos[1].get_template_argument_unsigned_value(2), True) + + def test_referenced(self): + tu = get_tu('void foo(); void bar() { foo(); }') + foo = get_cursor(tu, 'foo') + bar = get_cursor(tu, 'bar') + for c in bar.get_children(): + if c.kind == CursorKind.CALL_EXPR: + self.assertEqual(c.referenced.spelling, foo.spelling) + break + + def test_mangled_name(self): + kInputForMangling = """\ + int foo(int, int); + """ + tu = get_tu(kInputForMangling, lang='cpp') + foo = get_cursor(tu, 'foo') + + # Since libclang does not link in targets, we cannot pass a triple to it + # and force the target. To enable this test to pass on all platforms, accept + # all valid manglings. + # [c-index-test handles this by running the source through clang, emitting + # an AST file and running libclang on that AST file] + self.assertIn(foo.mangled_name, ('_Z3fooii', '__Z3fooii', '?foo@@YAHHH')) |