ffi-clang 0.2.0 → 0.2.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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +12 -8
  3. data/README.md +3 -1
  4. data/ffi-clang.gemspec +1 -1
  5. data/lib/ffi/clang.rb +3 -1
  6. data/lib/ffi/clang/code_completion.rb +193 -0
  7. data/lib/ffi/clang/comment.rb +154 -11
  8. data/lib/ffi/clang/compilation_database.rb +125 -0
  9. data/lib/ffi/clang/cursor.rb +145 -9
  10. data/lib/ffi/clang/diagnostic.rb +36 -10
  11. data/lib/ffi/clang/file.rb +69 -0
  12. data/lib/ffi/clang/index.rb +9 -17
  13. data/lib/ffi/clang/lib.rb +25 -2
  14. data/lib/ffi/clang/lib/code_completion.rb +130 -0
  15. data/lib/ffi/clang/lib/comment.rb +73 -12
  16. data/lib/ffi/clang/lib/compilation_database.rb +58 -0
  17. data/lib/ffi/clang/lib/cursor.rb +78 -14
  18. data/lib/ffi/clang/lib/diagnostic.rb +32 -12
  19. data/lib/ffi/clang/lib/file.rb +15 -3
  20. data/lib/ffi/clang/lib/inclusions.rb +32 -0
  21. data/lib/ffi/clang/lib/source_location.rb +18 -0
  22. data/lib/ffi/clang/lib/source_range.rb +5 -0
  23. data/lib/ffi/clang/lib/token.rb +58 -0
  24. data/lib/ffi/clang/lib/translation_unit.rb +71 -1
  25. data/lib/ffi/clang/lib/type.rb +61 -3
  26. data/lib/ffi/clang/source_location.rb +102 -0
  27. data/lib/ffi/clang/source_range.rb +25 -4
  28. data/lib/ffi/clang/token.rb +95 -0
  29. data/lib/ffi/clang/translation_unit.rb +118 -2
  30. data/lib/ffi/clang/type.rb +61 -0
  31. data/lib/ffi/clang/unsaved_file.rb +16 -0
  32. data/lib/ffi/clang/utils.rb +38 -12
  33. data/lib/ffi/clang/version.rb +1 -1
  34. data/spec/clang/code_completion_spec.rb +181 -0
  35. data/spec/clang/comment_spec.rb +385 -12
  36. data/spec/clang/compilation_database_spec.rb +178 -0
  37. data/spec/clang/cursor_spec.rb +335 -12
  38. data/spec/clang/diagnostic_spec.rb +63 -4
  39. data/spec/clang/file_spec.rb +84 -0
  40. data/spec/clang/index_spec.rb +62 -5
  41. data/spec/clang/source_location_spec.rb +104 -4
  42. data/spec/clang/source_range_spec.rb +76 -0
  43. data/spec/clang/token_spec.rb +84 -0
  44. data/spec/clang/translation_unit_spec.rb +202 -5
  45. data/spec/clang/type_spec.rb +191 -0
  46. data/spec/clang/utils_spec.rb +2 -3
  47. data/spec/fixtures/a.c +3 -0
  48. data/spec/fixtures/compile_commands.json +17 -0
  49. data/spec/fixtures/completion.cxx +8 -0
  50. data/spec/fixtures/docs.c +1 -0
  51. data/spec/fixtures/docs.cc +1 -0
  52. data/spec/fixtures/docs.h +46 -3
  53. data/spec/fixtures/list.c +1 -0
  54. data/spec/fixtures/location1.c +7 -0
  55. data/spec/fixtures/simple.c +3 -0
  56. data/spec/fixtures/test.cxx +36 -0
  57. data/spec/spec_helper.rb +11 -0
  58. metadata +50 -21
