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,378 @@
1
+ # Copyright, 2010-2012 by Jari Bakken.
2
+ # Copyright, 2013, by Samuel G. D. Williams. <http://www.codeotaku.com>
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
+ require 'ffi/clang/lib/cursor'
24
+ require 'ffi/clang/source_location'
25
+ require 'ffi/clang/comment'
26
+ require 'ffi/clang/type'
27
+
28
+ module FFI
29
+ module Clang
30
+ class Cursor
31
+ attr_reader :cursor
32
+ attr_reader :translation_unit
33
+
34
+ def self.null_cursor
35
+ Cursor.new Lib.get_null_cursor, nil
36
+ end
37
+
38
+ # this function is categorized as "Debugging facilities"
39
+ def self.kind_spelling(kind)
40
+ Lib.extract_string Lib.get_cursor_kind_spelling(kind)
41
+ end
42
+
43
+ def initialize(cxcursor, translation_unit)
44
+ @cursor = cxcursor
45
+ @translation_unit = translation_unit
46
+ end
47
+
48
+ def null?
49
+ Lib.cursor_is_null(@cursor) != 0
50
+ end
51
+
52
+ def raw_comment_text
53
+ Lib.extract_string Lib.cursor_get_raw_comment_text(@cursor)
54
+ end
55
+
56
+ def comment
57
+ Comment.build_from Lib.cursor_get_parsed_comment(@cursor)
58
+ end
59
+
60
+ def comment_range
61
+ SourceRange.new(Lib.cursor_get_comment_range(@cursor))
62
+ end
63
+
64
+ def declaration?
65
+ Lib.is_declaration(kind) != 0
66
+ end
67
+
68
+ def reference?
69
+ Lib.is_reference(kind) != 0
70
+ end
71
+
72
+ def expression?
73
+ Lib.is_expression(kind) != 0
74
+ end
75
+
76
+ def statement?
77
+ Lib.is_statement(kind) != 0
78
+ end
79
+
80
+ def attribute?
81
+ Lib.is_attribute(kind) != 0
82
+ end
83
+
84
+ def public?
85
+ Lib.cxx_get_access_specifier(@cursor) == :public
86
+ end
87
+
88
+ def private?
89
+ Lib.cxx_get_access_specifier(@cursor) == :private
90
+ end
91
+
92
+ def protected?
93
+ Lib.cxx_get_access_specifier(@cursor) == :protected
94
+ end
95
+
96
+ def invalid?
97
+ Lib.is_invalid(kind) != 0
98
+ end
99
+
100
+ def translation_unit?
101
+ Lib.is_translation_unit(kind) != 0
102
+ end
103
+
104
+ def preprocessing?
105
+ Lib.is_preprocessing(kind) != 0
106
+ end
107
+
108
+ def unexposed?
109
+ Lib.is_unexposed(kind) != 0
110
+ end
111
+
112
+ def location
113
+ ExpansionLocation.new(Lib.get_cursor_location(@cursor))
114
+ end
115
+
116
+ def extent
117
+ SourceRange.new(Lib.get_cursor_extent(@cursor))
118
+ end
119
+
120
+ def display_name
121
+ Lib.extract_string Lib.get_cursor_display_name(@cursor)
122
+ end
123
+
124
+ def spelling
125
+ Lib.extract_string Lib.get_cursor_spelling(@cursor)
126
+ end
127
+
128
+ def usr
129
+ Lib.extract_string Lib.get_cursor_usr(@cursor)
130
+ end
131
+
132
+ def kind
133
+ @cursor[:kind]
134
+ end
135
+
136
+ def kind_spelling
137
+ Cursor.kind_spelling @cursor[:kind]
138
+ end
139
+
140
+ def type
141
+ Type.new Lib.get_cursor_type(@cursor), @translation_unit
142
+ end
143
+
144
+ def result_type
145
+ Type.new Lib.get_cursor_result_type(@cursor), @translation_unit
146
+ end
147
+
148
+ def underlying_type
149
+ Type.new Lib.get_typedef_decl_underlying_type(@cursor), @translation_unit
150
+ end
151
+
152
+ def enum_decl_integer_type
153
+ Type.new Lib.get_enum_decl_integer_type(@cursor), @translation_unit
154
+ end
155
+
156
+ def virtual_base?
157
+ Lib.is_virtual_base(@cursor) != 0
158
+ end
159
+
160
+ def dynamic_call?
161
+ Lib.is_dynamic_call(@cursor) != 0
162
+ end
163
+
164
+ def variadic?
165
+ Lib.is_variadic(@cursor) != 0
166
+ end
167
+
168
+ def definition?
169
+ Lib.is_definition(@cursor) != 0
170
+ end
171
+
172
+ def static?
173
+ Lib.cxx_method_is_static(@cursor) != 0
174
+ end
175
+
176
+ def virtual?
177
+ Lib.cxx_method_is_virtual(@cursor) != 0
178
+ end
179
+
180
+ def pure_virtual?
181
+ Lib.cxx_method_is_pure_virtual(@cursor) != 0
182
+ end
183
+
184
+ def enum_value
185
+ Lib.get_enum_value @cursor
186
+ end
187
+
188
+ def enum_unsigned_value
189
+ Lib.get_enum_unsigned_value @cursor
190
+ end
191
+
192
+ def specialized_template
193
+ Cursor.new Lib.get_specialized_cursor_template(@cursor), @translation_unit
194
+ end
195
+
196
+ def canonical
197
+ Cursor.new Lib.get_canonical_cursor(@cursor), @translation_unit
198
+ end
199
+
200
+ def definition
201
+ Cursor.new Lib.get_cursor_definition(@cursor), @translation_unit
202
+ end
203
+
204
+ def referenced
205
+ Cursor.new Lib.get_cursor_referenced(@cursor), @translation_unit
206
+ end
207
+
208
+ def semantic_parent
209
+ Cursor.new Lib.get_cursor_semantic_parent(@cursor), @translation_unit
210
+ end
211
+
212
+ def lexical_parent
213
+ Cursor.new Lib.get_cursor_lexical_parent(@cursor), @translation_unit
214
+ end
215
+
216
+ def template_kind
217
+ Lib.get_template_cursor_kind @cursor
218
+ end
219
+
220
+ def access_specifier
221
+ Lib.get_cxx_access_specifier @cursor
222
+ end
223
+
224
+ def language
225
+ Lib.get_language @cursor
226
+ end
227
+
228
+ def translation_unit
229
+ @translation_unit
230
+ end
231
+
232
+ def visit_children(&block)
233
+ adapter = Proc.new do |cxcursor, parent_cursor, unused|
234
+ block.call Cursor.new(cxcursor, @translation_unit), Cursor.new(parent_cursor, @translation_unit)
235
+ end
236
+
237
+ Lib.visit_children(@cursor, adapter, nil)
238
+ end
239
+
240
+ def linkage
241
+ Lib.get_cursor_linkage(@cursor)
242
+ end
243
+
244
+ def availability
245
+ Lib.get_cursor_availability(@cursor)
246
+ end
247
+
248
+ def included_file
249
+ File.new Lib.get_included_file(@cursor), @translation_unit
250
+ end
251
+
252
+ def platform_availability(max_availability_size = 4)
253
+ availability_ptr = FFI::MemoryPointer.new(Lib::CXPlatformAvailability, max_availability_size)
254
+ always_deprecated_ptr = FFI::MemoryPointer.new :int
255
+ always_unavailable_ptr = FFI::MemoryPointer.new :int
256
+ deprecated_message_ptr = FFI::MemoryPointer.new Lib::CXString
257
+ unavailable_message_ptr = FFI::MemoryPointer.new Lib::CXString
258
+
259
+ actual_availability_size = Lib.get_cursor_platform_availability(
260
+ @cursor,
261
+ always_deprecated_ptr, deprecated_message_ptr,
262
+ always_unavailable_ptr, unavailable_message_ptr,
263
+ availability_ptr, max_availability_size)
264
+
265
+ availability = []
266
+ cur_ptr = availability_ptr
267
+ [actual_availability_size, max_availability_size].min.times {
268
+ availability << PlatformAvailability.new(cur_ptr)
269
+ cur_ptr += Lib::CXPlatformAvailability.size
270
+ }
271
+
272
+ # return as Hash
273
+ {
274
+ always_deprecated: always_deprecated_ptr.get_int(0),
275
+ always_unavailable: always_unavailable_ptr.get_int(0),
276
+ deprecated_message: Lib.extract_string(Lib::CXString.new(deprecated_message_ptr)),
277
+ unavailable_message: Lib.extract_string(Lib::CXString.new(unavailable_message_ptr)),
278
+ availability: availability
279
+ }
280
+ end
281
+
282
+ def overriddens
283
+ cursor_ptr = FFI::MemoryPointer.new :pointer
284
+ num_ptr = FFI::MemoryPointer.new :uint
285
+ Lib.get_overridden_cursors(@cursor, cursor_ptr, num_ptr)
286
+ num = num_ptr.get_uint(0)
287
+ cur_ptr = cursor_ptr.get_pointer(0)
288
+
289
+ overriddens = []
290
+ num.times {
291
+ overriddens << Cursor.new(cur_ptr, @translation_unit)
292
+ cur_ptr += Lib::CXCursor.size
293
+ }
294
+ Lib.dispose_overridden_cursors(cursor_ptr.get_pointer(0)) if num != 0
295
+ overriddens
296
+ end
297
+
298
+ def hash
299
+ Lib.get_cursor_hash(@cursor)
300
+ end
301
+
302
+ def bitfield?
303
+ Lib.is_bit_field(@cursor) != 0
304
+ end
305
+
306
+ def bitwidth
307
+ Lib.get_field_decl_bit_width(@cursor)
308
+ end
309
+
310
+ def overloaded_decl(i)
311
+ Cursor.new Lib.get_overloaded_decl(@cursor, i), @translation_unit
312
+ end
313
+
314
+ def num_overloaded_decls
315
+ Lib.get_num_overloaded_decls(@cursor)
316
+ end
317
+
318
+ def objc_type_encoding
319
+ Lib.extract_string Lib.get_decl_objc_type_encoding(@cursor)
320
+ end
321
+
322
+ def argument(i)
323
+ Cursor.new Lib.cursor_get_argument(@cursor, i), @translation_unit
324
+ end
325
+
326
+ def num_arguments
327
+ Lib.cursor_get_num_arguments(@cursor)
328
+ end
329
+
330
+ attr_reader :cursor
331
+
332
+ def ==(other)
333
+ Lib.are_equal(@cursor, other.cursor) != 0
334
+ end
335
+
336
+ class PlatformAvailability < AutoPointer
337
+ def initialize(memory_pointer)
338
+ pointer = FFI::Pointer.new(memory_pointer)
339
+ super(pointer)
340
+
341
+ # I'm not sure this is safe.
342
+ # Keep a reference to CXPlatformAvailability itself allocated by MemoryPointer.
343
+ @memory_pointer = memory_pointer
344
+ @platform_availability = Lib::CXPlatformAvailability.new(memory_pointer)
345
+ end
346
+
347
+ def self.release(pointer)
348
+ # Memory allocated by get_cursor_platform_availability is managed by AutoPointer.
349
+ Lib.dispose_platform_availability(Lib::CXPlatformAvailability.new(pointer))
350
+ end
351
+
352
+ def platform
353
+ Lib.get_string @platform_availability[:platform]
354
+ end
355
+
356
+ def introduced
357
+ @platform_availability[:introduced]
358
+ end
359
+
360
+ def deprecated
361
+ @platform_availability[:deprecated]
362
+ end
363
+
364
+ def obsoleted
365
+ @platform_availability[:obsoleted]
366
+ end
367
+
368
+ def unavailable
369
+ @platform_availability[:unavailable] != 0
370
+ end
371
+
372
+ def message
373
+ Lib.get_string @platform_availability[:message]
374
+ end
375
+ end
376
+ end
377
+ end
378
+ end
@@ -0,0 +1,113 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright, 2010-2012 by Jari Bakken.
3
+ # Copyright, 2013, by Samuel G. D. Williams. <http://www.codeotaku.com>
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
+ require 'ffi/clang/lib/diagnostic'
24
+ require 'ffi/clang/source_range'
25
+
26
+ module FFI
27
+ module Clang
28
+ class Diagnostic < AutoPointer
29
+ def self.default_display_opts
30
+ Lib.opts_from Lib::DiagnosticDisplayOptions, Lib.default_diagnostic_display_options
31
+ end
32
+
33
+ def initialize(translation_unit, pointer)
34
+ super pointer
35
+
36
+ @translation_unit = translation_unit
37
+ end
38
+
39
+ def self.release(pointer)
40
+ Lib.dispose_diagnostic(pointer)
41
+ end
42
+
43
+ def format(opts = {})
44
+ cxstring = Lib.format_diagnostic(self, display_opts(opts))
45
+ Lib.extract_string cxstring
46
+ end
47
+
48
+ def severity
49
+ Lib.get_diagnostic_severity self
50
+ end
51
+
52
+ def spelling
53
+ Lib.get_string Lib.get_diagnostic_spelling(self)
54
+ end
55
+
56
+ def location
57
+ sl = Lib.get_diagnostic_location(self)
58
+ ExpansionLocation.new sl
59
+ end
60
+
61
+ def fixits
62
+ n = Lib.get_diagnostic_num_fix_its(self)
63
+ n.times.map { |i|
64
+ ptr = MemoryPointer.new Lib::CXSourceRange
65
+ replace_text = Lib.extract_string(Lib.get_diagnostic_fix_it(self, i, ptr))
66
+ {text: replace_text, range: SourceRange.new(ptr)}
67
+ }
68
+ end
69
+
70
+ def ranges
71
+ n = Lib.get_diagnostic_num_ranges(self)
72
+
73
+ n.times.map {|i| SourceRange.new Lib.get_diagnostic_range(self, i)}
74
+ end
75
+
76
+ def children
77
+ diagnostic_set = Lib.get_child_diagnostics(self)
78
+ num_diagnostics = Lib.get_num_diagnostics_in_set(diagnostic_set)
79
+ num_diagnostics.times.map { |i|
80
+ Diagnostic.new(@translation_unit, Lib.get_diagnostic_in_set(diagnostic_set, i))
81
+ }
82
+ end
83
+
84
+ def enable_option
85
+ Lib.extract_string Lib.get_diagnostic_option(self, nil)
86
+ end
87
+
88
+ def disable_option
89
+ ptr = MemoryPointer.new Lib::CXString
90
+ Lib.get_diagnostic_option(self, ptr)
91
+ Lib.extract_string ptr
92
+ end
93
+
94
+ def category
95
+ Lib.extract_string Lib.get_diagnostic_category_text(self)
96
+ end
97
+
98
+ def category_id
99
+ Lib.get_diagnostic_category(self)
100
+ end
101
+
102
+ private
103
+
104
+ def display_opts(opts)
105
+ if opts.empty?
106
+ Lib.default_diagnostic_display_options
107
+ else
108
+ Lib.bitmask_from Lib::DiagnosticDisplayOptions, opts
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end