Class: Ryac::Pipeline::SpellingShorten

Inherits:
Stage
  • Object
show all
Defined in:
lib/ryac/pipeline/spelling_shorten.rb,
sig/ryac/pipeline/spelling_shorten.rbs

Overview

Same value, shorter spelling: symbol and string array literals collapse to their percent forms when that is strictly smaller, and the English spellings of Ruby's special globals collapse to their punctuation forms — the same storage cell under either name. The pairing lives in GvarRenameMapping::PERL_SPELLINGS, which also shields both spellings from the gvar renamer.

Constant Summary collapse

SAFE_WORD =

Words a percent literal can carry verbatim: nothing that needs escaping and nothing that could close or balance the delimiter.

Returns:

  • (Regexp)
%r{\A[A-Za-z0-9_/.:=!?-]+\z}

Instance Method Summary collapse

Methods inherited from Stage

#analysis, #analysis_options, #call, #finish, #fixpoint?, #needs_analysis?, new

Methods included from SourcePatcher

#apply_patches, #mk, #src, #verify_parses

Instance Method Details

#collect(ctx, patches) ⇒ void

This method returns an undefined value.

Parameters:



16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/ryac/pipeline/spelling_shorten.rb', line 16

def collect(ctx, patches)
  AstUtils.each_node(ctx.ast) do |node|
    case node
    when Prism::ArrayNode
      try_percent_array(node, patches)
    when Prism::GlobalVariableReadNode, Prism::GlobalVariableWriteNode
      short = GvarRenameMapping::PERL_SPELLINGS[node.name]
      if short
        loc = node.is_a?(Prism::GlobalVariableWriteNode) ? node.name_loc : node.location
        patches << { start: loc.start_offset, end: loc.end_offset, replacement: short }
      end
    end
  end
end

#plain?(node, klass) ⇒ Boolean

Parameters:

  • node (Prism::Node)
  • klass (Class)

Returns:

  • (Boolean)


55
56
57
# File 'lib/ryac/pipeline/spelling_shorten.rb', line 55

def plain?(node, klass)
  node.is_a?(klass) && SAFE_WORD.match?(node.unescaped) # steep:ignore NoMethod
end

#try_percent_array(node, patches) ⇒ void

This method returns an undefined value.

Parameters:

  • node (Prism::ArrayNode)
  • patches (Array[patch_entry])


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/ryac/pipeline/spelling_shorten.rb', line 33

def try_percent_array(node, patches)
  return unless node.opening == '['

  elements = node.elements
  return if elements.empty?

  sigil = if elements.all? { |e| plain?(e, Prism::SymbolNode) }
            '%i'
          elsif elements.all? { |e| plain?(e, Prism::StringNode) }
            '%w'
          end
  return unless sigil

  # Both node types carry their text as unescaped; SAFE_WORD already
  # guaranteed the text survives a percent literal verbatim.
  words = elements.map { |e| e.unescaped } # steep:ignore NoMethod
  new_size = 4 + words.sum(&:bytesize) + words.size - 1
  return unless new_size < node.location.length

  patches << mk(node, "#{sigil}[#{words.join(' ')}]")
end