Class: Ryac::Pipeline::EndlessMethod
- Defined in:
- lib/ryac/pipeline/endless_method.rb,
sig/ryac/pipeline/endless_method.rbs
Instance Method Summary collapse
- #collect(ctx, patches) ⇒ void
-
#fixpoint? ⇒ Boolean
A conversion can expose another convertible def (nested singles), so this runs to a fixed point.
- #keyword_logical?(node, source) ⇒ Boolean
- #try_def(node, source) ⇒ String?
- #walk(node, source, patches) ⇒ void
Methods inherited from Stage
#analysis, #analysis_options, #call, #finish, #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.
10 11 12 |
# File 'lib/ryac/pipeline/endless_method.rb', line 10 def collect(ctx, patches) walk(ctx.ast, ctx.source, patches) end |
#fixpoint? ⇒ Boolean
A conversion can expose another convertible def (nested singles), so this runs to a fixed point.
8 |
# File 'lib/ryac/pipeline/endless_method.rb', line 8 def fixpoint? = true |
#keyword_logical?(node, source) ⇒ Boolean
52 53 54 55 56 57 |
# File 'lib/ryac/pipeline/endless_method.rb', line 52 def keyword_logical?(node, source) return false unless node.is_a?(Prism::AndNode) || node.is_a?(Prism::OrNode) op = source.byteslice(node.operator_loc.start_offset, node.operator_loc.length) op == 'and' || op == 'or' end |
#try_def(node, source) ⇒ String?
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/ryac/pipeline/endless_method.rb', line 26 def try_def(node, source) body_node = node.body return nil unless body_node.is_a?(Prism::StatementsNode) return nil if AstUtils.setter_def_name?(node.name) stmts = body_node.body return nil if stmts.any? { |s| s.is_a?(Prism::MultiWriteNode) } body = src(source, body_node) if stmts.size > 1 body = "(#{body})" elsif (stmt = stmts.first) if keyword_logical?(stmt, source) || AstUtils.modifier_control_flow?(stmt) || AstUtils.match_rebind?(stmt) body = "(#{body})" end end header_end = body_node.location.start_offset # the def header range is always inside the source, so byteslice is non-nil header = source.byteslice(node.location.start_offset, header_end - node.location.start_offset).chomp(';') # steep:ignore NoMethod "#{header} =#{body}" end |
#walk(node, source, patches) ⇒ void
This method returns an undefined value.
16 17 18 19 20 21 22 23 24 |
# File 'lib/ryac/pipeline/endless_method.rb', line 16 def walk(node, source, patches) if node.is_a?(Prism::DefNode) && node.end_keyword_loc if (replacement = try_def(node, source)) patches << mk(node, replacement) return end end node.compact_child_nodes.each { |child| walk(child, source, patches) } end |