Class: Jazzy::SymbolGraph::SymNode

Inherits:
BaseNode
  • Object
show all
Includes:
Comparable
Defined in:
lib/jazzy/symbol_graph/sym_node.rb

Overview

A SymNode is a node of the reconstructed syntax tree holding a symbol. It can turn itself into SourceKit and helps decode extensions.

Instance Attribute Summary collapse

Attributes inherited from BaseNode

#children, #parent

Instance Method Summary collapse

Methods inherited from BaseNode

#add_child, #add_children_to_sourcekit

Constructor Details

#initialize(symbol) ⇒ SymNode

Returns a new instance of SymNode.



50
51
52
53
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 50

def initialize(symbol)
  self.symbol = symbol
  super()
end

Instance Attribute Details

#override=(value) ⇒ Object (writeonly)

Sets the attribute override

Parameters:

  • value

    the value to set the attribute override to.



33
34
35
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 33

def override=(value)
  @override = value
end

#protocol_requirement=(value) ⇒ Object (writeonly)

Sets the attribute protocol_requirement

Parameters:

  • value

    the value to set the attribute protocol_requirement to.



34
35
36
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 34

def protocol_requirement=(value)
  @protocol_requirement = value
end

#superclass_nameObject

Returns the value of attribute superclass_name.



36
37
38
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 36

def superclass_name
  @superclass_name
end

#symbolObject

Returns the value of attribute symbol.



32
33
34
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 32

def symbol
  @symbol
end

#unlisted=(value) ⇒ Object (writeonly)

Sets the attribute unlisted

Parameters:

  • value

    the value to set the attribute unlisted to.



35
36
37
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 35

def unlisted=(value)
  @unlisted = value
end

Instance Method Details

#<=>(other) ⇒ Object



159
160
161
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 159

def <=>(other)
  symbol <=> other.symbol
end

#actor?Boolean

Returns:

  • (Boolean)


67
68
69
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 67

def actor?
  symbol.kind.end_with?('actor')
end

#async?Boolean

approximately…

Returns:

  • (Boolean)


123
124
125
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 123

def async?
  symbol.declaration =~ /\basync\b[^)]*$/
end

#conformance?(protocol) ⇒ Boolean

Messy check whether we need to fabricate an extension for a protocol conformance: don’t bother if it’s already in the type declaration.

Returns:

  • (Boolean)


104
105
106
107
108
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 104

def conformance?(protocol)
  return false unless symbol.declaration =~ /(?<=:).*?(?=(where|$))/

  Regexp.last_match[0] =~ /\b#{protocol}\b/
end

#constraintsObject



71
72
73
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 71

def constraints
  symbol.constraints
end

#full_declarationObject



127
128
129
130
131
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 127

def full_declaration
  symbol.attributes
    .append(symbol.declaration + inherits_clause + where_clause)
    .join("\n")
end

#inherits_clauseObject



116
117
118
119
120
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 116

def inherits_clause
  return '' unless superclass_name

  " : #{superclass_name}"
end

#override?Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 38

def override?
  @override
end

#parent_qualified_nameObject



59
60
61
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 59

def parent_qualified_name
  symbol.path_components[0...-1].join('.')
end

#protocol?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 63

def protocol?
  symbol.kind.end_with?('protocol')
end

#protocol_requirement?Boolean

Returns:

  • (Boolean)


42
43
44
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 42

def protocol_requirement?
  @protocol_requirement
end

#qualified_nameObject



55
56
57
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 55

def qualified_name
  symbol.path_components.join('.')
end

#to_sourcekit(module_name) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 133

def to_sourcekit(module_name)
  declaration = full_declaration
  xml_declaration = "<swift>#{CGI.escapeHTML(declaration)}</swift>"

  hash = {
    'key.kind' => symbol.kind,
    'key.usr' => symbol.usr,
    'key.name' => symbol.name,
    'key.modulename' => module_name,
    'key.parsed_declaration' => declaration,
    'key.annotated_decl' => xml_declaration,
    'key.symgraph_async' => async?,
  }
  if params = symbol.parameter_names
    hash['key.doc.parameters'] =
      params.map { |name| { 'name' => name } }
  end
  hash['key.symgraph_spi'] = true if symbol.spi

  add_children_to_sourcekit(hash, module_name)
  symbol.add_to_sourcekit(hash)
end

#top_level_decl?Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 46

def top_level_decl?
  !@unlisted && parent.nil?
end

#try_add_child(node, unique_context_constraints) ⇒ Object

Add another SymNode as a member if possible. It must go in an extension if either:

- it has different generic constraints to us; or
- we're a protocol and it's a default impl / ext method


79
80
81
82
83
84
85
86
87
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 79

def try_add_child(node, unique_context_constraints)
  unless unique_context_constraints.empty? &&
         (!protocol? || node.protocol_requirement?)
    return false
  end

  add_child(node)
  true
end

#unique_context_constraints(context) ⇒ Object

The ‘Constraint`s on this decl that are both:

  1. Unique, ie. not just inherited from its context; and

  2. Constraining the *context’s* gen params rather than our own.



92
93
94
95
96
97
98
99
100
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 92

def unique_context_constraints(context)
  return symbol.constraints unless context

  new_generic_type_params =
    symbol.generic_type_params - context.symbol.generic_type_params

  (symbol.constraints - context.symbol.constraints)
    .select { |con| con.type_names.disjoint?(new_generic_type_params) }
end

#where_clauseObject

Generate the ‘where’ clause for the declaration



111
112
113
114
# File 'lib/jazzy/symbol_graph/sym_node.rb', line 111

def where_clause
  parent_constraints = parent&.constraints || []
  (constraints - parent_constraints).to_where_clause
end