ghazel-ffi-clang 0.2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +21 -0
  5. data/Gemfile +4 -0
  6. data/README.md +74 -0
  7. data/Rakefile +12 -0
  8. data/ext/rakefile.rb +12 -0
  9. data/ext/teapot.rb +16 -0
  10. data/ffi-clang.gemspec +26 -0
  11. data/lib/ffi/clang.rb +54 -0
  12. data/lib/ffi/clang/comment.rb +278 -0
  13. data/lib/ffi/clang/cursor.rb +378 -0
  14. data/lib/ffi/clang/diagnostic.rb +113 -0
  15. data/lib/ffi/clang/file.rb +69 -0
  16. data/lib/ffi/clang/index.rb +71 -0
  17. data/lib/ffi/clang/lib.rb +73 -0
  18. data/lib/ffi/clang/lib/comment.rb +117 -0
  19. data/lib/ffi/clang/lib/cursor.rb +353 -0
  20. data/lib/ffi/clang/lib/diagnostic.rb +87 -0
  21. data/lib/ffi/clang/lib/file.rb +57 -0
  22. data/lib/ffi/clang/lib/index.rb +34 -0
  23. data/lib/ffi/clang/lib/source_location.rb +53 -0
  24. data/lib/ffi/clang/lib/source_range.rb +46 -0
  25. data/lib/ffi/clang/lib/string.rb +45 -0
  26. data/lib/ffi/clang/lib/token.rb +58 -0
  27. data/lib/ffi/clang/lib/translation_unit.rb +106 -0
  28. data/lib/ffi/clang/lib/type.rb +154 -0
  29. data/lib/ffi/clang/lib/utils.rb +29 -0
  30. data/lib/ffi/clang/source_location.rb +149 -0
  31. data/lib/ffi/clang/source_range.rb +61 -0
  32. data/lib/ffi/clang/token.rb +95 -0
  33. data/lib/ffi/clang/translation_unit.rb +142 -0
  34. data/lib/ffi/clang/type.rb +135 -0
  35. data/lib/ffi/clang/unsaved_file.rb +49 -0
  36. data/lib/ffi/clang/utils.rb +58 -0
  37. data/lib/ffi/clang/version.rb +26 -0
  38. data/spec/clang/comment_spec.rb +470 -0
  39. data/spec/clang/cursor_spec.rb +709 -0
  40. data/spec/clang/diagnostic_spec.rb +89 -0
  41. data/spec/clang/file_spec.rb +84 -0
  42. data/spec/clang/index_spec.rb +70 -0
  43. data/spec/clang/source_location_spec.rb +140 -0
  44. data/spec/clang/source_range_spec.rb +76 -0
  45. data/spec/clang/token_spec.rb +83 -0
  46. data/spec/clang/translation_unit_spec.rb +214 -0
  47. data/spec/clang/type_spec.rb +289 -0
  48. data/spec/clang/utils_spec.rb +61 -0
  49. data/spec/fixtures/a.c +7 -0
  50. data/spec/fixtures/canonical.c +5 -0
  51. data/spec/fixtures/docs.c +1 -0
  52. data/spec/fixtures/docs.cc +1 -0
  53. data/spec/fixtures/docs.h +54 -0
  54. data/spec/fixtures/list.c +11 -0
  55. data/spec/fixtures/location1.c +7 -0
  56. data/spec/fixtures/simple.c +3 -0
  57. data/spec/fixtures/test.cxx +62 -0
  58. data/spec/spec_helper.rb +64 -0
  59. metadata +180 -0
