Class: Ryac::Pipeline::VariableRenamer

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

Overview

Configurable variable renaming stage. Default (no features): renames locals only. features: { keywords: true } → locals + keywords (Level 3) features: { keywords: true, ivars: true, cvars: true, gvars: true } → all variables (Level 4)

Constant Summary collapse

FEATURES =

Returns:

  • (Hash[Symbol, bool])
{ locals: true, keywords: false, ivars: false, cvars: false, gvars: false }.freeze

Instance Method Summary collapse

Methods included from RenamePatcher

#patch_assoc, #patch_block_param_node, #patch_block_params, #patch_def_params, #patch_for_node, #patch_keyword_hash, #patch_keyword_params, #patch_keyword_rest, #patch_multi_target_params, #patch_named_param, #patch_optional_params, #patch_post_params, #patch_required_params, #patch_rest_param, #patch_variable, #patch_variable_name_only, #prism_location_key, #walk_prism

Methods inherited from Stage

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

Methods included from SourcePatcher

#apply_patches, #mk, #src, #verify_parses

Constructor Details

#initialize(features: {}) ⇒ VariableRenamer

Returns a new instance of VariableRenamer.

Parameters:

  • features: (Hash[Symbol, bool]) (defaults to: {})


16
17
18
# File 'lib/ryac/pipeline/variable_renamer.rb', line 16

def initialize(features: {})
  @features = FEATURES.merge(features)
end

Instance Method Details

#build_rename_map(analysis) ⇒ Hash[location_key, String]

Parameters:

Returns:

  • (Hash[location_key, String])


29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/ryac/pipeline/variable_renamer.rb', line 29

def build_rename_map(analysis)
  map = {} #: Hash[location_key, String]
  map.merge!(analysis.local_rename_entries) if @features[:locals]
  map.merge!(analysis.keyword_rename_entries) if @features[:keywords]
  if @features[:ivars]
    map.merge!(analysis.ivar_rename_entries)
    map.merge!(analysis.attr_ivar_entries) if @features[:attr_ivars]
  end
  map.merge!(analysis.cvar_rename_entries) if @features[:cvars]
  map.merge!(analysis.gvar_rename_entries) if @features[:gvars]
  map
end

#collect(ctx, patches) ⇒ void

This method returns an undefined value.

Parameters:



20
21
22
23
24
25
# File 'lib/ryac/pipeline/variable_renamer.rb', line 20

def collect(ctx, patches)
  analysis = analysis(ctx)
  rename_map = build_rename_map(analysis)
  block_param_names_map = analysis.block_param_names_map
  collect_patches(ctx.ast, patches, analysis, rename_map, block_param_names_map)
end

#collect_patches(node, patches, analysis, rename_map, block_param_names_map) ⇒ void

This method returns an undefined value.

Parameters:

  • node (Prism::Node)
  • patches (Array[patch_entry])
  • analysis (AnalysisResult)
  • rename_map (Hash[location_key, String])
  • block_param_names_map (Hash[location_key, Hash[Symbol, String]])


42
43
44
45
# File 'lib/ryac/pipeline/variable_renamer.rb', line 42

def collect_patches(node, patches, analysis, rename_map, block_param_names_map)
  callback = proc { |subnode| handle_node(subnode, patches, analysis, rename_map, block_param_names_map) } #: ^(Prism::Node) -> (Symbol | nil)
  walk_prism(node, &callback)
end

#handle_node(subnode, patches, analysis, rename_map, block_param_names_map) ⇒ void

This method returns an undefined value.

Parameters:

  • subnode (Prism::Node)
  • patches (Array[patch_entry])
  • analysis (AnalysisResult)
  • rename_map (Hash[location_key, String])
  • block_param_names_map (Hash[location_key, Hash[Symbol, String]])


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/ryac/pipeline/variable_renamer.rb', line 47

def handle_node(subnode, patches, analysis, rename_map, block_param_names_map)
  case subnode
  # Local variables
  when Prism::LocalVariableReadNode
    patch_variable(subnode, patches, rename_map)
  when Prism::LocalVariableWriteNode
    patch_variable_name_only(subnode, patches, rename_map)
  when Prism::LocalVariableTargetNode
    patch_variable(subnode, patches, rename_map)
  when Prism::LocalVariableOperatorWriteNode,
       Prism::LocalVariableOrWriteNode,
       Prism::LocalVariableAndWriteNode
    patch_variable_name_only(subnode, patches, rename_map)

  # Instance variables
  when Prism::InstanceVariableReadNode
    patch_variable(subnode, patches, rename_map) if @features[:ivars]
  when Prism::InstanceVariableWriteNode
    patch_variable_name_only(subnode, patches, rename_map) if @features[:ivars]
  when Prism::InstanceVariableOperatorWriteNode,
       Prism::InstanceVariableOrWriteNode,
       Prism::InstanceVariableAndWriteNode
    patch_variable_name_only(subnode, patches, rename_map) if @features[:ivars]
  when Prism::InstanceVariableTargetNode
    patch_variable(subnode, patches, rename_map) if @features[:ivars]

  # Class variables
  when Prism::ClassVariableReadNode
    patch_variable(subnode, patches, rename_map) if @features[:cvars]
  when Prism::ClassVariableWriteNode
    patch_variable_name_only(subnode, patches, rename_map) if @features[:cvars]
  when Prism::ClassVariableOperatorWriteNode,
       Prism::ClassVariableOrWriteNode,
       Prism::ClassVariableAndWriteNode
    patch_variable_name_only(subnode, patches, rename_map) if @features[:cvars]
  when Prism::ClassVariableTargetNode
    patch_variable(subnode, patches, rename_map) if @features[:cvars]

  # Global variables
  when Prism::GlobalVariableReadNode
    patch_variable(subnode, patches, rename_map) if @features[:gvars]
  when Prism::GlobalVariableWriteNode
    patch_variable_name_only(subnode, patches, rename_map) if @features[:gvars]
  when Prism::GlobalVariableOperatorWriteNode,
       Prism::GlobalVariableOrWriteNode,
       Prism::GlobalVariableAndWriteNode
    patch_variable_name_only(subnode, patches, rename_map) if @features[:gvars]
  when Prism::GlobalVariableTargetNode
    patch_variable(subnode, patches, rename_map) if @features[:gvars]

  # Def params
  when Prism::DefNode
    patch_def_params(subnode, patches, analysis, :param_names)

  # Block params
  when Prism::CallNode
    patch_block_params(subnode, patches, block_param_names_map)

  # For node — patch index and walk body/collection manually to avoid
  # double-patching the index via LocalVariableTargetNode handler
  when Prism::ForNode
    patch_for_node(subnode, patches, analysis, :for_index_mangled)
    callback = proc { |n| handle_node(n, patches, analysis, rename_map, block_param_names_map) } #: ^(Prism::Node) -> (Symbol | nil)
    walk_prism(subnode.collection, &callback)
    walk_prism(subnode.statements, &callback)
    :skip_children

  # Hash assoc shorthand
  when Prism::KeywordHashNode
    callback = proc { |n| handle_node(n, patches, analysis, rename_map, block_param_names_map) } #: ^(Prism::Node) -> (Symbol | nil)
    patch_keyword_hash(subnode, patches, rename_map, &callback)
    :skip_children
  when Prism::AssocNode
    patch_assoc(subnode, patches, rename_map)
  end
end

#needs_analysis? ⇒ Boolean

Returns:

  • (Boolean)


14
# File 'lib/ryac/pipeline/variable_renamer.rb', line 14

def needs_analysis? = true