Class: Glyphs::SourceScanner::CallVisitor

Inherits:
Prism::Visitor
  • Object
show all
Defined in:
lib/glyphs/source_scanner.rb

Overview

Walks the Prism AST collecting icon references from call nodes.

Constant Summary collapse

GENERIC_CALLS =
%i[Icon icon].freeze
ICON_NAME_LITERAL =

A literal that could be an icon name: lowercase, digits, dashes/underscores. Excludes CSS classes (spaces/slashes), paths, and interpolated strings.

/\A[a-z][a-z0-9_-]*\z/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(references) ⇒ CallVisitor

Returns a new instance of CallVisitor.



215
216
217
218
219
220
221
# File 'lib/glyphs/source_scanner.rb', line 215

def initialize(references)
  @references = references
  @dynamic_libraries = Set.new
  @file_literals = Set.new
  @declaration_literals = Set.new
  super()
end

Instance Attribute Details

#declaration_literalsObject (readonly)

Literals in icon-declaration positions (icon: pairs, ICON constants).



213
214
215
# File 'lib/glyphs/source_scanner.rb', line 213

def declaration_literals
  @declaration_literals
end

#dynamic_librariesObject (readonly)

Libraries this file renders with a dynamic (non-literal) first argument.



209
210
211
# File 'lib/glyphs/source_scanner.rb', line 209

def dynamic_libraries
  @dynamic_libraries
end

#file_literalsObject (readonly)

Icon-name-shaped literals anywhere in this file (file-scoped candidates).



211
212
213
# File 'lib/glyphs/source_scanner.rb', line 211

def file_literals
  @file_literals
end

Instance Method Details

#visit_assoc_node(node) ⇒ Object

icon: :activity / menu_icon: "gear" — a hash pair keyed like an icon declares an icon name, wherever it lives.



251
252
253
254
255
# File 'lib/glyphs/source_scanner.rb', line 251

def visit_assoc_node(node)
  key = node.key
  collect_declaration(node.value) if key.is_a?(Prism::SymbolNode) && key.unescaped.match?(/icon/i)
  super
end

#visit_call_node(node) ⇒ Object



223
224
225
226
# File 'lib/glyphs/source_scanner.rb', line 223

def visit_call_node(node)
  record(node) if node.receiver.nil?
  super
end

#visit_constant_write_node(node) ⇒ Object

ICON = :bell / CHANNEL_ICONS = { .. => :whatsapp_logo } — a constant named like an icon is a declaration of icon name(s), wherever it lives.



244
245
246
247
# File 'lib/glyphs/source_scanner.rb', line 244

def visit_constant_write_node(node)
  collect_declaration(node.value) if node.name.to_s.match?(/ICON/i)
  super
end

#visit_string_node(node) ⇒ Object



228
229
230
231
232
233
234
235
# File 'lib/glyphs/source_scanner.rb', line 228

def visit_string_node(node)
  node.unescaped.scan(IconReference::ICONIFY_PATTERN) do |library, name|
    library = library.to_sym
    references << IconReference.new(library:, variant: IconReference.default_variant_for(library), name:)
  end
  collect_literal(@file_literals, node)
  super
end

#visit_symbol_node(node) ⇒ Object



237
238
239
240
# File 'lib/glyphs/source_scanner.rb', line 237

def visit_symbol_node(node)
  collect_literal(@file_literals, node)
  super
end