@@ -0,0 +1,178 @@
1
+ # Copyright, 2014, by Masahiro Sano.
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'spec_helper'
22
+
23
+ describe CompilationDatabase do
24
+ let(:dirpath) { fixture_path('') }
25
+ let(:cdb) { CompilationDatabase.new(dirpath) }
26
+ let(:file) { '/home/xxxxx/src/llvm-trunk/lib/Support/APFloat.cpp' }
27
+
28
+ it "can be created" do
29
+ expect(cdb).to be_kind_of(CompilationDatabase)
30
+ end
31
+
32
+ it "raises DatabaseLoadError if cannot be created" do
33
+ expect{CompilationDatabase.new('/not/exist/directory')}.to raise_error FFI::Clang::CompilationDatabase::DatabaseLoadError
34
+ end
35
+
36
+ it "calls compilation_database_dispose on GC" do
37
+ cdb.autorelease = false
38
+ expect(Lib).to receive(:compilation_database_dispose).with(cdb).once
39
+ expect{cdb.free}.not_to raise_error
40
+ end
41
+
42
+ describe '#compile_commands' do
43
+ let(:not_found_file) { '/home/xxxxx/not_found_file_path' }
44
+
45
+ it "returns compile commands used for a file" do
46
+ expect(cdb.compile_commands(file)).to be_kind_of(CompilationDatabase::CompileCommands)
47
+ expect(cdb.compile_commands(file).size).to eq(1)
48
+ end
49
+
50
+ it "returns compile commands if the specified file is not found" do
51
+ expect(cdb.compile_commands(not_found_file)).to be_kind_of(CompilationDatabase::CompileCommands)
52
+ expect(cdb.compile_commands(not_found_file).size).to eq(0)
53
+ end
54
+ end
55
+
56
+ describe '#all_compile_commands', from_3_3: true do
57
+ it "returns all compile commands in the database" do
58
+ expect(cdb.all_compile_commands).to be_kind_of(CompilationDatabase::CompileCommands)
59
+ expect(cdb.all_compile_commands.size).to eq(3)
60
+ end
61
+ end
62
+
63
+ describe CompilationDatabase::CompileCommands do
64
+ let(:commands) { cdb.compile_commands(file) }
65
+
66
+ it "calls compile_commands_dispose on GC" do
67
+ commands.autorelease = false
68
+ expect(Lib).to receive(:compile_commands_dispose).with(commands).once
69
+ expect{commands.free}.not_to raise_error
70
+ end
71
+
72
+ describe '#size' do
73
+ it "returns the number of CompileCommand" do
74
+ expect(commands.size).to be_kind_of(Integer)
75
+ expect(commands.size).to eq(1)
76
+ end
77
+
78
+ it "returns the number of CompileCommand", from_3_3: true do
79
+ expect(cdb.all_compile_commands.size).to eq(3)
80
+ end
81
+ end
82
+
83
+ describe '#command' do
84
+ it "returns the I'th CompileCommand" do
85
+ expect(commands.command(0)).to be_kind_of(CompilationDatabase::CompileCommand)
86
+ end
87
+ end
88
+
89
+ describe "#commands" do
90
+ it "returns all CompileCommand as Array" do
91
+ expect(commands.commands).to be_kind_of(Array)
92
+ expect(commands.commands.first).to be_kind_of(CompilationDatabase::CompileCommand)
93
+ expect(commands.commands.size).to eq(commands.size)
94
+ end
95
+ end
96
+
97
+ describe "#each" do
98
+ let(:spy) { double(stub: nil) }
99
+ it "calls block once for each CompileCommand" do
100
+ expect(spy).to receive(:stub).exactly(commands.size).times
101
+ commands.each { spy.stub }
102
+ end
103
+ end
104
+ end
105
+
106
+ describe CompilationDatabase::CompileCommand do
107
+ let(:cmd) { cdb.compile_commands(file).first }
108
+
109
+ describe '#directory' do
110
+ it "returns the working directory" do
111
+ expect(cmd.directory).to be_kind_of(String)
112
+ expect(cmd.directory).to eq('/home/xxxxx/src/build-trunk/lib/Support')
113
+ end
114
+ end
115
+
116
+ describe '#num_args' do
117
+ it "returns the number of CompileCommand" do
118
+ expect(cmd.num_args).to be_kind_of(Integer)
119
+ expect(cmd.num_args).to eq(31)
120
+ end
121
+ end
122
+
123
+ describe '#arg' do
124
+ it "returns the I'th argument value" do
125
+ expect(cmd.arg(0)).to be_kind_of(String)
126
+ expect(cmd.arg(0)).to eq('/opt/llvm/3.4/bin/clang++')
127
+ end
128
+ end
129
+
130
+ describe '#args' do
131
+ it "returns all argument values as Array" do
132
+ expect(cmd.args).to be_kind_of(Array)
133
+ expect(cmd.args.first).to be_kind_of(String)
134
+ expect(cmd.args.size).to eq(cmd.num_args)
135
+ end
136
+ end
137
+
138
+ describe '#num_mapped_sources', from_3_4: true do
139
+ # TODO: a case which has mapped sources
140
+
141
+ it "returns the number of source mappings" do
142
+ # expect(cmd.num_mapped_sources).to be_kind_of(Integer)
143
+ # expect(cmd.num_mapped_sources).to eq(0)
144
+ end
145
+ end
146
+
147
+ describe '#mapped_source_path', from_3_4: true do
148
+ it "returns the I'th mapped source path" do
149
+ # TODO: a case which returns real source path
150
+ # expect(cmd.mapped_source_path(0)).to be_kind_of(String)
151
+ end
152
+
153
+ it "returns nil if the index exceeds element size" do
154
+ # expect(cmd.mapped_source_path(1000)).to be_nil
155
+ end
156
+ end
157
+
158
+ describe '#mapped_source_content', from_3_4: true do
159
+ it "returns the I'th mapped source content" do
160
+ # TODO: a case which returns real source path
161
+ # expect(cmd.mapped_source_content(0)).to be_kind_of(String)
162
+ end
163
+
164
+ it "returns nil if the index exceeds element size" do
165
+ # expect(cmd.mapped_source_content(1000)).to be_nil
166
+ end
167
+ end
168
+
169
+ describe '#mapped_sources', from_3_4: true do
170
+ # TODO: a case which has mapped sources
171
+
172
+ it "returns all mapped sources as Array" do
173
+ # expect(cmd.mapped_sources).to be_kind_of(Array)
174
+ # expect(cmd.mapped_sources.size).to eq(cmd.num_mapped_sources)
175
+ end
176
+ end
177
+ end
178
+ end
@@ -1,6 +1,7 @@
1
1
  # Copyright, 2010-2012 by Jari Bakken.
