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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/.travis.yml +21 -0
- data/Gemfile +4 -0
- data/README.md +74 -0
- data/Rakefile +12 -0
- data/ext/rakefile.rb +12 -0
- data/ext/teapot.rb +16 -0
- data/ffi-clang.gemspec +26 -0
- data/lib/ffi/clang.rb +54 -0
- data/lib/ffi/clang/comment.rb +278 -0
- data/lib/ffi/clang/cursor.rb +378 -0
- data/lib/ffi/clang/diagnostic.rb +113 -0
- data/lib/ffi/clang/file.rb +69 -0
- data/lib/ffi/clang/index.rb +71 -0
- data/lib/ffi/clang/lib.rb +73 -0
- data/lib/ffi/clang/lib/comment.rb +117 -0
- data/lib/ffi/clang/lib/cursor.rb +353 -0
- data/lib/ffi/clang/lib/diagnostic.rb +87 -0
- data/lib/ffi/clang/lib/file.rb +57 -0
- data/lib/ffi/clang/lib/index.rb +34 -0
- data/lib/ffi/clang/lib/source_location.rb +53 -0
- data/lib/ffi/clang/lib/source_range.rb +46 -0
- data/lib/ffi/clang/lib/string.rb +45 -0
- data/lib/ffi/clang/lib/token.rb +58 -0
- data/lib/ffi/clang/lib/translation_unit.rb +106 -0
- data/lib/ffi/clang/lib/type.rb +154 -0
- data/lib/ffi/clang/lib/utils.rb +29 -0
- data/lib/ffi/clang/source_location.rb +149 -0
- data/lib/ffi/clang/source_range.rb +61 -0
- data/lib/ffi/clang/token.rb +95 -0
- data/lib/ffi/clang/translation_unit.rb +142 -0
- data/lib/ffi/clang/type.rb +135 -0
- data/lib/ffi/clang/unsaved_file.rb +49 -0
- data/lib/ffi/clang/utils.rb +58 -0
- data/lib/ffi/clang/version.rb +26 -0
- data/spec/clang/comment_spec.rb +470 -0
- data/spec/clang/cursor_spec.rb +709 -0
- data/spec/clang/diagnostic_spec.rb +89 -0
- data/spec/clang/file_spec.rb +84 -0
- data/spec/clang/index_spec.rb +70 -0
- data/spec/clang/source_location_spec.rb +140 -0
- data/spec/clang/source_range_spec.rb +76 -0
- data/spec/clang/token_spec.rb +83 -0
- data/spec/clang/translation_unit_spec.rb +214 -0
- data/spec/clang/type_spec.rb +289 -0
- data/spec/clang/utils_spec.rb +61 -0
- data/spec/fixtures/a.c +7 -0
- data/spec/fixtures/canonical.c +5 -0
- data/spec/fixtures/docs.c +1 -0
- data/spec/fixtures/docs.cc +1 -0
- data/spec/fixtures/docs.h +54 -0
- data/spec/fixtures/list.c +11 -0
- data/spec/fixtures/location1.c +7 -0
- data/spec/fixtures/simple.c +3 -0
- data/spec/fixtures/test.cxx +62 -0
- data/spec/spec_helper.rb +64 -0
- metadata +180 -0
@@ -0,0 +1,83 @@
|
|
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 Tokens do
|
24
|
+
let(:tu) { Index.new.parse_translation_unit(fixture_path("list.c")) }
|
25
|
+
let(:cursor) { tu.cursor }
|
26
|
+
let(:range) { find_first(cursor, :cursor_struct).extent }
|
27
|
+
let(:tokens) { tu.tokenize(range) }
|
28
|
+
|
29
|
+
it "can be obtained from a translation unit" do
|
30
|
+
expect(tokens).to be_kind_of(Tokens)
|
31
|
+
expect(tokens.size).to eq(13)
|
32
|
+
expect(tokens.tokens).to be_kind_of(Array)
|
33
|
+
expect(tokens.tokens.first).to be_kind_of(Token)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "calls dispose_tokens on GC" do
|
37
|
+
expect(Lib).to receive(:dispose_tokens).at_least(:once)
|
38
|
+
expect{tokens.free}.not_to raise_error
|
39
|
+
end
|
40
|
+
|
41
|
+
it "#each" do
|
42
|
+
spy = double(stub: nil)
|
43
|
+
expect(spy).to receive(:stub).exactly(tokens.size).times
|
44
|
+
tokens.each { spy.stub }
|
45
|
+
end
|
46
|
+
|
47
|
+
it "#cursors" do
|
48
|
+
expect(tokens.cursors).to be_kind_of(Array)
|
49
|
+
expect(tokens.cursors.size).to eq(tokens.size)
|
50
|
+
expect(tokens.cursors.first).to be_kind_of(Cursor)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe Token do
|
55
|
+
let(:tu) { Index.new.parse_translation_unit(fixture_path("list.c")) }
|
56
|
+
let(:cursor) { tu.cursor }
|
57
|
+
let(:range) { find_first(cursor, :cursor_struct).extent }
|
58
|
+
let(:token) { tu.tokenize(range).first }
|
59
|
+
|
60
|
+
it "can be obtained from a translation unit" do
|
61
|
+
expect(token).to be_kind_of(Token)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "#kind" do
|
65
|
+
expect(token.kind).to be_kind_of(Symbol)
|
66
|
+
expect(token.kind).to eq(:keyword)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "#spelling" do
|
70
|
+
expect(token.spelling).to be_kind_of(String)
|
71
|
+
expect(token.spelling).to eq('struct')
|
72
|
+
end
|
73
|
+
|
74
|
+
it "#location" do
|
75
|
+
expect(token.location).to be_kind_of(SourceLocation)
|
76
|
+
expect(token.location.line).to eq(1)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "#extent" do
|
80
|
+
expect(token.extent).to be_kind_of(SourceRange)
|
81
|
+
expect(token.extent.start.line).to eq(1)
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,214 @@
|
|
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 TranslationUnit do
|
24
|
+
before :all do
|
25
|
+
FileUtils.mkdir_p TMP_DIR
|
26
|
+
end
|
27
|
+
|
28
|
+
after :all do
|
29
|
+
FileUtils.rm_rf TMP_DIR
|
30
|
+
end
|
31
|
+
|
32
|
+
let(:tu) { Index.new.parse_translation_unit fixture_path("a.c") }
|
33
|
+
|
34
|
+
it "returns a list of diagnostics" do
|
35
|
+
diags = tu.diagnostics
|
36
|
+
expect(diags).to be_kind_of(Array)
|
37
|
+
expect(diags).to_not be_empty
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns a list of diagnostics from an unsaved file" do
|
41
|
+
file = UnsavedFile.new("a.c", File.read(fixture_path("a.c")))
|
42
|
+
tu = Index.new.parse_translation_unit("a.c", nil,[file])
|
43
|
+
diags = tu.diagnostics
|
44
|
+
expect(diags).to be_kind_of(Array)
|
45
|
+
expect(diags).to_not be_empty
|
46
|
+
end
|
47
|
+
|
48
|
+
it "calls dispose_translation_unit on GC" do
|
49
|
+
expect(Lib).to receive(:dispose_translation_unit).with(tu)
|
50
|
+
expect{tu.free}.not_to raise_error
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#spelling" do
|
54
|
+
let (:spelling) { tu.spelling }
|
55
|
+
|
56
|
+
it "returns own filename" do
|
57
|
+
expect(spelling).to be_kind_of(String)
|
58
|
+
expect(spelling).to eq(fixture_path("a.c"))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#file" do
|
63
|
+
let (:file) { tu.file(fixture_path("a.c")) }
|
64
|
+
|
65
|
+
it "returns File instance" do
|
66
|
+
expect(file).to be_kind_of(FFI::Clang::File)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#location" do
|
71
|
+
let(:file) { tu.file(fixture_path("a.c")) }
|
72
|
+
let(:column) { 12 }
|
73
|
+
let(:location) { tu.location(file, 1, column) }
|
74
|
+
|
75
|
+
it "returns source location at a specific point" do
|
76
|
+
expect(location).to be_kind_of(SourceLocation)
|
77
|
+
expect(location.file).to eq(fixture_path("a.c"))
|
78
|
+
expect(location.line).to eq(1)
|
79
|
+
expect(location.column).to eq(column)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#location_offset" do
|
84
|
+
let(:file) { tu.file(fixture_path("a.c")) }
|
85
|
+
let(:offset) { 10 }
|
86
|
+
let(:location) { tu.location_offset(file, offset) }
|
87
|
+
|
88
|
+
it "returns source location at a specific offset point" do
|
89
|
+
expect(location).to be_kind_of(SourceLocation)
|
90
|
+
expect(location.file).to eq(fixture_path("a.c"))
|
91
|
+
expect(location.column).to eq(offset+1)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "#cursor" do
|
96
|
+
let(:cursor) { tu.cursor }
|
97
|
+
let(:location) { tu.location(tu.file(fixture_path("a.c")), 1, 10) }
|
98
|
+
let(:cursor_with_loc) { tu.cursor(location) }
|
99
|
+
|
100
|
+
it "returns translation unit cursor if no arguments are specified" do
|
101
|
+
expect(cursor).to be_kind_of(Cursor)
|
102
|
+
expect(cursor.kind).to eq(:cursor_translation_unit)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "returns a correspond cursor if a source location is passed" do
|
106
|
+
expect(cursor_with_loc).to be_kind_of(Cursor)
|
107
|
+
expect(cursor_with_loc.kind).to eq(:cursor_parm_decl)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "#self.default_editing_translation_unit_options" do
|
112
|
+
let (:opts) { FFI::Clang::TranslationUnit.default_editing_translation_unit_options }
|
113
|
+
it "returns hash with symbols of TranslationUnitFlags" do
|
114
|
+
expect(opts).to be_kind_of(Hash)
|
115
|
+
opts.keys.each { |key|
|
116
|
+
expect(FFI::Clang::Lib::TranslationUnitFlags.symbols).to include(key)
|
117
|
+
}
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "#default_save_options" do
|
122
|
+
let (:opts) { tu.default_save_options }
|
123
|
+
it "returns hash with symbols of SaveTranslationUnitFlags" do
|
124
|
+
expect(opts).to be_kind_of(Hash)
|
125
|
+
opts.keys.each { |key|
|
126
|
+
expect(FFI::Clang::Lib::SaveTranslationUnitFlags.symbols).to include(key)
|
127
|
+
}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "#save" do
|
132
|
+
let (:filepath) { "#{TMP_DIR}/save_translation_unit" }
|
133
|
+
let (:may_not_exist_filepath) { "#{TMP_DIR}/not_writable_directory/save_translation_unit" }
|
134
|
+
it "saves translation unit as a file" do
|
135
|
+
expect{tu.save(filepath)}.not_to raise_error
|
136
|
+
expect(FileTest.exist?(filepath)).to be_true
|
137
|
+
end
|
138
|
+
|
139
|
+
it "raises exception if save path is not writable" do
|
140
|
+
FileUtils.mkdir_p File.dirname(may_not_exist_filepath)
|
141
|
+
File.chmod(0444, File.dirname(may_not_exist_filepath))
|
142
|
+
expect{tu.save(may_not_exist_filepath)}.to raise_error
|
143
|
+
expect(FileTest.exist?(may_not_exist_filepath)).to be_false
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "#default_reparse_options" do
|
148
|
+
let (:opts) { tu.default_reparse_options }
|
149
|
+
it "returns hash with symbols of ReparseFlags" do
|
150
|
+
expect(opts).to be_kind_of(Hash)
|
151
|
+
opts.keys.each { |key|
|
152
|
+
expect(FFI::Clang::Lib::ReparseFlags.symbols).to include(key)
|
153
|
+
}
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "#reparse" do
|
158
|
+
let (:path) { "#{TMP_DIR}/reparse_tmp.c" }
|
159
|
+
before :each do
|
160
|
+
FileUtils.touch path
|
161
|
+
@reparse_tu = Index.new.parse_translation_unit(path)
|
162
|
+
end
|
163
|
+
after :each do
|
164
|
+
FileUtils.rm path, :force => true
|
165
|
+
end
|
166
|
+
|
167
|
+
it "recretes translation unit" do
|
168
|
+
File::open(path, "w+") { |io|
|
169
|
+
io.write("int a;")
|
170
|
+
}
|
171
|
+
expect(find_first(@reparse_tu.cursor, :cursor_variable)).to be_false
|
172
|
+
expect{@reparse_tu.reparse}.not_to raise_error
|
173
|
+
expect(find_first(@reparse_tu.cursor, :cursor_variable).spelling).to eq("a")
|
174
|
+
end
|
175
|
+
|
176
|
+
it "raises exception if the file is not found when reparsing" do
|
177
|
+
FileUtils.rm path, :force => true
|
178
|
+
expect{@reparse_tu.reparse}.to raise_error
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe "#resource_usage" do
|
183
|
+
let (:ru) { tu.resource_usage }
|
184
|
+
it "returns ResourceUsage instance that represents memory usage of TU" do
|
185
|
+
expect(ru).to be_kind_of(TranslationUnit::ResourceUsage)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe TranslationUnit::ResourceUsage do
|
190
|
+
let (:ru) { tu.resource_usage }
|
191
|
+
describe "#entries" do
|
192
|
+
let (:entries) { tu.resource_usage.entries }
|
193
|
+
it "returns array of CXTUResourceUsageEntry" do
|
194
|
+
expect(entries).to be_kind_of(Array)
|
195
|
+
expect(entries.first).to be_kind_of(Lib::CXTUResourceUsageEntry)
|
196
|
+
expect(entries.first[:kind]).to be_kind_of(Symbol)
|
197
|
+
expect(entries.first[:amount]).to be_kind_of(Integer)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "#self.name" do
|
202
|
+
let(:name) { FFI::Clang::TranslationUnit::ResourceUsage.name(:ast) }
|
203
|
+
it "returns the name of the memory category" do
|
204
|
+
expect(name).to be_kind_of(String)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
describe "#self.release" do
|
209
|
+
it "releases data by calling 'clang_disposeCXTUResourceUsage'" do
|
210
|
+
expect{ ru.free }.not_to raise_error
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,289 @@
|
|
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
|
+
require 'spec_helper'
|
24
|
+
|
25
|
+
describe Type do
|
26
|
+
let(:cursor) { Index.new.parse_translation_unit(fixture_path("a.c")).cursor }
|
27
|
+
let(:cursor_cxx) { Index.new.parse_translation_unit(fixture_path("test.cxx")).cursor }
|
28
|
+
let(:cursor_list) { Index.new.parse_translation_unit(fixture_path("list.c")).cursor }
|
29
|
+
let(:type) { find_first(cursor, :cursor_function).type }
|
30
|
+
|
31
|
+
it "can tell us about the main function", from_3_3: true do
|
32
|
+
type.variadic?.should equal(false)
|
33
|
+
|
34
|
+
type.num_arg_types.should equal(2)
|
35
|
+
type.arg_type(0).spelling.should eq("int")
|
36
|
+
type.arg_type(1).spelling.should eq("const char *")
|
37
|
+
type.result_type.spelling.should eq("int")
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#kind_spelling' do
|
41
|
+
let(:kind_spelling_type) { find_matching(cursor_cxx) { |child, parent|
|
42
|
+
child.kind == :cursor_typedef_decl and child.spelling == 'const_int_ptr'}.type }
|
43
|
+
|
44
|
+
it 'returns type kind name with string' do
|
45
|
+
kind_spelling_type.kind_spelling.should eq 'Typedef'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#canonical' do
|
50
|
+
let(:canonical_type) { find_matching(cursor_cxx) { |child, parent|
|
51
|
+
child.kind == :cursor_typedef_decl and child.spelling == 'const_int_ptr'
|
52
|
+
}.type.canonical }
|
53
|
+
|
54
|
+
it 'extracts typedef', upto_3_2: true do
|
55
|
+
expect(canonical_type).to be_kind_of(Type)
|
56
|
+
expect(canonical_type.kind).to be(:type_pointer)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'extracts typedef', from_3_3: true do
|
60
|
+
expect(canonical_type).to be_kind_of(Type)
|
61
|
+
expect(canonical_type.kind).to be(:type_pointer)
|
62
|
+
expect(canonical_type.spelling).to eq('const int *')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#pointee' do
|
67
|
+
let(:pointee_type) { find_matching(cursor_cxx) { |child, parent|
|
68
|
+
child.kind == :cursor_typedef_decl and child.spelling == 'const_int_ptr'
|
69
|
+
}.type.canonical.pointee }
|
70
|
+
|
71
|
+
it 'gets pointee type of pointer, C++ reference', upto_3_2: true do
|
72
|
+
expect(pointee_type).to be_kind_of(Type)
|
73
|
+
expect(pointee_type.kind).to be(:type_int)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'gets pointee type of pointer, C++ reference', from_3_3: true do
|
77
|
+
expect(pointee_type).to be_kind_of(Type)
|
78
|
+
expect(pointee_type.kind).to be(:type_int)
|
79
|
+
expect(pointee_type.spelling).to eq('const int')
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe '#const_qualified?' do
|
84
|
+
let(:pointer_type) { find_matching(cursor_cxx) { |child, parent|
|
85
|
+
child.kind == :cursor_typedef_decl and child.spelling == 'const_int_ptr'
|
86
|
+
}.type.canonical }
|
87
|
+
|
88
|
+
let(:pointee_type) { find_matching(cursor_cxx) { |child, parent|
|
89
|
+
child.kind == :cursor_typedef_decl and child.spelling == 'const_int_ptr'
|
90
|
+
}.type.canonical.pointee }
|
91
|
+
|
92
|
+
it 'checks type is const qualified' do
|
93
|
+
pointee_type.const_qualified?.should equal true
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'cannot check whether pointee type is const qualified' do
|
97
|
+
pointer_type.const_qualified?.should equal false
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe '#volatile_qualified?' do
|
102
|
+
let(:pointer_type) { find_matching(cursor) { |child, parent|
|
103
|
+
child.kind == :cursor_variable and child.spelling == 'volatile_int_ptr'
|
104
|
+
}.type }
|
105
|
+
|
106
|
+
it 'checks type is volatile qualified' do
|
107
|
+
expect(pointer_type.volatile_qualified?).to be_true
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '#restrict_qualified?' do
|
112
|
+
let(:pointer_type) { find_matching(cursor) { |child, parent|
|
113
|
+
child.kind == :cursor_variable and child.spelling == 'restrict_int_ptr'
|
114
|
+
}.type }
|
115
|
+
|
116
|
+
it 'checks type is restrict qualified' do
|
117
|
+
expect(pointer_type.restrict_qualified?).to be_true
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe '#element_type' do
|
122
|
+
let(:array_type) { find_matching(cursor_cxx) { |child, parent|
|
123
|
+
child.kind == :cursor_variable and child.spelling == 'int_array'
|
124
|
+
}.type }
|
125
|
+
|
126
|
+
it 'returns the element type of the array type' do
|
127
|
+
expect(array_type.element_type).to be_kind_of(Type)
|
128
|
+
expect(array_type.element_type.kind).to eq(:type_int)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe '#num_elements' do
|
133
|
+
let(:array_type) { find_matching(cursor_cxx) { |child, parent|
|
134
|
+
child.kind == :cursor_variable and child.spelling == 'int_array'
|
135
|
+
}.type }
|
136
|
+
|
137
|
+
it 'returns the number of elements of the array' do
|
138
|
+
expect(array_type.num_elements).to eq(8)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe '#array_element_type' do
|
143
|
+
let(:array_type) { find_matching(cursor_cxx) { |child, parent|
|
144
|
+
child.kind == :cursor_variable and child.spelling == 'int_array'
|
145
|
+
}.type }
|
146
|
+
|
147
|
+
it 'returns the array element type of the array type' do
|
148
|
+
expect(array_type.array_element_type).to be_kind_of(Type)
|
149
|
+
expect(array_type.array_element_type.kind).to eq(:type_int)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe '#array_size' do
|
154
|
+
let(:array_type) { find_matching(cursor_cxx) { |child, parent|
|
155
|
+
child.kind == :cursor_variable and child.spelling == 'int_array'
|
156
|
+
}.type }
|
157
|
+
|
158
|
+
it 'returns the number of elements of the array' do
|
159
|
+
expect(array_type.array_size).to eq(8)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe '#alignof', from_3_3: true do
|
164
|
+
let(:array_type) { find_matching(cursor_cxx) { |child, parent|
|
165
|
+
child.kind == :cursor_variable and child.spelling == 'int_array'
|
166
|
+
}.type }
|
167
|
+
|
168
|
+
it 'returns the alignment of the type in bytes' do
|
169
|
+
expect(array_type.alignof).to be_kind_of(Integer)
|
170
|
+
expect(array_type.alignof).to be > 0
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe '#sizeof', from_3_3: true do
|
175
|
+
let(:array_type) { find_matching(cursor_cxx) { |child, parent|
|
176
|
+
child.kind == :cursor_variable and child.spelling == 'int_array'
|
177
|
+
}.type }
|
178
|
+
|
179
|
+
it 'returns the size of the type in bytes' do
|
180
|
+
expect(array_type.sizeof).to be_kind_of(Integer)
|
181
|
+
expect(array_type.sizeof).to be(32)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe '#offsetof', from_3_3: true do
|
186
|
+
let(:struct) { find_matching(cursor_list) { |child, parent|
|
187
|
+
child.kind == :cursor_struct and child.spelling == 'List'
|
188
|
+
}.type }
|
189
|
+
|
190
|
+
it 'returns the offset of a field in a record of the type in bits' do
|
191
|
+
expect(struct.offsetof('Next')).to be_kind_of(Integer)
|
192
|
+
expect(struct.offsetof('Next')).to be(64)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe '#ref_qualifier', from_3_4: true do
|
197
|
+
let(:lvalue) { find_matching(cursor_cxx) { |child, parent|
|
198
|
+
child.kind == :cursor_cxx_method and child.spelling == 'func_lvalue_ref'
|
199
|
+
}.type }
|
200
|
+
let(:rvalue) { find_matching(cursor_cxx) { |child, parent|
|
201
|
+
child.kind == :cursor_cxx_method and child.spelling == 'func_rvalue_ref'
|
202
|
+
}.type }
|
203
|
+
let(:none) { find_matching(cursor_cxx) { |child, parent|
|
204
|
+
child.kind == :cursor_cxx_method and child.spelling == 'func_none'
|
205
|
+
}.type }
|
206
|
+
|
207
|
+
it 'returns :ref_qualifier_lvalue the type is ref-qualified with lvalue' do
|
208
|
+
expect(lvalue.ref_qualifier).to be(:ref_qualifier_lvalue)
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'returns :ref_qualifier_rvalue the type is ref-qualified with rvalue' do
|
212
|
+
expect(rvalue.ref_qualifier).to be(:ref_qualifier_rvalue)
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'returns :ref_qualifier_none the type is not ref-qualified' do
|
216
|
+
expect(none.ref_qualifier).to be(:ref_qualifier_none)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
describe '#pod?' do
|
221
|
+
let(:struct) { find_matching(cursor_list) { |child, parent|
|
222
|
+
child.kind == :cursor_struct and child.spelling == 'List'
|
223
|
+
}.type }
|
224
|
+
|
225
|
+
it 'returns true if the type is a POD type' do
|
226
|
+
expect(struct.pod?).to be_true
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
describe '#class_type', from_3_4: true do
|
231
|
+
let(:member_pointer) { find_matching(cursor_cxx) { |child, parent|
|
232
|
+
child.kind == :cursor_variable and child.spelling == 'member_pointer'
|
233
|
+
}.type }
|
234
|
+
|
235
|
+
it 'returns the class type of the member pointer type' do
|
236
|
+
expect(member_pointer.class_type).to be_kind_of(Type)
|
237
|
+
expect(member_pointer.class_type.kind).to be(:type_record)
|
238
|
+
expect(member_pointer.class_type.spelling).to eq('A')
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
describe '#declaration' do
|
243
|
+
let(:struct_ref) { find_matching(cursor_cxx) { |child, parent|
|
244
|
+
child.kind == :cursor_type_ref and child.spelling == 'struct D'
|
245
|
+
}.type }
|
246
|
+
let(:struct_decl) { find_matching(cursor_cxx) { |child, parent|
|
247
|
+
child.kind == :cursor_struct and child.spelling == 'D'
|
248
|
+
} }
|
249
|
+
let(:no_decl) { find_first(cursor_cxx, :cursor_cxx_method).type }
|
250
|
+
|
251
|
+
it 'returns the class type of the member pointer type' do
|
252
|
+
expect(struct_ref.declaration).to be_kind_of(Cursor)
|
253
|
+
expect(struct_ref.declaration.kind).to be(:cursor_struct)
|
254
|
+
expect(struct_ref.declaration).to eq(struct_decl)
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'returns :cursor_no_decl_found if the type has no declaration' do
|
258
|
+
expect(no_decl.declaration).to be_kind_of(Cursor)
|
259
|
+
expect(no_decl.declaration.kind).to be(:cursor_no_decl_found)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
describe '#calling_conv' do
|
264
|
+
let(:function) { find_matching(cursor_cxx) { |child, parent|
|
265
|
+
child.kind == :cursor_function and child.spelling == 'f_variadic'
|
266
|
+
}.type }
|
267
|
+
|
268
|
+
it 'returns the calling convention associated with the function type', from_3_4: true do
|
269
|
+
expect(function.calling_conv).to be(:calling_conv_c)
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'returns the calling convention associated with the function type', upto_3_3: true do
|
273
|
+
expect(function.calling_conv).to be(:calling_conv_default)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
describe '#==' do
|
278
|
+
let(:type_decl) { find_matching(cursor_cxx) { |child, parent|
|
279
|
+
child.kind == :cursor_field_decl and child.spelling == 'int_member_a'
|
280
|
+
}.type }
|
281
|
+
let(:type_ref) { find_matching(cursor_cxx) { |child, parent|
|
282
|
+
child.kind == :cursor_decl_ref_expr and child.spelling == 'int_member_a'
|
283
|
+
}.type }
|
284
|
+
|
285
|
+
it 'checks if two types represent the same type' do
|
286
|
+
expect(type_decl == type_ref).to be_true
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|