1from clang.cindex import CursorKind 2from clang.cindex import TypeKind 3from .util import get_cursor 4from .util import get_cursors 5from .util import get_tu 6 7kInput = """\ 8// FIXME: Find nicer way to drop builtins and other cruft. 9int start_decl; 10 11struct s0 { 12 int a; 13 int b; 14}; 15 16struct s1; 17 18void f0(int a0, int a1) { 19 int l0, l1; 20 21 if (a0) 22 return; 23 24 for (;;) { 25 break; 26 } 27} 28""" 29 30def test_get_children(): 31 tu = get_tu(kInput) 32 33 # Skip until past start_decl. 34 it = tu.cursor.get_children() 35 while it.next().spelling != 'start_decl': 36 pass 37 38 tu_nodes = list(it) 39 40 assert len(tu_nodes) == 3 41 42 assert tu_nodes[0] != tu_nodes[1] 43 assert tu_nodes[0].kind == CursorKind.STRUCT_DECL 44 assert tu_nodes[0].spelling == 's0' 45 assert tu_nodes[0].is_definition() == True 46 assert tu_nodes[0].location.file.name == 't.c' 47 assert tu_nodes[0].location.line == 4 48 assert tu_nodes[0].location.column == 8 49 assert tu_nodes[0].hash > 0 50 51 s0_nodes = list(tu_nodes[0].get_children()) 52 assert len(s0_nodes) == 2 53 assert s0_nodes[0].kind == CursorKind.FIELD_DECL 54 assert s0_nodes[0].spelling == 'a' 55 assert s0_nodes[0].type.kind == TypeKind.INT 56 assert s0_nodes[1].kind == CursorKind.FIELD_DECL 57 assert s0_nodes[1].spelling == 'b' 58 assert s0_nodes[1].type.kind == TypeKind.INT 59 60 assert tu_nodes[1].kind == CursorKind.STRUCT_DECL 61 assert tu_nodes[1].spelling == 's1' 62 assert tu_nodes[1].displayname == 's1' 63 assert tu_nodes[1].is_definition() == False 64 65 assert tu_nodes[2].kind == CursorKind.FUNCTION_DECL 66 assert tu_nodes[2].spelling == 'f0' 67 assert tu_nodes[2].displayname == 'f0(int, int)' 68 assert tu_nodes[2].is_definition() == True 69 70def test_canonical(): 71 source = 'struct X; struct X; struct X { int member; };' 72 tu = get_tu(source) 73 74 cursors = [] 75 for cursor in tu.cursor.get_children(): 76 if cursor.spelling == 'X': 77 cursors.append(cursor) 78 79 assert len(cursors) == 3 80 assert cursors[1].canonical == cursors[2].canonical 81 82def test_underlying_type(): 83 tu = get_tu('typedef int foo;') 84 typedef = get_cursor(tu, 'foo') 85 assert typedef is not None 86 87 assert typedef.kind.is_declaration() 88 underlying = typedef.underlying_typedef_type 89 assert underlying.kind == TypeKind.INT 90 91kParentTest = """\ 92 class C { 93 void f(); 94 } 95 96 void C::f() { } 97 """ 98def test_semantic_parent(): 99 tu = get_tu(kParentTest, 'cpp') 100 curs = get_cursors(tu, 'f') 101 decl = get_cursor(tu, 'C') 102 assert(len(curs) == 2) 103 assert(curs[0].semantic_parent == curs[1].semantic_parent) 104 assert(curs[0].semantic_parent == decl) 105 106def test_lexical_parent(): 107 tu = get_tu(kParentTest, 'cpp') 108 curs = get_cursors(tu, 'f') 109 decl = get_cursor(tu, 'C') 110 assert(len(curs) == 2) 111 assert(curs[0].lexical_parent != curs[1].lexical_parent) 112 assert(curs[0].lexical_parent == decl) 113 assert(curs[1].lexical_parent == tu.cursor) 114 115def test_enum_type(): 116 tu = get_tu('enum TEST { FOO=1, BAR=2 };') 117 enum = get_cursor(tu, 'TEST') 118 assert enum is not None 119 120 assert enum.kind == CursorKind.ENUM_DECL 121 enum_type = enum.enum_type 122 assert enum_type.kind == TypeKind.UINT 123 124def test_enum_type_cpp(): 125 tu = get_tu('enum TEST : long long { FOO=1, BAR=2 };', lang="cpp") 126 enum = get_cursor(tu, 'TEST') 127 assert enum is not None 128 129 assert enum.kind == CursorKind.ENUM_DECL 130 assert enum.enum_type.kind == TypeKind.LONGLONG 131 132def test_objc_type_encoding(): 133 tu = get_tu('int i;', lang='objc') 134 i = get_cursor(tu, 'i') 135 136 assert i is not None 137 assert i.objc_type_encoding == 'i' 138 139def test_enum_values(): 140 tu = get_tu('enum TEST { SPAM=1, EGG, HAM = EGG * 20};') 141 enum = get_cursor(tu, 'TEST') 142 assert enum is not None 143 144 assert enum.kind == CursorKind.ENUM_DECL 145 146 enum_constants = list(enum.get_children()) 147 assert len(enum_constants) == 3 148 149 spam, egg, ham = enum_constants 150 151 assert spam.kind == CursorKind.ENUM_CONSTANT_DECL 152 assert spam.enum_value == 1 153 assert egg.kind == CursorKind.ENUM_CONSTANT_DECL 154 assert egg.enum_value == 2 155 assert ham.kind == CursorKind.ENUM_CONSTANT_DECL 156 assert ham.enum_value == 40 157 158def test_enum_values_cpp(): 159 tu = get_tu('enum TEST : long long { SPAM = -1, HAM = 0x10000000000};', lang="cpp") 160 enum = get_cursor(tu, 'TEST') 161 assert enum is not None 162 163 assert enum.kind == CursorKind.ENUM_DECL 164 165 enum_constants = list(enum.get_children()) 166 assert len(enum_constants) == 2 167 168 spam, ham = enum_constants 169 170 assert spam.kind == CursorKind.ENUM_CONSTANT_DECL 171 assert spam.enum_value == -1 172 assert ham.kind == CursorKind.ENUM_CONSTANT_DECL 173 assert ham.enum_value == 0x10000000000 174 175def test_annotation_attribute(): 176 tu = get_tu('int foo (void) __attribute__ ((annotate("here be annotation attribute")));') 177 178 foo = get_cursor(tu, 'foo') 179 assert foo is not None 180 181 for c in foo.get_children(): 182 if c.kind == CursorKind.ANNOTATE_ATTR: 183 assert c.displayname == "here be annotation attribute" 184 break 185 else: 186 assert False, "Couldn't find annotation" 187 188def test_result_type(): 189 tu = get_tu('int foo();') 190 foo = get_cursor(tu, 'foo') 191 192 assert foo is not None 193 t = foo.result_type 194 assert t.kind == TypeKind.INT 195