@@ -0,0 +1,709 @@
1
+ # Copyright, 2010-2012 by Jari Bakken.
2
+ # Copyright, 2013, by Samuel G. D. Williams. <http://www.codeotaku.com>
3
+ # Copyright, 2013, by Garry C. Marshall. <http://www.meaningfulname.net>
4
+ # Copyright, 2014, by Masahiro Sano.
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+
24
+ require 'spec_helper'
25
+
26
+ describe Cursor do
27
+ let(:cursor) { Index.new.parse_translation_unit(fixture_path("list.c")).cursor }
28
+ let(:cursor_cxx) { Index.new.parse_translation_unit(fixture_path("test.cxx")).cursor }
29
+ let(:cursor_canon) { Index.new.parse_translation_unit(fixture_path("canonical.c")).cursor }
30
+ let(:cursor_pp) { Index.new.parse_translation_unit(fixture_path("docs.c"),[],[],{detailed_preprocessing_record: true}).cursor }
31
+
32
+ it "can be obtained from a translation unit" do
33
+ cursor.should be_kind_of(Cursor)
34
+ cursor.kind.should equal(:cursor_translation_unit)
35
+ cursor.null?.should equal(false)
36
+ cursor.translation_unit?.should equal(true)
37
+ end
38
+
39
+ it "returns the source location of the cursor" do
40
+ location = cursor.location
41
+ location.should be_kind_of(SourceLocation)
42
+ end
43
+
44
+ describe '#extent' do
45
+ let(:extent) { cursor.extent }
46
+ it "has an extent which is a SourceRange" do
47
+ expect(extent).to be_kind_of(SourceRange)
48
+ end
49
+
50
+ it 'has filename and posion at start point' do
51
+ expect(extent.start.file).to eq(fixture_path("list.c"))
52
+ expect(extent.start.line).to equal(1)
53
+ end
54
+
55
+ it 'has filename and posion at end point', from_3_4: true do
56
+ expect(extent.end.file).to eq(fixture_path("list.c"))
57
+ expect(extent.end.line).to equal(12)
58
+ end
59
+
60
+ it 'has filename and posion at end point', upto_3_3: true do
61
+ expect(extent.end.file).to eq(fixture_path("list.c"))
62
+ expect(extent.end.line).to equal(11)
63
+ end
64
+ end
65
+
66
+ it "returns the path of the translation unit for the translation unit cursor" do
67
+ cursor.display_name.should eq(fixture_path("list.c"))
68
+ cursor.spelling.should eq(fixture_path("list.c"))
69
+ end
70
+
71
+ it "allows us to visit its children" do
72
+ counter = 0
73
+ cursor.visit_children do |cursor, parent|
74
+ counter += 1
75
+ :recurse
76
+ end
77
+ counter.should_not equal(0)
78
+ end
79
+
80
+ describe "Null Cursor" do
81
+ it "can be a null cursor" do
82
+ Cursor.null_cursor.should be_kind_of(Cursor)
83
+ Cursor.null_cursor.kind.should equal(:cursor_invalid_file)
84
+ end
85
+
86
+ it "is null?" do
87
+ Cursor.null_cursor.null?.should equal(true)
88
+ end
89
+
90
+ it "is invalid?" do
91
+ Cursor.null_cursor.invalid?.should equal(true)
92
+ end
93
+
94
+ it "compares as equal to another null cursor instance" do
95
+ Cursor.null_cursor.should eq(Cursor.null_cursor)
96
+ end
97
+
98
+ it "should not equal a Translation Unit cursor" do
99
+ Cursor.null_cursor.should_not eq(cursor)
100
+ end
101
+ end
102
+
103
+ describe "Function Cursors" do
104
+ let (:func) { find_first(cursor, :cursor_function) }
105
+
106
+ it "is not invalid?" do
107
+ func.invalid?.should equal(false)
108
+ end
109
+
110
+ it "can find the first function declaration" do
111
+ func.should_not equal(nil)
112
+ func.kind.should equal(:cursor_function)
113
+ end
114
+
115
+ it "has an extent representing the bounds of the function" do
116
+ func.extent.should be_kind_of(SourceRange)
117
+ func.extent.start.line.should equal(5)
118
+ func.extent.end.line.should equal(5)
119
+ end
120
+
121
+ it "returns the name of the function" do
122
+ func.spelling.should eq("sum")
123
+ func.display_name.should eq("sum(union List *)")
124
+ end
125
+ end
126
+
127
+ describe "Struct Cursors" do
128
+ let (:struct) { find_first(cursor, :cursor_struct) }
129
+
130
+ it "can find the first struct" do
131
+ struct.should_not equal(nil)
132
+ struct.kind.should equal(:cursor_struct)
133
+ end
134
+
135
+ it "has an extent representing the bounds of the struct" do
136
+ struct.extent.start.line.should equal(1)
137
+ struct.extent.end.line.should equal(4)
138
+ end
139
+
140
+ it "returns the name of the struct" do
141
+ struct.spelling.should eq("List")
142
+ struct.display_name.should eq("List")
143
+ end
144
+
145
+ end
146
+
147
+ describe '#kind_spelling' do
148
+ let (:struct) { find_first(cursor, :cursor_struct) }
149
+
150
+ it "returns the spelling of the given kind" do
151
+ expect(struct.kind_spelling).to eq('StructDecl')
152
+ end
153
+ end
154
+
155
+ describe '#declaration?' do
156
+ let (:struct) { find_first(cursor, :cursor_struct) }
157
+
158
+ it "checks the cursor is declaration" do
159
+ expect(struct.declaration?).to be_true
160
+ end
161
+ end
162
+
163
+ describe '#reference?' do
164
+ let (:ref) { find_first(cursor, :cursor_type_ref) }
165
+
166
+ it "checks the cursor is reference" do
167
+ expect(ref.reference?).to be_true
168
+ end
169
+ end
170
+
171
+ describe '#expression?' do
172
+ let (:literal) { find_first(cursor, :cursor_integer_literal) }
173
+
174
+ it "checks the cursor is expression" do
175
+ expect(literal.expression?).to be_true
176
+ end
177
+ end
178
+
179
+ describe '#statement?' do
180
+ let (:return_stmt) { find_first(cursor, :cursor_return_stmt) }
181
+
182
+ it "checks the cursor is statement" do
183
+ expect(return_stmt.statement?).to be_true
184
+ end
185
+ end
186
+
187
+ describe '#attribute?' do
188
+ let (:attr) { find_first(cursor_cxx, :cursor_unexposed_attr) }
189
+
190
+ it "checks the cursor is attribute" do
191
+ expect(attr.attribute?).to be_true
192
+ end
193
+ end
194
+
195
+ describe '#public?' do
196
+ let(:public_cursor) { find_matching(cursor_cxx) { |child, parent|
197
+ child.kind == :cursor_field_decl and child.spelling == 'public_member_int' } }
198
+
199
+ it 'checks access control level is public', from_3_3: true do
200
+ expect(public_cursor.public?).to be_true
201
+ end
202
+
203
+ it 'returns false on clang 3.2', upto_3_2: true do
204
+ expect(public_cursor.public?).to be_false
205
+ end
206
+ end
207
+
208
+ describe '#private?' do
209
+ let(:private_cursor) { find_matching(cursor_cxx) { |child, parent|
210
+ child.kind == :cursor_field_decl and child.spelling == 'private_member_int' } }
211
+
212
+ it 'checks access control level is private', from_3_3: true do
213
+ expect(private_cursor.private?).to be_true
214
+ end
215
+
216
+ it 'returns false on clang 3.2', upto_3_2: true do
217
+ expect(private_cursor.private?).to be_false
218
+ end
219
+ end
220
+
221
+ describe '#protected?' do
222
+ let(:protected_cursor) { find_matching(cursor_cxx) { |child, parent|
223
+ child.kind == :cursor_field_decl and child.spelling == 'protected_member_int' } }
224
+
225
+ it 'checks access control level is protected', from_3_3: true do
226
+ expect(protected_cursor.protected?).to be_true
227
+ end
228
+
229
+ it 'returns false on clang 3.2', upto_3_2: true do
230
+ expect(protected_cursor.protected?).to be_false
231
+ end
232
+ end
233
+
234
+ describe '#preprocessing?' do
235
+ let (:pp) { find_first(cursor_pp, :cursor_macro_definition) }
236
+
237
+ it 'checks the cursor is preprocessing' do
238
+ expect(pp.preprocessing?).to be_true
239
+ end
240
+ end
241
+
242
+ describe '#unexposed?' do
243
+ let(:unexposed_cursor) { find_matching(cursor_cxx) { |child, parent|
244
+ child.kind == :cursor_unexposed_expr and child.spelling == 'func_overloaded' } }
245
+
246
+ it 'checks the cursor is unexposed' do
247
+ expect(unexposed_cursor.unexposed?).to be_true
248
+ end
249
+ end
250
+
251
+ describe '#virtual_base?' do
252
+ let(:virtual_base_cursor) { find_matching(cursor_cxx) { |child, parent|
253
+ child.kind == :cursor_cxx_base_specifier and parent.spelling == 'B' } }
254
+
255
+ it 'checks cursor is virtual base' do
256
+ virtual_base_cursor.virtual_base?.should equal true
257
+ end
258
+ end
259
+
260
+ describe '#virtual?' do
261
+ let(:virtual_cursor) { find_matching(cursor_cxx) { |child, parent|
262
+ child.kind == :cursor_cxx_method and child.spelling == 'func_a' } }
263
+
264
+ it 'checks member function is virtual' do
265
+ virtual_cursor.virtual?.should equal true
266
+ end
267
+ end
268
+
269
+ describe '#pure_virtual?', from_3_4: true do
270
+ let(:pure_virtual_cursor) { find_matching(cursor_cxx) { |child, parent|
271
+ child.kind == :cursor_cxx_method and
272
+ child.spelling == 'func_a' and parent.spelling == 'A' } }
273
+
274
+ it 'checks member function is purely virtual' do
275
+ pure_virtual_cursor.pure_virtual?.should equal true
276
+ end
277
+ end
278
+
279
+ describe '#static?' do
280
+ let(:static_method_cursor) { find_matching(cursor_cxx) { |child, parent|
281
+ child.kind == :cursor_cxx_method and child.spelling == 'func_b' } }
282
+
283
+ it 'checks cursor is static member function' do
284
+ static_method_cursor.static?.should equal true
285
+ end
286
+ end
287
+
288
+ describe '#enum_value' do
289
+ let(:enum_value_cursor) { find_matching(cursor_cxx) { |child, parent|
290
+ child.kind == :cursor_enum_constant_decl and child.spelling == 'EnumC' } }
291
+
292
+ it 'returns enum value' do
293
+ enum_value_cursor.enum_value.should equal 100
294
+ end
295
+ end
296
+
297
+ describe '#enum_unsigned_value' do
298
+ let(:enum_value_cursor) { find_matching(cursor_cxx) { |child, parent|
299
+ child.kind == :cursor_enum_constant_decl and child.spelling == 'EnumC' } }
300
+
301
+ it 'returns enum unsigned value' do
302
+ expect(enum_value_cursor.enum_unsigned_value).to eq(100)
303
+ end
304
+ end
305
+
306
+ describe '#dynamic_call?' do
307
+ let(:dynamic_call) { find_matching(cursor_cxx) { |child, parent|
308
+ child.kind == :cursor_call_expr and child.spelling == 'func_a' and
309
+ child.semantic_parent.spelling == 'f_dynamic_call' } }
310
+
311
+ it 'checks if the method call is dynamic' do
312
+ expect(dynamic_call.dynamic_call?).to be_true
313
+ end
314
+ end
315
+
316
+ describe '#specialized_template', from_3_3: true do # looks not working on 3.2
317
+ let(:cursor_function) { find_matching(cursor_cxx) { |child, parent|
318
+ child.kind == :cursor_function and child.spelling == 'func_overloaded' } }
319
+
320
+ it "returns a cursor that may represent a specialization or instantiation of a template" do
321
+ expect(cursor_function.specialized_template).to be_kind_of(Cursor)
322
+ expect(cursor_function.specialized_template.kind).to be(:cursor_function_template)
323
+ end
324
+ end
325
+
326
+ describe '#canonical' do
327
+ let (:structs) { find_all(cursor_canon, :cursor_struct) }
328
+
329
+ it "mathes 3 cursors" do
330
+ structs.size.should eq(3)
331
+ end
332
+
333
+ it "refers the first cursor as canonical one" do
334
+ structs[0].canonical.should eq(structs[0])
335
+ structs[1].canonical.should eq(structs[0])
336
+ structs[2].canonical.should eq(structs[0])
337
+ end
338
+ end
339
+
340
+ describe '#definition' do
341
+ let (:structs) { find_all(cursor_canon, :cursor_struct) }
342
+
343
+ it "mathes 3 cursors" do
344
+ structs.size.should eq(3)
345
+ end
346
+
347
+ it "refers the third cursor as definition one" do
348
+ structs[0].definition.should eq(structs[2])
349
+ structs[1].definition.should eq(structs[2])
350
+ structs[2].definition.should eq(structs[2])
351
+ end
352
+ end
353
+
354
+ describe '#template_kind', from_3_3: true do # looks not working on 3.2
355
+ let(:template) { find_matching(cursor_cxx) { |child, parent|
356
+ child.kind == :cursor_function_template and child.spelling == 'func_overloaded' } }
357
+
358
+ it "returns the cursor kind of the specializations would be generated" do
359
+ expect(template.template_kind).to be_kind_of(Symbol)
360
+ expect(template.template_kind).to be(:cursor_function)
361
+ end
362
+ end
363
+
364
+ describe '#access_specifier' do
365
+ let(:access_specifier_cursor) { find_matching(cursor_cxx) { |child, parent|
366
+ child.kind == :cursor_cxx_method and child.spelling == 'func_d' } }
367
+
368
+ it 'returns access specifier symbol', from_3_3: true do
369
+ access_specifier_cursor.access_specifier.should equal :private
370
+ end
371
+
372
+ it 'returns access specifier symbol(invalid, why?)', upto_3_2: true do
373
+ access_specifier_cursor.access_specifier.should equal :invalid
374
+ end
375
+ end
376
+
377
+ describe '#language' do
378
+ let(:c_language_cursor) { find_matching(cursor) { |c, p| c.kind == :cursor_struct } }
379
+ let(:cxx_language_cursor) { find_matching(cursor_cxx) { |c, p| c.kind == :cursor_struct } }
380
+
381
+ it 'returns :c if the cursor language is C' do
382
+ c_language_cursor.language.should equal :c
383
+ end
384
+
385
+ it 'returns :c_plus_plus if the cursor language is C++' do
386
+ cxx_language_cursor.language.should equal :c_plus_plus
387
+ end
388
+ end
389
+
390
+ describe '#translation_unit' do
391
+ let (:struct) { find_first(cursor, :cursor_struct) }
392
+
393
+ it "can find the first struct" do
394
+ struct.should_not equal(nil)
395
+ end
396
+
397
+ it "returns the translation unit that a cursor originated from" do
398
+ struct.translation_unit.should be_kind_of(TranslationUnit)
399
+ struct.translation_unit.spelling.should eq(fixture_path("list.c"))
400
+ end
401
+ end
402
+
403
+ describe '#linkage' do
404
+ let (:ref) { find_first(cursor, :cursor_type_ref) }
405
+ let (:func) { find_first(cursor, :cursor_function) }
406
+
407
+ it "returns :external if the cursor is non-static function" do
408
+ func.linkage.should equal :external
409
+ end
410
+
411
+ it "returns :invalid if the cursor does not have linkage" do
412
+ ref.linkage.should equal :invalid
413
+ end
414
+ end
415
+
416
+ describe '#semantic_parent' do
417
+ let(:parent) { find_matching(cursor_cxx) { |child, parent|
418
+ child.kind == :cursor_cxx_method and child.spelling == 'func_d' and parent.spelling != 'D' } }
419
+
420
+ it 'returns base class as semantic parent' do
421
+ parent.semantic_parent.spelling.should eq('D')
422
+ end
423
+ end
424
+
425
+ describe '#lexical_parent' do
426
+ let(:parent) { find_matching(cursor_cxx) { |child, parent|
427
+ child.kind == :cursor_cxx_method and child.spelling == 'func_d' and parent.spelling != 'D' } }
428
+
429
+ it 'returns translation unit as lexical parent' do
430
+ parent.lexical_parent.kind.should eq(:cursor_translation_unit)
431
+ end
432
+ end
433
+
434
+ describe '#included_file' do
435
+ #TODO
436
+ end
437
+
438
+ describe '#definition?' do
439
+ let (:struct) { find_all(cursor_canon, :cursor_struct).at(2) }
440
+
441
+ it "checks cursor is a definition" do
442
+ struct.definition?.should be_true
443
+ end
444
+ end
445
+
446
+ describe '#usr' do
447
+ let (:func) { find_first(cursor, :cursor_function) }
448
+
449
+ it "returns something in string" do
450
+ func.usr.should be_kind_of(String)
451
+ end
452
+ end
453
+
454
+ describe '#variadic?', from_3_3: true do
455
+ let(:func) { find_matching(cursor_cxx) { |child, parent|
456
+ child.kind == :cursor_function and child.spelling == 'f_variadic' } }
457
+
458
+ it "checks cursor is a variadic function" do
459
+ func.variadic?.should be_true
460
+ end
461
+ end
462
+
463
+ describe '#referenced' do
464
+ let(:struct) { find_matching(cursor_cxx) { |child, parent|
465
+ child.kind == :cursor_struct and child.spelling == 'A' } }
466
+ let(:ref) { find_matching(cursor_cxx) { |child, parent|
467
+ child.kind == :cursor_type_ref and child.spelling == 'struct A' } }
468
+
469
+ it "returns a cursor that this cursor references" do
470
+ ref.referenced.should eq(struct)
471
+ end
472
+
473
+ end
474
+
475
+ describe '#hash' do
476
+ let (:func) { find_first(cursor, :cursor_function) }
477
+
478
+ it "computes hash for the cursor" do
479
+ func.hash.should be_kind_of(Fixnum)
480
+ end
481
+ end
482
+
483
+ describe '#availability' do
484
+ let (:func) { find_first(cursor, :cursor_function) }
485
+
486
+ it "returns :available for the cursor availability" do
487
+ func.availability.should equal(:available)
488
+ end
489
+ end
490
+
491
+ describe '#type' do
492
+ let (:field) { find_first(cursor, :cursor_field_decl) }
493
+
494
+ it "returns type for the cursor" do
495
+ field.type.should be_kind_of(Type)
496
+ field.type.kind.should equal(:type_int)
497
+ end
498
+ end
499
+
500
+ describe '#underlying_type' do
501
+ let (:typedef) { find_first(cursor_cxx, :cursor_typedef_decl) }
502
+
503
+ it "returns type that the cursor type is underlying" do
504
+ typedef.underlying_type.should be_kind_of(Type)
505
+ typedef.underlying_type.kind.should equal(:type_pointer)
506
+ end
507
+ end
508
+
509
+ describe '#bitfield?', from_3_3: true do
510
+ let(:bitfield) { find_matching(cursor_cxx) { |child, parent|
511
+ child.kind == :cursor_field_decl and child.spelling == 'bit_field_a' } }
512
+ let(:non_bitfield) { find_matching(cursor_cxx) { |child, parent|
513
+ child.kind == :cursor_field_decl and child.spelling == 'non_bit_field_c' } }
514
+
515
+ it "returns true if the cursor is bitfield" do
516
+ expect(bitfield.bitfield?).to be_true
517
+ end
518
+
519
+ it "returns false if the cursor is not bitfield" do
520
+ expect(non_bitfield.bitfield?).to be_false
521
+ end
522
+ end
523
+
524
+ describe '#bitwidth', from_3_3: true do
525
+ let(:bitfield) { find_matching(cursor_cxx) { |child, parent|
526
+ child.kind == :cursor_field_decl and child.spelling == 'bit_field_a' } }
527
+ let(:non_bitfield) { find_matching(cursor_cxx) { |child, parent|
528
+ child.kind == :cursor_field_decl and child.spelling == 'non_bit_field_c' } }
529
+
530
+ it "returns the bit width of the bit field if the cursor is bitfield" do
531
+ expect(bitfield.bitwidth).to be_kind_of(Integer)
532
+ expect(bitfield.bitwidth).to eq(2)
533
+ end
534
+
535
+ it "returns -1 if the cursor is not bitfield" do
536
+ expect(non_bitfield.bitwidth).to eq(-1)
537
+ end
538
+ end
539
+
540
+ describe '#enum_decl_integer_type' do
541
+ let(:enum) { find_matching(cursor_cxx) { |child, parent|
542
+ child.kind == :cursor_enum_decl and child.spelling == 'normal_enum' } }
543
+
544
+ it "returns the integer type of the enum declaration" do
545
+ expect(enum.enum_decl_integer_type).to be_kind_of(Type)
546
+ expect(enum.enum_decl_integer_type.kind).to be(:type_uint)
547
+ end
548
+ end
549
+
550
+ describe '#platform_availability' do
551
+ let(:func) { find_matching(cursor_cxx) { |child, parent|
552
+ child.kind == :cursor_function and child.spelling == 'availability_func'} }
553
+ let(:availability) { func.platform_availability }
554
+
555
+ it "returns the availability of the entity as Hash" do
556
+ expect(availability).to be_kind_of(Hash)
557
+ expect(availability[:always_deprecated]).to be_kind_of(Integer)
558
+ expect(availability[:always_unavailable]).to be_kind_of(Integer)
559
+ expect(availability[:deprecated_message]).to be_kind_of(String)
560
+ expect(availability[:unavailable_message]).to be_kind_of(String)
561
+ expect(availability[:availability]).to be_kind_of(Array)
562
+ end
563
+ end
564
+
565
+ describe '#overriddens' do
566
+ let(:override_cursor) { find_matching(cursor_cxx) { |child, parent|
567
+ child.kind == :cursor_cxx_method and
568
+ child.spelling == 'func_a' and parent.spelling == 'D' } }
569
+
570
+ it "returns the set of methods which are overridden by this cursor method" do
571
+ expect(override_cursor.overriddens).to be_kind_of(Array)
572
+ expect(override_cursor.overriddens.size).to eq(2)
573
+ expect(override_cursor.overriddens.map{|cur| cur.semantic_parent.spelling}).to eq(["B", "C"])
574
+ end
575
+ end
576
+
577
+ describe '#overloaded_decl' do
578
+ let(:overloaded) { find_matching(cursor_cxx) { |child, parent|
579
+ child.kind == :cursor_overloaded_decl_ref and child.spelling == 'func_overloaded' } }
580
+
581
+ it "returns a cursor for one of the overloaded declarations" do
582
+ expect(overloaded.overloaded_decl(0)).to be_kind_of(Cursor)
583
+ expect(overloaded.overloaded_decl(0).kind).to be(:cursor_function_template)
584
+ expect(overloaded.overloaded_decl(0).spelling).to eq('func_overloaded')
585
+ end
586
+ end
587
+
588
+ describe '#num_overloaded_decls' do
589
+ let(:overloaded) { find_matching(cursor_cxx) { |child, parent|
590
+ child.kind == :cursor_overloaded_decl_ref and child.spelling == 'func_overloaded' } }
591
+
592
+ it "returns the number of overloaded declarations" do
593
+ expect(overloaded.num_overloaded_decls).to be_kind_of(Integer)
594
+ expect(overloaded.num_overloaded_decls).to be(2)
595
+ end
596
+ end
597
+
598
+ describe '#objc_type_encoding' do
599
+ #TODO
600
+ end
601
+
602
+ describe '#argument' do
603
+ let(:func) { find_matching(cursor_cxx) { |child, parent|
604
+ child.kind == :cursor_function and child.spelling == 'f_non_variadic' } }
605
+
606
+ it "returns the argument cursor of the function" do
607
+ expect(func.argument(0)).to be_kind_of(Cursor)
608
+ expect(func.argument(0).spelling).to eq('a')
609
+ end
610
+ end
611
+
612
+ describe '#num_arguments' do
613
+ let(:cursor_cxx) { Index.new.parse_translation_unit(fixture_path("test.cxx")).cursor }
614
+ let(:func) { find_matching(cursor_cxx) { |child, parent|
615
+ child.kind == :cursor_function and child.spelling == 'f_non_variadic' } }
616
+
617
+ it "returns the number of non-variadic arguments" do
618
+ expect(func.num_arguments).to be_kind_of(Integer)
619
+ expect(func.num_arguments).to be(3)
620
+ end
621
+ end
622
+
623
+ describe '#result_type' do
624
+ let(:func) { find_matching(cursor_cxx) { |child, parent|
625
+ child.kind == :cursor_function and child.spelling == 'f_non_variadic' } }
626
+
627
+ it "result the result type of the function" do
628
+ expect(func.result_type).to be_kind_of(Type)
629
+ expect(func.result_type.kind).to be(:type_void)
630
+ end
631
+ end
632
+
633
+ describe '#raw_comment_text' do
634
+ let(:func) { find_matching(cursor_pp) { |child, parent|
635
+ child.kind == :cursor_function and child.spelling == 'a_function' } }
636
+
637
+ it "checks the cursor is declaration" do
638
+ expect(func.raw_comment_text).to be_kind_of(String)
639
+ expect(func.raw_comment_text).not_to be_empty
640
+ end
641
+ end
642
+
643
+ describe '#comment' do
644
+ let(:func) { find_matching(cursor_pp) { |child, parent|
645
+ child.kind == :cursor_function and child.spelling == 'a_function' } }
646
+
647
+ it "checks the cursor is declaration" do
648
+ expect(func.comment).to be_kind_of(Comment)
649
+ end
650
+ end
651
+
652
+ describe '#included_file' do
653
+ let (:inclusion) { find_first(cursor_pp, :cursor_inclusion_directive) }
654
+
655
+ it 'returns the file that is included by the given inclusion directive cursor' do
656
+ expect(inclusion.included_file).to be_kind_of(FFI::Clang::File)
657
+ expect(File.basename(inclusion.included_file.name)).to eq("docs.h")
658
+ end
659
+ end
660
+
661
+ describe Cursor::PlatformAvailability do
662
+ let(:func) { find_matching(cursor_cxx) { |child, parent|
663
+ child.kind == :cursor_function and child.spelling == 'availability_func'} }
664
+ let(:availability) { func.platform_availability[:availability].first }
665
+
666
+ it "can be obtained by Cursor#platform_availability" do
667
+ expect(availability).to be_kind_of(Cursor::PlatformAvailability)
668
+ end
669
+
670
+ describe "#platform" do
671
+ it "returns availability information for the platform" do
672
+ expect(availability.platform).to be_kind_of(String)
673
+ end
674
+ end
675
+
676
+ describe "#introduced" do
677
+ it "returns the version number in which this entity was introduced" do
678
+ expect(availability.introduced).to be_kind_of(Lib::CXVersion)
679
+ expect(availability.introduced.to_s).to eq("10.4.1")
680
+ end
681
+ end
682
+
683
+ describe "#deprecated" do
684
+ it "returns the version number in which this entity was deprecated" do
685
+ expect(availability.deprecated).to be_kind_of(Lib::CXVersion)
686
+ expect(availability.deprecated.to_s).to eq("10.6")
687
+ end
688
+ end
689
+
690
+ describe "#obsoleted" do
691
+ it "returns the version number in which this entity was obsoleted" do
692
+ expect(availability.obsoleted).to be_kind_of(Lib::CXVersion)
693
+ expect(availability.obsoleted.to_s).to eq("10.7")
694
+ end
695
+ end
696
+
697
+ describe "#unavailable" do
698
+ it "returns whether the entity is unavailable on this platform" do
699
+ expect(availability.unavailable).to be_false
700
+ end
701
+ end
702
+
703
+ describe "#message" do
704
+ it "returns an optional message to provide to a user of this API" do
705
+ expect(availability.message).to be_kind_of(String)
706
+ end
707
+ end
708
+ end
709
+ end