code_completion.rb (5036B)
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_relative 'lib/code_completion' 22 23 module FFI 24 module Clang 25 class CodeCompletion 26 def self.default_code_completion_options 27 Lib.opts_from Lib::CodeCompleteFlags, Lib.default_code_completion_options 28 end 29 30 class Results < FFI::AutoPointer 31 include Enumerable 32 33 attr_reader :size 34 attr_reader :results 35 36 def initialize(code_complete_results, translation_unit) 37 super code_complete_results.pointer 38 @translation_unit = translation_unit 39 @code_complete_results = code_complete_results 40 initialize_results 41 end 42 43 def self.release(pointer) 44 Lib.dispose_code_complete_results(pointer) 45 end 46 47 def each(&block) 48 @results.each do |token| 49 block.call(token) 50 end 51 end 52 53 def num_diagnostics 54 Lib.get_code_complete_get_num_diagnostics(@code_complete_results) 55 end 56 57 def diagnostic(i) 58 Diagnostic.new(@translation_unit, Lib.get_code_complete_get_diagnostic(@code_complete_results, i)) 59 end 60 61 def diagnostics 62 num_diagnostics.times.map { |i| 63 Diagnostic.new(@translation_unit, Lib.get_code_complete_get_diagnostic(@code_complete_results, i)) 64 } 65 end 66 67 def contexts 68 Lib.opts_from Lib::CompletionContext, Lib.get_code_complete_get_contexts(@code_complete_results) 69 end 70 71 def container_usr 72 Lib.extract_string Lib.get_code_complete_get_container_usr(@code_complete_results) 73 end 74 75 def container_kind 76 is_incomplete = MemoryPointer.new :uint 77 Lib.get_code_complete_get_container_kind(@code_complete_results, is_incomplete) 78 end 79 80 def incomplete? 81 is_incomplete = MemoryPointer.new :uint 82 Lib.get_code_complete_get_container_kind(@code_complete_results, is_incomplete) 83 is_incomplete.read_uint != 0 84 end 85 86 def objc_selector 87 Lib.extract_string Lib.get_code_complete_get_objc_selector(@code_complete_results) 88 end 89 90 def sort! 91 Lib.sort_code_completion_results(@code_complete_results[:results], @code_complete_results[:num]) 92 initialize_results 93 end 94 95 def inspect 96 @results.inspect 97 end 98 99 private 100 101 def initialize_results 102 @size = @code_complete_results[:num] 103 cur_ptr = @code_complete_results[:results] 104 @results = [] 105 @size.times { 106 @results << Result.new(Lib::CXCompletionResult.new(cur_ptr)) 107 cur_ptr += Lib::CXCompletionResult.size 108 } 109 end 110 end 111 112 class Result 113 def initialize(result) 114 @result = result 115 end 116 117 def kind 118 @result[:kind] 119 end 120 121 def string 122 CodeCompletion::String.new @result[:string] 123 end 124 125 def inspect 126 "<#{kind.inspect} = #{string.inspect}>" 127 end 128 end 129 130 class String 131 def initialize(ptr) 132 @pointer = ptr 133 end 134 135 def chunk_kind(i) 136 Lib.get_completion_chunk_kind(@pointer, i) 137 end 138 139 def chunk_text(i) 140 Lib.extract_string Lib.get_completion_text(@pointer, i) 141 end 142 143 def chunk_completion(i) 144 CodeCompletion::String.new Lib.get_completion_chunk_completion_string(@pointer, i) 145 end 146 147 def num_chunks 148 Lib.get_num_completion_chunks(@pointer) 149 end 150 151 def chunks 152 num_chunks.times.map { |i| 153 { kind: chunk_kind(i), text: chunk_text(i), completion: chunk_completion(i) } 154 } 155 end 156 157 def priority 158 Lib.get_completion_priority(@pointer) 159 end 160 161 def availability 162 Lib.get_completion_availability(@pointer) 163 end 164 165 def num_annotations 166 Lib.get_completion_num_annotations(@pointer) 167 end 168 169 def annotation(i) 170 Lib.extract_string Lib.get_completion_annotation(@pointer, i) 171 end 172 173 def annotations 174 num_annotations.times.map { |i| 175 Lib.extract_string Lib.get_completion_annotation(@pointer, i) 176 } 177 end 178 179 def parent 180 Lib.extract_string Lib.get_completion_parent(@pointer, nil) 181 end 182 183 def comment 184 Lib.extract_string Lib.get_completion_brief_comment(@pointer) 185 end 186 187 def inspect 188 chunks.inspect 189 end 190 end 191 end 192 end 193 end