translation_unit.rb (5493B)
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_relative 'lib/translation_unit' 24 require_relative 'lib/inclusions' 25 require_relative 'cursor' 26 require_relative 'file' 27 require_relative 'token' 28 29 module FFI 30 module Clang 31 class TranslationUnit < AutoPointer 32 def initialize(pointer, index) 33 super pointer 34 @index = index 35 end 36 37 def self.release(pointer) 38 Lib.dispose_translation_unit(pointer) 39 end 40 41 def self.default_editing_translation_unit_options 42 bitmask = Lib.default_editing_translation_unit_options 43 Lib.opts_from Lib::TranslationUnitFlags, bitmask 44 end 45 46 def default_save_options 47 bitmask = Lib.default_save_options(self) 48 Lib.opts_from Lib::SaveTranslationUnitFlags, bitmask 49 end 50 51 def save(filename, opts = {}) 52 ret = Lib.save_translation_unit(self, filename, 0) 53 sym = Lib::SaveError[ret] 54 raise Error, "unknown return values: #{ret} #{sym.inspect}" unless sym 55 raise Error, "save error: #{sym.inspect}, filename: #{filename}" if sym != :none 56 end 57 58 def default_reparse_options 59 bitmask = Lib.default_save_options(self) 60 Lib.opts_from Lib::ReparseFlags, bitmask 61 end 62 63 def reparse(unsaved = [], opts = {}) 64 unsaved_files = UnsavedFile.unsaved_pointer_from(unsaved) 65 if Lib.reparse_translation_unit(self, unsaved.size, unsaved_files, 0) != 0 66 raise Error, "reparse error" 67 end 68 end 69 70 def diagnostics 71 n = Lib.get_num_diagnostics(self) 72 73 n.times.map do |i| 74 Diagnostic.new(self, Lib.get_diagnostic(self, i)) 75 end 76 end 77 78 def cursor(location = nil) 79 if location.nil? 80 Cursor.new Lib.get_translation_unit_cursor(self), self 81 else 82 Cursor.new Lib.get_cursor(self, location.location), self 83 end 84 end 85 86 def location(file, line, column) 87 ExpansionLocation.new Lib.get_location(self, file, line, column) 88 end 89 90 def location_offset(file, offset) 91 ExpansionLocation.new Lib.get_location_offset(self, file, offset) 92 end 93 94 def file(file_name = nil) 95 if file_name.nil? 96 File.new(Lib.get_file(self, spelling), self) 97 else 98 File.new(Lib.get_file(self, file_name), self) 99 end 100 end 101 102 def spelling 103 Lib.extract_string Lib.get_translation_unit_spelling(self) 104 end 105 106 def resource_usage 107 FFI::Clang::TranslationUnit::ResourceUsage.new Lib.resource_usage(self) 108 end 109 110 def tokenize(range) 111 token_ptr = MemoryPointer.new :pointer 112 uint_ptr = MemoryPointer.new :uint 113 Lib.tokenize(self, range.range, token_ptr, uint_ptr) 114 Tokens.new(token_ptr.get_pointer(0), uint_ptr.get_uint(0), self) 115 end 116 117 def code_complete(source_file, line, column, unsaved = [], opts = nil) 118 opts = CodeCompletion.default_code_completion_options if opts.nil? 119 unsaved_files = UnsavedFile.unsaved_pointer_from(unsaved) 120 option_bitmask = Lib.bitmask_from(Lib::CodeCompleteFlags, opts) 121 ptr = Lib.code_complete_at(self, source_file, line, column, unsaved_files, unsaved.length, option_bitmask) 122 CodeCompletion::Results.new ptr, self 123 end 124 125 def inclusions(&block) 126 adapter = Proc.new do |included_file, inclusion_stack, include_len, unused| 127 file = Lib.extract_string Lib.get_file_name(included_file) 128 cur_ptr = inclusion_stack 129 inclusions = [] 130 include_len.times { 131 inclusions << SourceLocation.new(Lib::CXSourceLocation.new(cur_ptr)) 132 cur_ptr += Lib::CXSourceLocation.size 133 } 134 block.call file, inclusions 135 end 136 137 Lib.get_inclusions(self, adapter, nil) 138 end 139 140 class ResourceUsage < AutoPointer 141 def initialize(resource_usage) 142 # CXResourceUsage is returned by value and should be freed explicitly. 143 # Get FFI::pointer of the data so that the data is handled by AutoPointer. 144 pointer = FFI::Pointer.new(resource_usage.to_ptr) 145 super(pointer) 146 @resource_usage = resource_usage 147 end 148 149 def self.release(pointer) 150 # clang_disposeCXTUResourceUsage requires value type, so create it by pointer 151 Lib.dispose_resource_usage(Lib::CXTUResourceUsage.new(pointer)) 152 end 153 154 def self.name(kind) 155 Lib.resource_usage_name(kind) 156 end 157 158 def entries 159 ary = [] 160 ptr = @resource_usage[:entries] 161 @resource_usage[:numEntries].times { 162 ary << Lib::CXTUResourceUsageEntry.new(ptr) 163 ptr += Lib::CXTUResourceUsageEntry.size 164 } 165 ary 166 end 167 end 168 end 169 end 170 end