Class: Jazzy::SymbolGraph::Symbol
- Inherits:
-
Object
- Object
- Jazzy::SymbolGraph::Symbol
- Includes:
- Comparable
- Defined in:
- lib/jazzy/symbol_graph/symbol.rb
Overview
A Symbol is a tidied-up SymbolGraph JSON object
Constant Summary collapse
- KIND_MAP =
Mapping SymbolGraph’s declkinds to SourceKit
{ 'class' => 'class', 'struct' => 'struct', 'enum' => 'enum', 'enum.case' => 'enumelement', # intentional 'protocol' => 'protocol', 'init' => 'function.constructor', 'deinit' => 'function.destructor', 'func.op' => 'function.operator', 'type.method' => 'function.method.class', 'static.method' => 'function.method.static', 'method' => 'function.method.instance', 'func' => 'function.free', 'type.property' => 'var.class', 'static.property' => 'var.static', 'property' => 'var.instance', 'var' => 'var.global', 'subscript' => 'function.subscript', 'type.subscript' => 'function.subscript', 'static.subscript' => 'function.subscript', 'typealias' => 'typealias', 'associatedtype' => 'associatedtype', 'actor' => 'actor', 'macro' => 'macro', 'extension' => 'extension', }.freeze
Instance Attribute Summary collapse
-
#acl ⇒ Object
Returns the value of attribute acl.
-
#attributes ⇒ Object
array, can be empty.
-
#constraints ⇒ Object
array, can be empty.
-
#declaration ⇒ Object
Returns the value of attribute declaration.
-
#doc_comments ⇒ Object
can be nil.
-
#generic_type_params ⇒ Object
set, can be empty.
-
#kind ⇒ Object
Returns the value of attribute kind.
-
#location ⇒ Object
can be nil, keys :filename :line :character.
-
#parameter_names ⇒ Object
array, can be nil.
-
#path_components ⇒ Object
Returns the value of attribute path_components.
-
#spi ⇒ Object
Returns the value of attribute spi.
-
#usr ⇒ Object
Returns the value of attribute usr.
Instance Method Summary collapse
- #<=>(other) ⇒ Object
-
#add_to_sourcekit(hash) ⇒ Object
SourceKit common fields, shared by extension and regular symbols.
-
#adjust_kind_for_declaration(kind, keywords) ⇒ Object
We treat ‘static var’ differently to ‘class var’ We treat actors as first-class entities.
-
#availability_attributes(avail_hash_list) ⇒ Object
Availability Re-encode this as Swift.
- #decode_version(hash) ⇒ Object
- #extension? ⇒ Boolean
- #full_name ⇒ Object
-
#init_acl(acl) ⇒ Object
Mapping SymbolGraph’s ACL to SourceKit.
- #init_attributes(avail_hash_list) ⇒ Object
-
#init_constraints(hash, raw_decl) ⇒ Object
Generic constraints: in one or both of two places.
-
#init_declaration(raw_decl) ⇒ Object
Repair problems with SymbolGraph’s declprinter.
- #init_doc_comments(comments_hash) ⇒ Object
-
#init_func_signature(func_signature) ⇒ Object
Remember pieces of methods for later markdown parsing.
-
#init_generic_type_params(hash) ⇒ Object
Generic type params.
- #init_kind(kind, keywords) ⇒ Object
-
#init_location(loc_hash) ⇒ Object
Symbol location - only available for public+ decls.
-
#initialize(hash) ⇒ Symbol
constructor
A new instance of Symbol.
- #name ⇒ Object
- #parse_decl_fragments(fragments) ⇒ Object
- #spi_attributes ⇒ Object
Constructor Details
#initialize(hash) ⇒ Symbol
Returns a new instance of Symbol.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 29 def initialize(hash) self.usr = hash[:identifier][:precise] self.path_components = hash[:pathComponents] raw_decl, keywords = parse_decl_fragments(hash[:declarationFragments]) init_kind(hash[:kind][:identifier], keywords) init_declaration(raw_decl) if func_signature = hash[:functionSignature] init_func_signature(func_signature) end init_acl(hash[:accessLevel]) self.spi = hash[:spi] if location = hash[:location] init_location(location) end init_constraints(hash, raw_decl) if comments_hash = hash[:docComment] init_doc_comments(comments_hash) end init_attributes(hash[:availability] || []) init_generic_type_params(hash) end |
Instance Attribute Details
#acl ⇒ Object
Returns the value of attribute acl.
12 13 14 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 12 def acl @acl end |
#attributes ⇒ Object
array, can be empty
17 18 19 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 17 def attributes @attributes end |
#constraints ⇒ Object
array, can be empty
15 16 17 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 15 def constraints @constraints end |
#declaration ⇒ Object
Returns the value of attribute declaration.
10 11 12 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 10 def declaration @declaration end |
#doc_comments ⇒ Object
can be nil
16 17 18 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 16 def doc_comments @doc_comments end |
#generic_type_params ⇒ Object
set, can be empty
18 19 20 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 18 def generic_type_params @generic_type_params end |
#kind ⇒ Object
Returns the value of attribute kind.
11 12 13 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 11 def kind @kind end |
#location ⇒ Object
can be nil, keys :filename :line :character
14 15 16 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 14 def location @location end |
#parameter_names ⇒ Object
array, can be nil
19 20 21 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 19 def parameter_names @parameter_names end |
#path_components ⇒ Object
Returns the value of attribute path_components.
9 10 11 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 9 def path_components @path_components end |
#spi ⇒ Object
Returns the value of attribute spi.
13 14 15 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 13 def spi @spi end |
#usr ⇒ Object
Returns the value of attribute usr.
8 9 10 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 8 def usr @usr end |
Instance Method Details
#<=>(other) ⇒ Object
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 251 def <=>(other) # Things with location: order by file/line/column # (pls tell what wheel i am reinventing :/) if location && other_loc = other.location if location[:filename] == other_loc[:filename] if location[:line] == other_loc[:line] return location[:character] <=> other_loc[:character] end return location[:line] <=> other_loc[:line] end return location[:filename] <=> other_loc[:filename] end # Things with a location before things without a location return +1 if location.nil? && other.location return -1 if location && other.location.nil? # Things without a location: by name and then USR return usr <=> other.usr if name == other.name name <=> other.name end |
#add_to_sourcekit(hash) ⇒ Object
SourceKit common fields, shared by extension and regular symbols. Things we do not know for fabricated extensions.
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 231 def add_to_sourcekit(hash) unless doc_comments.nil? hash['key.doc.comment'] = doc_comments hash['key.doc.full_as_xml'] = '' end hash['key.accessibility'] = acl unless location.nil? hash['key.filepath'] = location[:filename] hash['key.doc.line'] = location[:line] + 1 hash['key.doc.column'] = location[:character] + 1 end hash end |
#adjust_kind_for_declaration(kind, keywords) ⇒ Object
We treat ‘static var’ differently to ‘class var’ We treat actors as first-class entities
113 114 115 116 117 118 119 120 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 113 def adjust_kind_for_declaration(kind, keywords) if kind == 'swift.class' && keywords.member?('actor') return 'swift.actor' end return kind unless keywords.member?('static') kind.gsub('type', 'static') end |
#availability_attributes(avail_hash_list) ⇒ Object
Availability Re-encode this as Swift. Should really teach Jazzy about these, could maybe then do something smarter here.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 189 def availability_attributes(avail_hash_list) avail_hash_list.map do |avail| str = '@available(' if avail[:isUnconditionallyDeprecated] str += '*, deprecated' elsif domain = avail[:domain] str += domain %i[introduced deprecated obsoleted].each do |event| if version = avail[event] str += ", #{event}: #{decode_version(version)}" end end else warn "Found confusing availability: #{avail}" next nil end str += ", message: \"#{avail[:message]}\"" if avail[:message] str += ", renamed: \"#{avail[:renamed]}\"" if avail[:renamed] str + ')' end.compact end |
#decode_version(hash) ⇒ Object
213 214 215 216 217 218 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 213 def decode_version(hash) str = hash[:major].to_s str += ".#{hash[:minor]}" if hash[:minor] str += ".#{hash[:patch]}" if hash[:patch] str end |
#extension? ⇒ Boolean
130 131 132 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 130 def extension? kind.end_with?('extension') end |
#full_name ⇒ Object
25 26 27 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 25 def full_name path_components.join('.') end |
#init_acl(acl) ⇒ Object
Mapping SymbolGraph’s ACL to SourceKit
136 137 138 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 136 def init_acl(acl) self.acl = "source.lang.swift.accessibility.#{acl}" end |
#init_attributes(avail_hash_list) ⇒ Object
224 225 226 227 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 224 def init_attributes(avail_hash_list) self.attributes = availability_attributes(avail_hash_list) + spi_attributes end |
#init_constraints(hash, raw_decl) ⇒ Object
Generic constraints: in one or both of two places. There can be duplicates; these are removed by ‘Constraint`.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 151 def init_constraints(hash, raw_decl) raw_constraints = %i[swiftGenerics swiftExtension].flat_map do |key| next [] unless container = hash[key] container[:constraints] || [] end constraints = Constraint.new_list_for_symbol(raw_constraints, path_components) if raw_decl =~ / where (.*)$/ constraints += Constraint.new_list_from_declaration(Regexp.last_match[1]) end self.constraints = constraints.sort.uniq end |
#init_declaration(raw_decl) ⇒ Object
Repair problems with SymbolGraph’s declprinter
63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 63 def init_declaration(raw_decl) # Too much 'Self.TypeName'; omitted arg labels look odd; # duplicated constraints; swift 5.3 vs. master workaround self.declaration = raw_decl .gsub(/\bSelf\./, '') .gsub(/(?<=\(|, )_: /, '_ arg: ') .gsub(/ where.*$/, '') if kind == 'source.lang.swift.decl.class' declaration.sub!(/\s*:.*$/, '') end end |
#init_doc_comments(comments_hash) ⇒ Object
180 181 182 183 184 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 180 def init_doc_comments(comments_hash) self.doc_comments = comments_hash[:lines] .map { |l| l[:text] } .join("\n") end |
#init_func_signature(func_signature) ⇒ Object
Remember pieces of methods for later markdown parsing
77 78 79 80 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 77 def init_func_signature(func_signature) self.parameter_names = (func_signature[:parameters] || []).map { |h| h[:name] } end |
#init_generic_type_params(hash) ⇒ Object
Generic type params
169 170 171 172 173 174 175 176 177 178 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 169 def init_generic_type_params(hash) self.generic_type_params = Set.new( if (generics = hash[:swiftGenerics]) && (parameters = generics[:parameters]) parameters.map { |p| p[:name] } else [] end, ) end |
#init_kind(kind, keywords) ⇒ Object
122 123 124 125 126 127 128 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 122 def init_kind(kind, keywords) adjusted = adjust_kind_for_declaration(kind, keywords) sourcekit_kind = KIND_MAP[adjusted.sub('swift.', '')] raise "Unknown symbol kind '#{kind}'" unless sourcekit_kind self.kind = "source.lang.swift.decl.#{sourcekit_kind}" end |
#init_location(loc_hash) ⇒ Object
Symbol location - only available for public+ decls
142 143 144 145 146 147 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 142 def init_location(loc_hash) self.location = {} location[:filename] = loc_hash[:uri].sub(%r{^file://}, '') location[:line] = loc_hash[:position][:line] location[:character] = loc_hash[:position][:character] end |
#name ⇒ Object
21 22 23 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 21 def name path_components[-1] || '??' end |
#parse_decl_fragments(fragments) ⇒ Object
51 52 53 54 55 56 57 58 59 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 51 def parse_decl_fragments(fragments) decl = '' keywords = Set.new fragments.each do |frag| decl += frag[:spelling] keywords.add(frag[:spelling]) if frag[:kind] == 'keyword' end [decl, keywords] end |
#spi_attributes ⇒ Object
220 221 222 |
# File 'lib/jazzy/symbol_graph/symbol.rb', line 220 def spi_attributes spi ? ['@_spi(Unknown)'] : [] end |