ghazel-ffi-clang 0.2.0.1

Sign up to get free protection for your applications and to get access to all the features.
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