mangrove 0.7.1 → 0.7.2

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.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mangrove
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kazuma Murata
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-09-12 00:00:00.000000000 Z
11
+ date: 2023-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sorbet-runtime
@@ -108,7 +108,6 @@ files:
108
108
  - hooks/pre-push
109
109
  - lib/mangrove.rb
110
110
  - lib/mangrove/control_flow/control_signal.rb
111
- - lib/mangrove/control_flow/rewriter.rb
112
111
  - lib/mangrove/option.rb
113
112
  - lib/mangrove/option/control_signal.rb
114
113
  - lib/mangrove/result.rb
@@ -1,158 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- require "parser"
5
- require "parser/current"
6
- require "unparser"
7
- require "method_source"
8
- require "sorbet-runtime"
9
-
10
- module Mangrove
11
- module ControlFlow
12
- class << self
13
- extend T::Sig
14
-
15
- sig { params(method_to_be_rewritten: T.any(Method, UnboundMethod)).returns(String) }
16
- def impl!(method_to_be_rewritten)
17
- filename, line_number = method_to_be_rewritten.source_location
18
-
19
- source = method_to_be_rewritten.source
20
- ast = Parser::CurrentRuby.parse(source)
21
- source_buffer = Parser::Source::Buffer.new("#{filename}:#{line_number}", source:)
22
- rewriter = Rewriter.new
23
- rewriter.rewrite(source_buffer, ast)
24
- end
25
- end
26
-
27
- class Rewriter < Parser::TreeRewriter
28
- CONTROL_SIGNAL = Mangrove::ControlFlow::ControlSignal
29
-
30
- def on_def(node)
31
- indent = node.location.expression.begin.column
32
- code = Unparser.unparse(with_rescue(node))
33
- indented_code = code.lines.map.with_index { |line, index| index.zero? ? line : (" " * indent) + line }
34
- replace(node.location.expression, indented_code)
35
- end
36
-
37
- def on_defs(node)
38
- indent = node.location.expression.begin.column
39
- code = Unparser.unparse(with_rescue(node))
40
- indented_code = code.lines.map.with_index { |line, index| index.zero? ? line : (" " * indent) + line }
41
- replace(node.location.expression, indented_code)
42
- end
43
-
44
- def on_block(node)
45
- indent = node.location.expression.begin.column
46
- code = Unparser.unparse(with_rescue(node))
47
- indented_code = code.lines.map.with_index { |line, index| index.zero? ? line : (" " * indent) + line }
48
- replace(node.location.expression, indented_code)
49
- end
50
-
51
- private
52
-
53
- def rescue_node(body)
54
- ::Parser::AST::Node.new(:rescue, [
55
- body,
56
- nil
57
- ])
58
- end
59
-
60
- def add_rescue_node(parent)
61
- children = parent.children.dup
62
- # nilの場合はblockをこちらで包む必要がある
63
- # nilではない場合はすでに包まれているのでこちらで包む必要はない
64
- method_body_index = children.length - 1
65
- method_body = children[method_body_index]
66
-
67
- children[method_body_index] = rescue_node(method_body)
68
- parent.updated(nil, children)
69
- end
70
-
71
- def use_rescue_node(parent)
72
- children = parent.children.dup
73
-
74
- rescue_index = children.find_index { _1.respond_to?(:type) && _1.type == :rescue }
75
-
76
- rescue_node_on_ast = children[rescue_index]
77
- updated_rescue_node_on_ast = insert_rescue_body_node(rescue_node_on_ast)
78
- children[rescue_index] = updated_rescue_node_on_ast
79
-
80
- parent.updated(nil, children)
81
- end
82
-
83
- def insert_rescue_body_node(rescue_node)
84
- rescue_node_children = rescue_node.children.dup
85
- rescue_body_node_index = rescue_node_children.find_index { _1.respond_to?(:type) && _1.type == :resbody }
86
-
87
- # when rescue is newly inserted
88
- if rescue_body_node_index.nil?
89
- rescue_body_node_index = rescue_node_children.length - 1
90
- end
91
-
92
- rescue_node_children.insert(rescue_body_node_index, rescue_body_node)
93
- rescue_node.updated(nil, rescue_node_children)
94
- end
95
-
96
- def use_ensure_node(ensure_node)
97
- # ensureのchildrenの最後から2番目(最後のrescue)に追加する
98
-
99
- ensure_node_children = ensure_node.children.dup
100
-
101
- rescue_index = ensure_node_children.find_index { _1.respond_to?(:type) && _1.type == :rescue }
102
-
103
- if rescue_index.nil?
104
- ensure_node = add_rescue_node(ensure_node)
105
- end
106
-
107
- use_rescue_node(ensure_node)
108
- end
109
-
110
- def with_rescue(parent)
111
- children = parent.children.dup
112
- ensure_index = children.find_index { _1.respond_to?(:type) && _1.type == :ensure }
113
-
114
- if ensure_index.nil?
115
- rescue_index = children.find_index { _1.respond_to?(:type) && _1.type == :rescue }
116
-
117
- if rescue_index.nil?
118
- parent = add_rescue_node(parent)
119
- end
120
-
121
- use_rescue_node(parent)
122
- else
123
- updated_ensure_node = use_ensure_node(children[ensure_index])
124
- children[ensure_index] = updated_ensure_node
125
- parent.updated(nil, children)
126
- end
127
- end
128
-
129
- def rescue_body_node
130
- control_flow = Mangrove::ControlFlow::ControlSignal
131
-
132
- ::Parser::AST::Node.new(:resbody, [
133
- ::Parser::AST::Node.new(:array, [
134
- ::Parser::AST::Node.new(:const, [nil, control_flow.to_s])
135
- ]),
136
- ::Parser::AST::Node.new(:lvasgn, [:exception]),
137
- ::Parser::AST::Node.new(:send, [
138
- ::Parser::AST::Node.new(:const, [
139
- ::Parser::AST::Node.new(:const, [
140
- ::Parser::AST::Node.new(:const, %i[
141
- cbase
142
- Mangrove
143
- ]),
144
- :Result
145
- ]),
146
- :Err
147
- ]),
148
- :new,
149
- ::Parser::AST::Node.new(:send, [
150
- ::Parser::AST::Node.new(:lvar, [:exception]),
151
- :inner_value
152
- ])
153
- ])
154
- ])
155
- end
156
- end
157
- end
158
- end