class Jazzy::SymbolGraph::Symbol
A Symbol
is a tidied-up SymbolGraph
JSON object
Constants
- KIND_MAP
Mapping SymbolGraph’s declkinds to SourceKit
Attributes
acl[RW]
attributes[RW]
constraints[RW]
declaration[RW]
doc_comments[RW]
generic_type_params[RW]
kind[RW]
location[RW]
parameter_names[RW]
path_components[RW]
spi[RW]
usr[RW]
Public Class Methods
new(hash)
click to toggle source
# 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
Public Instance Methods
<=>(other)
click to toggle source
# 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)
click to toggle source
SourceKit common fields, shared by extension and regular symbols. Things we do not know for fabricated extensions.
# 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)
click to toggle source
We treat ‘static var’ differently to ‘class var’ We treat actors as first-class entities
# 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)
click to toggle source
Availability Re-encode this as Swift. Should really teach Jazzy
about these, could maybe then do something smarter here.
# 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)
click to toggle source
# 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?()
click to toggle source
# File lib/jazzy/symbol_graph/symbol.rb, line 130 def extension? kind.end_with?('extension') end
full_name()
click to toggle source
# File lib/jazzy/symbol_graph/symbol.rb, line 25 def full_name path_components.join('.') end
init_acl(acl)
click to toggle source
Mapping SymbolGraph’s ACL to SourceKit
# 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)
click to toggle source
# 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)
click to toggle source
Generic constraints: in one or both of two places. There can be duplicates; these are removed by ‘Constraint`.
# 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)
click to toggle source
Repair problems with SymbolGraph’s declprinter
# 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)
click to toggle source
# 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)
click to toggle source
Remember pieces of methods for later markdown parsing
# 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)
click to toggle source
Generic type params
# 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)
click to toggle source
# 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)
click to toggle source
Symbol
location - only available for public+ decls
# 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()
click to toggle source
# File lib/jazzy/symbol_graph/symbol.rb, line 21 def name path_components[-1] || '??' end
parse_decl_fragments(fragments)
click to toggle source
# 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()
click to toggle source
# File lib/jazzy/symbol_graph/symbol.rb, line 220 def spi_attributes spi ? ['@_spi(Unknown)'] : [] end