2
2
  # Copyright, 2013, by Samuel G. D. Williams. <http://www.codeotaku.com>
3
3
  # Copyright, 2013, by Garry C. Marshall. <http://www.meaningfulname.net>
4
+ # Copyright, 2014, by Masahiro Sano.
4
5
  #
5
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
7
  # of this software and associated documentation files (the "Software"), to deal
@@ -26,6 +27,7 @@ describe Cursor do
26
27
  let(:cursor) { Index.new.parse_translation_unit(fixture_path("list.c")).cursor }
27
28
  let(:cursor_cxx) { Index.new.parse_translation_unit(fixture_path("test.cxx")).cursor }
28
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 }
29
31
 
30
32
  it "can be obtained from a translation unit" do
31
33
  cursor.should be_kind_of(Cursor)
@@ -52,12 +54,12 @@ describe Cursor do
52
54
 
53
55
  it 'has filename and posion at end point', from_3_4: true do
54
56
  expect(extent.end.file).to eq(fixture_path("list.c"))
55
- expect(extent.end.line).to equal(11)
57
+ expect(extent.end.line).to equal(12)
56
58
  end
57
59
 
58
60
  it 'has filename and posion at end point', upto_3_3: true do
59
61
  expect(extent.end.file).to eq(fixture_path("list.c"))
60
- expect(extent.end.line).to equal(10)
62
+ expect(extent.end.line).to equal(11)
61
63
  end
62
64
  end
63
65
 
@@ -142,6 +144,110 @@ describe Cursor do
142
144
 
143
145
  end
144
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
+
145
251
  describe '#virtual_base?' do
146
252
  let(:virtual_base_cursor) { find_matching(cursor_cxx) { |child, parent|
147
253
  child.kind == :cursor_cxx_base_specifier and parent.spelling == 'B' } }
@@ -188,12 +294,33 @@ describe Cursor do
188
294
  end
189
295
  end
190
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
+
191
306
  describe '#dynamic_call?' do
192
- # TODO
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
193
314
  end
194
315
 
195
- describe '#specialized_template' do
196
- # TODO
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
197
324
  end
198
325
 
199
326
  describe '#canonical' do
@@ -224,8 +351,14 @@ describe Cursor do
224
351
  end
225
352
  end
226
353
 
227
- describe '#template_kind' do
228
- # TODO
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
229
362
  end
230
363
 
231
364
  describe '#access_specifier' do
@@ -263,6 +396,7 @@ describe Cursor do
263
396
 
264
397
  it "returns the translation unit that a cursor originated from" do
265
398
  struct.translation_unit.should be_kind_of(TranslationUnit)
399
+ struct.translation_unit.spelling.should eq(fixture_path("list.c"))
266
400
  end
267
401
  end
268
402
 
@@ -305,7 +439,7 @@ describe Cursor do
305
439
  let (:struct) { find_all(cursor_canon, :cursor_struct).at(2) }
306
440
 
307
441
  it "checks cursor is a definition" do
308
- struct.definition?.should be_true
442
+ struct.definition?.should be true
309
443
  end
310
444
  end
311
445
 
@@ -322,7 +456,7 @@ describe Cursor do
322
456
  child.kind == :cursor_function and child.spelling == 'f_variadic' } }
323
457
 
324
458
  it "checks cursor is a variadic function" do
325
- func.variadic?.should be_true
459
+ func.variadic?.should be true
326
460
  end
327
461
  end
328
462
 
@@ -372,15 +506,204 @@ describe Cursor do
372
506
  end
373
507
  end
374
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
+
375
540
  describe '#enum_decl_integer_type' do
376
- #TODO
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
377
548
  end
378
549
 
379
550
  describe '#platform_availability' do
380
- #TODO
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
381
596
  end
382
597
 
383
- describe '#get_overridden_cursors' do
598
+ describe '#objc_type_encoding' do
384
599
  #TODO
385
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
386
709
  end