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,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe Diagnostic do
4
+ let(:diagnostics) { Index.new.parse_translation_unit(fixture_path("list.c")).diagnostics }
5
+ let(:diagnostic) { diagnostics.first }
6
+
7
+ it "returns a string representation of the diagnostic" do
8
+ str = diagnostic.format
9
+ str.should be_kind_of(String)
10
+ str.should =~ /does not match previous/
11
+ end
12
+
13
+ it "returns a string representation according to the given opts" do
14
+ diagnostic.format(:source_location => true).should include("list.c:5")
15
+ end
16
+
17
+ it "returns the text of the diagnostic" do
18
+ diagnostic.spelling.should be_kind_of(String)
19
+ end
20
+
21
+ it "returns the severity of the diagnostic" do
22
+ diagnostic.severity.should == :error
23
+ end
24
+
25
+ it "returns the ranges of the diagnostic" do
26
+ rs = diagnostics[1].ranges
27
+ rs.should be_kind_of(Array)
28
+ rs.should_not be_empty
29
+ rs.first.should be_kind_of(SourceRange)
30
+ end
31
+
32
+ it "calls dispose_diagnostic on GC" do
33
+ expect(Lib).to receive(:dispose_diagnostic).with(diagnostic).at_least(:once)
34
+ expect{diagnostic.free}.not_to raise_error
35
+ end
36
+
37
+ context "#self.default_display_opts" do
38
+ it "returns the set of display options" do
39
+ expect(FFI::Clang::Diagnostic.default_display_opts).to be_kind_of(Hash)
40
+ expect(FFI::Clang::Diagnostic.default_display_opts.keys.map(&:class).uniq).to eq([Symbol])
41
+ expect(FFI::Clang::Diagnostic.default_display_opts.values.uniq).to eq([true])
42
+ end
43
+ end
44
+
45
+ context "#fixits" do
46
+ it "returns the replacement information by Array of Hash" do
47
+ expect(diagnostic.fixits).to be_kind_of(Array)
48
+ expect(diagnostic.fixits.first).to be_kind_of(Hash)
49
+ expect(diagnostic.fixits.first[:text]).to eq('struct')
50
+ expect(diagnostic.fixits.first[:range]).to be_kind_of(SourceRange)
51
+ end
52
+ end
53
+
54
+ context "#children" do
55
+ it "returns child diagnostics by Array" do
56
+ expect(diagnostic.children).to be_kind_of(Array)
57
+ expect(diagnostic.children.first).to be_kind_of(Diagnostic)
58
+ expect(diagnostic.children.first.severity).to eq(:note)
59
+ end
60
+ end
61
+
62
+ context "#enable_option" do
63
+ it "returns the name of the command-line option that enabled this diagnostic" do
64
+ expect(diagnostics[3].enable_option).to be_kind_of(String)
65
+ expect(diagnostics[3].enable_option).to eq('-Wempty-body')
66
+ end
67
+ end
68
+
69
+ context "#disable_option" do
70
+ it "returns the name of the command-line option that disables this diagnostic" do
71
+ expect(diagnostics[3].disable_option).to be_kind_of(String)
72
+ expect(diagnostics[3].disable_option).to eq('-Wno-empty-body')
73
+ end
74
+ end
75
+
76
+ context "#category" do
77
+ it "returns the diagnostic category text" do
78
+ expect(diagnostic.category).to be_kind_of(String)
79
+ expect(diagnostic.category).to eq('Semantic Issue')
80
+ end
81
+ end
82
+
83
+ context "#category_id" do
84
+ it "returns the category number" do
85
+ expect(diagnostic.category_id).to be_kind_of(Integer)
86
+ expect(diagnostic.category_id).to eq(2)
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,84 @@
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 File do
24
+ let(:file_list) { Index.new.parse_translation_unit(fixture_path("list.c")).file(fixture_path("list.c")) }
25
+ let(:file_docs) { Index.new.parse_translation_unit(fixture_path("docs.c")).file(fixture_path("docs.h")) }
26
+
27
+ it "can be obtained from a translation unit" do
28
+ expect(file_list).to be_kind_of(FFI::Clang::File)
29
+ end
30
+
31
+ describe "#name" do
32
+ let(:name) { file_list.name }
33
+
34
+ it 'returns its file name' do
35
+ expect(name).to be_kind_of(String)
36
+ expect(name).to eq(fixture_path("list.c"))
37
+ end
38
+ end
39
+
40
+ describe "#to_s" do
41
+ let(:name) { file_list.to_s }
42
+
43
+ it 'returns its file name' do
44
+ expect(name).to be_kind_of(String)
45
+ expect(name).to eq(fixture_path("list.c"))
46
+ end
47
+ end
48
+
49
+ describe "#time" do
50
+ let(:time) { file_list.time }
51
+
52
+ it 'returns file time' do
53
+ expect(time).to be_kind_of(Time)
54
+ end
55
+ end
56
+
57
+ describe "#include_guarded?" do
58
+ it 'returns false if included file is notguarded' do
59
+ expect(file_list.include_guarded?).to be_false
60
+ end
61
+
62
+ it 'returns true if included file is guarded' do
63
+ expect(file_docs.include_guarded?).to be_true
64
+ end
65
+ end
66
+
67
+ describe "#device", from_3_3: true do
68
+ it 'returns device from CXFileUniqueID' do
69
+ expect(file_list.device).to be_kind_of(Integer)
70
+ end
71
+ end
72
+
73
+ describe "#inode", from_3_3: true do
74
+ it 'returns inode from CXFileUniqueID' do
75
+ expect(file_list.inode).to be_kind_of(Integer)
76
+ end
77
+ end
78
+
79
+ describe "#modification", from_3_3: true do
80
+ it 'returns modification time as Time from CXFileUniqueID' do
81
+ expect(file_list.modification).to be_kind_of(Time)
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,70 @@
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 Index 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(:index) { Index.new }
33
+
34
+ it "calls dispose_index_debug_unit on GC" do
35
+ expect(Lib).to receive(:dispose_index).with(index).at_least(:once)
36
+ expect{index.free}.not_to raise_error
37
+ end
38
+
39
+ describe '#parse_translation_unit' do
40
+ it "can parse a source file" do
41
+ tu = index.parse_translation_unit fixture_path("a.c")
42
+ expect(tu).to be_kind_of(TranslationUnit)
43
+ end
44
+
45
+ it "raises error when file is not found" do
46
+ expect { index.parse_translation_unit fixture_path("xxxxxxxxx.c") }.to raise_error
47
+ end
48
+
49
+ it "can handle command line options" do
50
+ expect{index.parse_translation_unit(fixture_path("a.c"), ["-std=c++11"])}.not_to raise_error
51
+ end
52
+ end
53
+
54
+ describe '#create_translation_unit' do
55
+ before :all do
56
+ system("clang -c #{fixture_path('simple.c')} -emit-ast -o #{TMP_DIR}/simple.ast")
57
+ end
58
+
59
+ it "can create translation unit from a ast file" do
60
+ expect(FileTest.exist?("#{TMP_DIR}/simple.ast")).to be_true
61
+ tu = index.create_translation_unit "#{TMP_DIR}/simple.ast"
62
+ expect(tu).to be_kind_of(TranslationUnit)
63
+ end
64
+
65
+ it "raises error when file is not found" do
66
+ expect(FileTest.exist?('not_found.ast')).to be_false
67
+ expect { index.create_translation_unit 'not_found.ast' }.to raise_error
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,140 @@
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 SourceLocation do
27
+ let(:tu) { Index.new.parse_translation_unit(fixture_path("list.c")) }
28
+ let(:tu_location) { tu.cursor.location }
29
+ let(:diagnostic_location) { tu.diagnostics.first.location }
30
+ let(:loc1_tu) { Index.new.parse_translation_unit(fixture_path("location1.c")) }
31
+ let(:loc1_cursor) { find_first(loc1_tu.cursor, :cursor_function) }
32
+ let(:docs_cursor) { Index.new.parse_translation_unit(fixture_path("docs.c")).cursor }
33
+
34
+ it "should have a nil File if the SourceLocation is for a Translation Unit" do
35
+ expect(tu_location.file).to be_nil
36
+ end
37
+
38
+ it "should provide a File, line and column for a Diagnostic" do
39
+ expect(diagnostic_location.file).to eq(fixture_path("list.c"))
40
+ expect(diagnostic_location.line).to equal(5)
41
+ expect(diagnostic_location.column).to equal(9)
42
+ end
43
+
44
+ it "should be ExpansionLocation" do
45
+ expect(tu_location).to be_kind_of(SourceLocation)
46
+ expect(tu_location).to be_kind_of(ExpansionLocation)
47
+ end
48
+
49
+ describe "Null Location" do
50
+ let(:null_location) { SourceLocation.null_location }
51
+ it "can be a null location" do
52
+ expect(null_location).to be_kind_of(SourceLocation)
53
+ expect(null_location.file).to be_nil
54
+ expect(null_location.line).to eq(0)
55
+ expect(null_location.column).to eq(0)
56
+ expect(null_location.offset).to eq(0)
57
+ end
58
+
59
+ it "is null?" do
60
+ expect(null_location.null?).to equal(true)
61
+ end
62
+
63
+ it "compares as equal to another null location instance" do
64
+ expect(null_location).to eq(SourceLocation.null_location)
65
+ end
66
+ end
67
+
68
+ describe "#from_main_file?", from_3_4: true do
69
+ it "returns true if the cursor location is in main file" do
70
+ expect(loc1_cursor.location.from_main_file?).to be_true
71
+ end
72
+
73
+ it "returns false if the cursor location is not in main file" do
74
+ expect(docs_cursor.location.from_main_file?).to be_false
75
+ end
76
+ end
77
+
78
+ describe "#in_system_header?", from_3_4: true do
79
+ it "returns false if the cursor location is not in system header" do
80
+ expect(loc1_cursor.location.in_system_header?).to be_false
81
+ end
82
+ end
83
+
84
+ describe "#expansion_location" do
85
+ let (:expansion_location) { loc1_cursor.location.expansion_location }
86
+
87
+ it "should be ExpansionLocaion" do
88
+ expect(expansion_location).to be_kind_of(SourceLocation)
89
+ expect(expansion_location).to be_kind_of(ExpansionLocation)
90
+ end
91
+
92
+ it "returns source location that does not care a # line directive" do
93
+ expect(expansion_location.line).to eq(3)
94
+ end
95
+ end
96
+
97
+ describe "#presumed_location" do
98
+ let (:presumed_location) { loc1_cursor.location.presumed_location }
99
+
100
+ it "should be FileLocaion" do
101
+ expect(presumed_location).to be_kind_of(SourceLocation)
102
+ expect(presumed_location).to be_kind_of(PresumedLocation)
103
+ end
104
+
105
+ it "returns preprocessed filename" do
106
+ expect(presumed_location.filename).to eq("dummy.c")
107
+ end
108
+
109
+ it "returns source location specified by a # line directive" do
110
+ expect(presumed_location.line).to eq(124)
111
+ end
112
+ end
113
+
114
+ describe "#file_location", from_3_3: true do
115
+ let (:file_location) { loc1_cursor.location.file_location }
116
+
117
+ it "should be FileLocaion" do
118
+ expect(file_location).to be_kind_of(SourceLocation)
119
+ expect(file_location).to be_kind_of(FileLocation)
120
+ end
121
+
122
+ it "returns source location that does not care a # line directive" do
123
+ expect(file_location.line).to eq(3)
124
+ end
125
+ end
126
+
127
+ describe "#spelling_location" do
128
+ let (:spelling_location) { loc1_cursor.location.spelling_location }
129
+
130
+ it "should be SpellingLocaion" do
131
+ expect(spelling_location).to be_kind_of(SourceLocation)
132
+ expect(spelling_location).to be_kind_of(SpellingLocation)
133
+ end
134
+
135
+ it "returns source location that does not care a # line directive" do
136
+ expect(spelling_location.line).to eq(3)
137
+ end
138
+ end
139
+
140
+ end
@@ -0,0 +1,76 @@
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 SourceRange do
24
+ let(:tu) { Index.new.parse_translation_unit(fixture_path("list.c")) }
25
+ let(:tu_range) { tu.cursor.extent }
26
+
27
+ it "can be obtained from a cursor" do
28
+ expect(tu_range).to be_kind_of(SourceRange)
29
+ expect(tu_range.null?).to be_false
30
+ end
31
+
32
+ it "has start and end source location" do
33
+ expect(tu_range.start).to be_kind_of(SourceLocation)
34
+ expect(tu_range.start.null?).to be_false
35
+ expect(tu_range.end).to be_kind_of(SourceLocation)
36
+ expect(tu_range.end.null?).to be_false
37
+ end
38
+
39
+ describe "Null Range" do
40
+ let(:null_range) { SourceRange.null_range }
41
+ it "can be a null range" do
42
+ expect(null_range).to be_kind_of(SourceRange)
43
+ end
44
+
45
+ it "is null?" do
46
+ expect(null_range.null?).to equal(true)
47
+ end
48
+
49
+ it "has null locations" do
50
+ expect(null_range.start.null?).to be_true
51
+ expect(null_range.end.null?).to be_true
52
+ end
53
+
54
+ it "compares as equal to another null range instance" do
55
+ expect(null_range).to eq(SourceRange.null_range)
56
+ end
57
+ end
58
+
59
+ describe "Get Range" do
60
+ let(:range) { SourceRange.new(tu_range.start, tu_range.end) }
61
+
62
+ it "can be obtained from two source locations" do
63
+ expect(range).to be_kind_of(SourceRange)
64
+ expect(range.null?).to be_false
65
+ end
66
+
67
+ it "is same to original source range" do
68
+ expect(range).to eq(tu_range)
69
+ end
70
+
71
+ it "is same to original source range's locations" do
72
+ expect(range.start).to eq(tu_range.start)
73
+ expect(range.end).to eq(tu_range.end)
74
+ end
75
+ end
76
+ end