Class: Glyphs::SourceScanner

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

Overview

Scans an application's source for statically-known icon references and returns a Set of IconReference. Ruby/Phlex files are parsed with Prism (a real AST); templates (.erb/.haml/.slim) are text-scanned for icon calls and iconify class strings.

Dynamic names/variants/libraries are silently skipped — they can't be known statically and are covered by the pruner's keep-list. A file that fails to parse warns and is skipped rather than aborting the scan.

Defined Under Namespace

Classes: CallVisitor, DynamicHarvest

Constant Summary collapse

DEFAULT_RUBY_GLOBS =
["app/**/*.rb", "lib/**/*.rb"].freeze
DEFAULT_TEMPLATE_GLOBS =
["app/**/*.erb", "app/**/*.haml", "app/**/*.slim"].freeze
TEMPLATE_CALL_NAMES =

Template (.erb/.haml/.slim) text scanning. Prism can't parse these, so we match icon calls textually: the method, the literal first-argument name, and the argument tail (to pull out variant: and, for the generic icon/Icon helper, library:/from:). Icon/icon are included here (they're handled by the AST visitor for .rb files) so the generic rails_icons view helper is caught in templates too.

(
  IconReference::LIBRARY_TO_COMPONENT.values +
    IconReference::LEGACY_HELPERS.keys +
    %w[Icon icon]
).freeze
TEMPLATE_CALL_PATTERN =

The tail runs to the end of the line or the ERB/Slim tag close (%>, -%>) — NOT to the first ), which would truncate variant:/from: sitting after a nested call like class: cn("a"). Over-capturing the tail only ever ADDS a keep (never drops a reference), so it errs safe.

/
  \b(#{Regexp.union(TEMPLATE_CALL_NAMES)})
  \(?\s*[:"']([a-z0-9_-]+)['"]?      # first arg is a literal symbol or string
  ([^\n]*?)                          # argument tail (rest of the logical line)
  (?=-?%>|\n|\z)
/x
TEMPLATE_VARIANT_PATTERN =
/\bvariant:\s*[:"']?([a-z0-9_.-]*)/
TEMPLATE_LIBRARY_PATTERN =
/\b(?:library|from):\s*[:"']([a-z0-9_-]+)/
GENERIC_TEMPLATE_CALLS =
%w[Icon icon].freeze

Instance Method Summary collapse

Constructor Details

#initialize(root:, ruby_globs: DEFAULT_RUBY_GLOBS, template_globs: DEFAULT_TEMPLATE_GLOBS, extra_globs: []) ⇒ SourceScanner

extra_globs are additional locations to text-scan on top of the built-in Ruby and template defaults (never replacing them) — e.g. a config file that names icons. They're scanned like templates (regex, not AST).



46
47
48
49
50
51
# File 'lib/glyphs/source_scanner.rb', line 46

def initialize(root:, ruby_globs: DEFAULT_RUBY_GLOBS, template_globs: DEFAULT_TEMPLATE_GLOBS, extra_globs: [])
  @root = root
  @ruby_globs = ruby_globs
  @template_globs = template_globs
  @extra_globs = Array(extra_globs)
end

Instance Method Details

#callObject

Confirmed references: icons named by a LITERAL in an icon call (or an iconify string). These are guaranteed-real — the pruner keeps them AND the runner asserts every one still resolves on disk after a prune.



56
57
58
59
# File 'lib/glyphs/source_scanner.rb', line 56

def call
  scan
  @references
end

#dynamic_keepsObject

Advisory per-library keeps harvested from DYNAMIC call sites (see DynamicHarvest). { library => Set[names] }. These may include literals that aren't real icons (a CSS class, a method name), so — like the configured keep_icons — they are kept if present but NEVER asserted by verification. Feed them into the pruner's keep path, not the runner's expected-files set.



67
68
69
70
# File 'lib/glyphs/source_scanner.rb', line 67

def dynamic_keeps
  scan
  @dynamic_keeps
end