glyphs 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 245c7101b5dad69bf73859eea7a5d7c9027f1573d4e1b4ccbcde2bed3e61266f
4
- data.tar.gz: 585c169414705979b1c45bf02ad87de324c5e6a16fb6a8ddb0e631961820e533
3
+ metadata.gz: 8c8e883474d143ec14502ef27013e1a264c0a89d76b7dd24ef29d2025d96ad5c
4
+ data.tar.gz: afad4dcca3bda0162be398c66a7a7bb65c36af8facb9c4b5eb13f5d4d29a1d2c
5
5
  SHA512:
6
- metadata.gz: c5dfa80d58dbf2cc918f7a0ea2b74937156356137abca9c7297f0a974c1ee079176f335b6a5d33599f81f9d6af8f8efe324d9ab841f52126750bc80fb01abb38
7
- data.tar.gz: 4a6b23ac1e990068f529e2ad7ed54fa078391256894d59b8a2390b5a9e773fd26a0dc55b11dcd3bfb00e13548791e80bcf1a5659bdd2ca82d26a5db1495893f1
6
+ metadata.gz: a9c94ace100a67479cb24e793dfd7bc9c71238bfd472f2d29be37076410c27e0cc69d48b2952fad4574bac1e5184770d0b19542284c06edb520fece72d6c1526
7
+ data.tar.gz: 8d2cb2a5ca53b92884b28de6a2813326796b034754d5b6f14ab37b4fb7f54c1d49b6deb61dc53d75c0c668e8908447e9a5fdfd8bb71fbb5440c22a5bd9c15b61
data/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ### Fixed
6
+
7
+ - **Declaration harvest unwraps trailing `.freeze`.** `ICONS = { "x" => :car }.freeze`
8
+ (and `%i[a b].freeze`) used to yield a Prism `CallNode`, so hash/array values
9
+ were never collected. Cross-file dynamics (`PhosphorIcon(@icon)` in a shared
10
+ component + names only in a frozen `ICONS` map) then lost those icons at
11
+ `glyphs:prune_icons`. `collect_declaration` now unwraps zero-arg `.freeze`
12
+ (and parentheses) before walking the value.
13
+
5
14
  ### Added
6
15
 
7
16
  - **Dynamic icon calls are now resolved from source.** `SourceScanner` no longer
@@ -13,7 +22,8 @@
13
22
  - _declaration-based_: literals in icon-declaration positions anywhere (a hash
14
23
  pair keyed `/icon/i`, or a constant named `/ICON/`) are kept for every
15
24
  dynamically-rendered library, closing the cross-file gap (e.g. a notifier
16
- `ICON = :bell` constant rendered from a view).
25
+ `ICON = :bell` constant rendered from a view). Frozen maps
26
+ (`ICONS = { … }.freeze`) are included — see Fixed above.
17
27
 
18
28
  This makes `keep_icons` a last-resort escape hatch (DB/ENV/gem-chrome names)
19
29
  rather than the primary mechanism. Only literals are harvested, so the scanner
data/README.md CHANGED
@@ -133,9 +133,9 @@ The scanner resolves them from source, so you rarely need `keep_icons` at all:
133
133
  ternaries (`@open ? "caret-up" : "caret-down"`), `case/when`, and locals.
134
134
  - **Declaration-based** — literals in icon-declaration positions *anywhere* — a
135
135
  hash pair keyed like an icon (`icon: :gear`, `menu_icon: "house"`) or a
136
- constant named like one (`ICON = :bell`, `STATUS_ICONS = { .. => :warning }`) —
137
- are kept for every dynamically-rendered library, so a name declared in one
138
- file and rendered from another survives.
136
+ constant named like one (`ICON = :bell`, `STATUS_ICONS = { .. => :warning }`,
137
+ including trailing `.freeze`) — are kept for every dynamically-rendered
138
+ library, so a name declared in one file and rendered from another survives.
139
139
 
140
140
  Only literals are harvested, so the scanner never invents a reference; the
141
141
  worst case is keeping a coincidentally icon-named string, which the post-prune
@@ -346,7 +346,11 @@ module Glyphs
346
346
 
347
347
  # Harvests icon names from a declaration value: a bare literal, an array of
348
348
  # literals (`ICON = %i[a b]`), or a hash's values (`{ "sms" => :device }`).
349
+ # Trailing `.freeze` is unwrapped so `ICONS = { … }.freeze` still harvests —
350
+ # without this, cross-file dynamics (`PhosphorIcon(@icon)` + names only in a
351
+ # frozen `ICONS` hash) lose those names at prune.
349
352
  def collect_declaration(value_node)
353
+ value_node = unwrap_declaration_wrappers(value_node)
350
354
  case value_node
351
355
  when Prism::SymbolNode, Prism::StringNode
352
356
  collect_literal(@declaration_literals, value_node)
@@ -356,6 +360,37 @@ module Glyphs
356
360
  value_node.elements.grep(Prism::AssocNode).each { |assoc| collect_declaration(assoc.value) }
357
361
  end
358
362
  end
363
+
364
+ # Peel zero-arg `.freeze` and parentheses so the underlying Hash/Array/literal
365
+ # is what declaration harvest walks.
366
+ def unwrap_declaration_wrappers(value_node)
367
+ loop do
368
+ case value_node
369
+ when Prism::CallNode
370
+ break unless freeze_call?(value_node)
371
+
372
+ value_node = value_node.receiver
373
+ when Prism::ParenthesesNode
374
+ value_node = value_node.body
375
+ when Prism::StatementsNode
376
+ # `(expr)` → StatementsNode with one child; multi-statement bodies are
377
+ # not valid constant values, so take the sole statement when present.
378
+ break unless value_node.body.size == 1
379
+
380
+ value_node = value_node.body.first
381
+ else
382
+ break
383
+ end
384
+ end
385
+ value_node
386
+ end
387
+
388
+ # `receiver.freeze` with no args — the common immutable-constant pattern.
389
+ def freeze_call?(node)
390
+ node.name == :freeze &&
391
+ node.receiver &&
392
+ (node.arguments.nil? || node.arguments.arguments.empty?)
393
+ end
359
394
  end
360
395
  end
361
396
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Glyphs
4
- VERSION = "0.2.2"
4
+ VERSION = "0.2.3"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glyphs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikael Henriksson