type_spec.rb (10009B)
1 # -*- coding: utf-8 -*- 2 # Copyright, 2013, by Carlos MartÃn Nieto <cmn@dwim.me> 3 # Copyright, 2014, by Masahiro Sano. 4 # 5 # Permission is hereby granted, free of charge, to any person obtaining a copy 6 # of this software and associated documentation files (the "Software"), to deal 7 # in the Software without restriction, including without limitation the rights 8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 # copies of the Software, and to permit persons to whom the Software is 10 # furnished to do so, subject to the following conditions: 11 # 12 # The above copyright notice and this permission notice shall be included in 13 # all copies or substantial portions of the Software. 14 # 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 # THE SOFTWARE. 22 23 describe Type do 24 let(:cursor) { Index.new.parse_translation_unit(fixture_path("a.c")).cursor } 25 let(:cursor_cxx) { Index.new.parse_translation_unit(fixture_path("test.cxx")).cursor } 26 let(:cursor_list) { Index.new.parse_translation_unit(fixture_path("list.c")).cursor } 27 let(:type) { find_first(cursor, :cursor_function).type } 28 29 it "can tell us about the main function" do 30 expect(type.variadic?).to equal(false) 31 32 expect(type.num_arg_types).to equal(2) 33 expect(type.arg_type(0).spelling).to eq("int") 34 expect(type.arg_type(1).spelling).to eq("const char *") 35 expect(type.result_type.spelling).to eq("int") 36 end 37 38 describe '#kind_spelling' do 39 let(:kind_spelling_type) { find_matching(cursor_cxx) { |child, parent| 40 child.kind == :cursor_typedef_decl and child.spelling == 'const_int_ptr'}.type } 41 42 it 'returns type kind name with string' do 43 expect(kind_spelling_type.kind_spelling).to eq 'Typedef' 44 end 45 end 46 47 describe '#canonical' do 48 let(:canonical_type) { find_matching(cursor_cxx) { |child, parent| 49 child.kind == :cursor_typedef_decl and child.spelling == 'const_int_ptr' 50 }.type.canonical } 51 52 it 'extracts typedef' do 53 expect(canonical_type).to be_kind_of(Type) 54 expect(canonical_type.kind).to be(:type_pointer) 55 expect(canonical_type.spelling).to eq('const int *') 56 end 57 end 58 59 describe '#pointee' do 60 let(:pointee_type) { find_matching(cursor_cxx) { |child, parent| 61 child.kind == :cursor_typedef_decl and child.spelling == 'const_int_ptr' 62 }.type.canonical.pointee } 63 64 it 'gets pointee type of pointer, C++ reference' do 65 expect(pointee_type).to be_kind_of(Type) 66 expect(pointee_type.kind).to be(:type_int) 67 expect(pointee_type.spelling).to eq('const int') 68 end 69 end 70 71 describe '#const_qualified?' do 72 let(:pointer_type) { find_matching(cursor_cxx) { |child, parent| 73 child.kind == :cursor_typedef_decl and child.spelling == 'const_int_ptr' 74 }.type.canonical } 75 76 let(:pointee_type) { find_matching(cursor_cxx) { |child, parent| 77 child.kind == :cursor_typedef_decl and child.spelling == 'const_int_ptr' 78 }.type.canonical.pointee } 79 80 it 'checks type is const qualified' do 81 expect(pointee_type.const_qualified?).to equal true 82 end 83 84 it 'cannot check whether pointee type is const qualified' do 85 expect(pointer_type.const_qualified?).to equal false 86 end 87 end 88 89 describe '#volatile_qualified?' do 90 let(:pointer_type) { find_matching(cursor) { |child, parent| 91 child.kind == :cursor_variable and child.spelling == 'volatile_int_ptr' 92 }.type } 93 94 it 'checks type is volatile qualified' do 95 expect(pointer_type.volatile_qualified?).to be true 96 end 97 end 98 99 describe '#restrict_qualified?' do 100 let(:pointer_type) { find_matching(cursor) { |child, parent| 101 child.kind == :cursor_variable and child.spelling == 'restrict_int_ptr' 102 }.type } 103 104 it 'checks type is restrict qualified' do 105 expect(pointer_type.restrict_qualified?).to be true 106 end 107 end 108 109 describe '#element_type' do 110 let(:array_type) { find_matching(cursor_cxx) { |child, parent| 111 child.kind == :cursor_variable and child.spelling == 'int_array' 112 }.type } 113 114 it 'returns the element type of the array type' do 115 expect(array_type.element_type).to be_kind_of(Type) 116 expect(array_type.element_type.kind).to eq(:type_int) 117 end 118 end 119 120 describe '#num_elements' do 121 let(:array_type) { find_matching(cursor_cxx) { |child, parent| 122 child.kind == :cursor_variable and child.spelling == 'int_array' 123 }.type } 124 125 it 'returns the number of elements of the array' do 126 expect(array_type.num_elements).to eq(8) 127 end 128 end 129 130 describe '#array_element_type' do 131 let(:array_type) { find_matching(cursor_cxx) { |child, parent| 132 child.kind == :cursor_variable and child.spelling == 'int_array' 133 }.type } 134 135 it 'returns the array element type of the array type' do 136 expect(array_type.array_element_type).to be_kind_of(Type) 137 expect(array_type.array_element_type.kind).to eq(:type_int) 138 end 139 end 140 141 describe '#array_size' do 142 let(:array_type) { find_matching(cursor_cxx) { |child, parent| 143 child.kind == :cursor_variable and child.spelling == 'int_array' 144 }.type } 145 146 it 'returns the number of elements of the array' do 147 expect(array_type.array_size).to eq(8) 148 end 149 end 150 151 describe '#alignof' do 152 let(:array_type) { find_matching(cursor_cxx) { |child, parent| 153 child.kind == :cursor_variable and child.spelling == 'int_array' 154 }.type } 155 156 it 'returns the alignment of the type in bytes' do 157 expect(array_type.alignof).to be_kind_of(Integer) 158 expect(array_type.alignof).to be > 0 159 end 160 end 161 162 describe '#sizeof' do 163 let(:array_type) { find_matching(cursor_cxx) { |child, parent| 164 child.kind == :cursor_variable and child.spelling == 'int_array' 165 }.type } 166 167 it 'returns the size of the type in bytes' do 168 expect(array_type.sizeof).to be_kind_of(Integer) 169 expect(array_type.sizeof).to be(32) 170 end 171 end 172 173 describe '#offsetof' do 174 let(:struct) { find_matching(cursor_list) { |child, parent| 175 child.kind == :cursor_struct and child.spelling == 'List' 176 }.type } 177 178 it 'returns the offset of a field in a record of the type in bits' do 179 expect(struct.offsetof('Next')).to be_kind_of(Integer) 180 expect(struct.offsetof('Next')).to be(64) 181 end 182 end 183 184 describe '#ref_qualifier' do 185 let(:lvalue) { find_matching(cursor_cxx) { |child, parent| 186 child.kind == :cursor_cxx_method and child.spelling == 'func_lvalue_ref' 187 }.type } 188 let(:rvalue) { find_matching(cursor_cxx) { |child, parent| 189 child.kind == :cursor_cxx_method and child.spelling == 'func_rvalue_ref' 190 }.type } 191 let(:none) { find_matching(cursor_cxx) { |child, parent| 192 child.kind == :cursor_cxx_method and child.spelling == 'func_none' 193 }.type } 194 195 it 'returns :ref_qualifier_lvalue the type is ref-qualified with lvalue' do 196 expect(lvalue.ref_qualifier).to be(:ref_qualifier_lvalue) 197 end 198 199 it 'returns :ref_qualifier_rvalue the type is ref-qualified with rvalue' do 200 expect(rvalue.ref_qualifier).to be(:ref_qualifier_rvalue) 201 end 202 203 it 'returns :ref_qualifier_none the type is not ref-qualified' do 204 expect(none.ref_qualifier).to be(:ref_qualifier_none) 205 end 206 end 207 208 describe '#pod?' do 209 let(:struct) { find_matching(cursor_list) { |child, parent| 210 child.kind == :cursor_struct and child.spelling == 'List' 211 }.type } 212 213 it 'returns true if the type is a POD type' do 214 expect(struct.pod?).to be true 215 end 216 end 217 218 describe '#class_type' do 219 let(:member_pointer) { find_matching(cursor_cxx) { |child, parent| 220 child.kind == :cursor_variable and child.spelling == 'member_pointer' 221 }.type } 222 223 it 'returns the class type of the member pointer type' do 224 expect(member_pointer.class_type).to be_kind_of(Type) 225 expect(member_pointer.class_type.kind).to be(:type_record) 226 expect(member_pointer.class_type.spelling).to eq('A') 227 end 228 end 229 230 describe '#declaration' do 231 let(:struct_ref) { find_matching(cursor_cxx) { |child, parent| 232 child.kind == :cursor_type_ref and child.spelling == 'struct D' 233 }.type } 234 let(:struct_decl) { find_matching(cursor_cxx) { |child, parent| 235 child.kind == :cursor_struct and child.spelling == 'D' 236 } } 237 let(:no_decl) { find_first(cursor_cxx, :cursor_cxx_method).type } 238 239 it 'returns the class type of the member pointer type' do 240 expect(struct_ref.declaration).to be_kind_of(Cursor) 241 expect(struct_ref.declaration.kind).to be(:cursor_struct) 242 expect(struct_ref.declaration).to eq(struct_decl) 243 end 244 245 it 'returns :cursor_no_decl_found if the type has no declaration' do 246 expect(no_decl.declaration).to be_kind_of(Cursor) 247 expect(no_decl.declaration.kind).to be(:cursor_no_decl_found) 248 end 249 end 250 251 describe '#calling_conv' do 252 let(:function) { find_matching(cursor_cxx) { |child, parent| 253 child.kind == :cursor_function and child.spelling == 'f_variadic' 254 }.type } 255 256 it 'returns the calling convention associated with the function type' do 257 expect(function.calling_conv).to be(:calling_conv_c) 258 end 259 end 260 261 describe '#==' do 262 let(:type_decl) { find_matching(cursor_cxx) { |child, parent| 263 child.kind == :cursor_field_decl and child.spelling == 'int_member_a' 264 }.type } 265 let(:type_ref) { find_matching(cursor_cxx) { |child, parent| 266 child.kind == :cursor_decl_ref_expr and child.spelling == 'int_member_a' 267 }.type } 268 269 it 'checks if two types represent the same type' do 270 expect(type_decl == type_ref).to be true 271 end 272 end 273 end