node_mutation 1.16.0 → 1.17.1
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 +4 -4
- data/CHANGELOG.md +8 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +9 -3
- data/README.md +1 -1
- data/lib/node_mutation/{parser_adapter.rb → adapter/parser.rb} +2 -37
- data/lib/node_mutation/adapter/syntax_tree.rb +118 -0
- data/lib/node_mutation/adapter.rb +2 -0
- data/lib/node_mutation/version.rb +1 -1
- data/lib/node_mutation.rb +2 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7b6c582369f095034122ac0dc0d1cafaba27a86049bb80c36b1d8f50dc8876c
|
4
|
+
data.tar.gz: d81a61d2316dad6242b81df48b61752459638e44c03935af6f618b006f5fa339
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f16a4e2b54ac9820c35e3d0bd31b2d3b6a23a08144e8a2486d8093fea95087e2b75a27924af69908ba4c6c6f88f0bcd56d5a9ea944fbb395ae422b18e0fff2b
|
7
|
+
data.tar.gz: e2a1ea1260c204562d957a7d756811c565212e56c6660d7e03c90b15341b03728859fa3158fce7d51ec50ad30cbb7c070606698b548b6f4fa3ca9fe73a27235c
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
node_mutation (1.
|
4
|
+
node_mutation (1.17.1)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -34,10 +34,11 @@ GEM
|
|
34
34
|
notiffany (0.1.3)
|
35
35
|
nenv (~> 0.1)
|
36
36
|
shellany (~> 0.0)
|
37
|
-
parser (3.2.1
|
37
|
+
parser (3.2.2.1)
|
38
38
|
ast (~> 2.4.1)
|
39
|
-
parser_node_ext (1.
|
39
|
+
parser_node_ext (1.1.0)
|
40
40
|
parser
|
41
|
+
prettier_print (1.2.1)
|
41
42
|
pry (0.14.1)
|
42
43
|
coderay (~> 1.1)
|
43
44
|
method_source (~> 1.0)
|
@@ -59,6 +60,10 @@ GEM
|
|
59
60
|
rspec-support (~> 3.11.0)
|
60
61
|
rspec-support (3.11.0)
|
61
62
|
shellany (0.0.1)
|
63
|
+
syntax_tree (6.1.1)
|
64
|
+
prettier_print (>= 1.2.0)
|
65
|
+
syntax_tree_ext (0.3.0)
|
66
|
+
syntax_tree
|
62
67
|
thor (1.2.1)
|
63
68
|
|
64
69
|
PLATFORMS
|
@@ -74,6 +79,7 @@ DEPENDENCIES
|
|
74
79
|
parser_node_ext
|
75
80
|
rake (~> 13.0)
|
76
81
|
rspec (~> 3.0)
|
82
|
+
syntax_tree_ext
|
77
83
|
|
78
84
|
BUNDLED WITH
|
79
85
|
2.3.7
|
data/README.md
CHANGED
@@ -74,7 +74,7 @@ we define an [Adapter](https://github.com/xinminlabs/node-mutation-ruby/blob/mai
|
|
74
74
|
if you implement the Adapter interface, you can set it as NodeMutation's adapter.
|
75
75
|
|
76
76
|
```ruby
|
77
|
-
NodeMutation.configure(adapter:
|
77
|
+
NodeMutation.configure(adapter: SyntaxTreeAdapter.new) // default is ParserAdapter
|
78
78
|
```
|
79
79
|
|
80
80
|
### strategy
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'parser'
|
4
|
+
require 'parser_node_ext'
|
4
5
|
|
5
6
|
class NodeMutation::ParserAdapter < NodeMutation::Adapter
|
6
7
|
def get_source(node)
|
@@ -111,24 +112,6 @@ class NodeMutation::ParserAdapter < NodeMutation::Adapter
|
|
111
112
|
NodeMutation::Struct::Range.new(node.loc.begin.begin_pos, node.loc.end.end_pos)
|
112
113
|
end
|
113
114
|
else
|
114
|
-
if node.type == :hash && child_name.to_s.end_with?('_pair')
|
115
|
-
pair_node = node.pairs.find { |pair| pair.key.to_value.to_s == child_name.to_s[0..-6] }
|
116
|
-
raise NodeMutation::MethodNotSupported,
|
117
|
-
"#{direct_child_name} is not supported for #{get_source(node)}" unless pair_node
|
118
|
-
return child_node_range(pair, nested_child_name) if nested_child_name
|
119
|
-
|
120
|
-
return NodeMutation::Struct::Range.new(pair_node.loc.expression.begin_pos, pair_node.loc.expression.end_pos)
|
121
|
-
end
|
122
|
-
|
123
|
-
if node.type == :hash && child_name.to_s.end_with?('_value')
|
124
|
-
pair_node = node.pairs.find { |pair| pair.key.to_value.to_s == child_name.to_s[0..-7] }
|
125
|
-
raise NodeMutation::MethodNotSupported,
|
126
|
-
"#{direct_child_name} is not supported for #{get_source(node)}" unless pair_node
|
127
|
-
return child_node_range(pair.value, nested_child_name) if nested_child_name
|
128
|
-
|
129
|
-
return NodeMutation::Struct::Range.new(pair_node.value.loc.expression.begin_pos, pair_node.value.loc.expression.end_pos)
|
130
|
-
end
|
131
|
-
|
132
115
|
raise NodeMutation::MethodNotSupported,
|
133
116
|
"#{direct_child_name} is not supported for #{get_source(node)}" unless node.respond_to?(direct_child_name)
|
134
117
|
|
@@ -206,24 +189,6 @@ class NodeMutation::ParserAdapter < NodeMutation::Adapter
|
|
206
189
|
return child_node
|
207
190
|
end
|
208
191
|
|
209
|
-
if node.is_a?(Parser::AST::Node) && node.type == :hash && direct_child_name.end_with?('_pair')
|
210
|
-
pair_node = node.pairs.find { |pair| pair.key.to_value.to_s == direct_child_name[0..-6] }
|
211
|
-
raise NodeMutation::MethodNotSupported,
|
212
|
-
"#{direct_child_name} is not supported for #{get_source(node)}" unless pair_node
|
213
|
-
return child_node_by_name(pair_node, nested_child_name) if nested_child_name
|
214
|
-
|
215
|
-
return pair_node
|
216
|
-
end
|
217
|
-
|
218
|
-
if node.is_a?(Parser::AST::Node) && node.type == :hash && direct_child_name.end_with?('_value')
|
219
|
-
pair_node = node.pairs.find { |pair| pair.key.to_value.to_s == direct_child_name[0..-7] }
|
220
|
-
raise NodeMutation::MethodNotSupported,
|
221
|
-
"#{direct_child_name} is not supported for #{get_source(node)}" unless pair_node
|
222
|
-
return child_node_by_name(pair_node.value, nested_child_name) if nested_child_name
|
223
|
-
|
224
|
-
return pair_node.value
|
225
|
-
end
|
226
|
-
|
227
192
|
if node.respond_to?(direct_child_name)
|
228
193
|
child_node = node.send(direct_child_name)
|
229
194
|
elsif direct_child_name.include?('(') && direct_child_name.include?(')')
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'syntax_tree'
|
4
|
+
require 'syntax_tree_ext'
|
5
|
+
|
6
|
+
class NodeMutation::SyntaxTreeAdapter < NodeMutation::Adapter
|
7
|
+
def get_source(node)
|
8
|
+
if node.is_a?(Array)
|
9
|
+
return node.first.source[node.first.location.start_char...node.last.location.end_char]
|
10
|
+
end
|
11
|
+
|
12
|
+
node.source[node.location.start_char...node.location.end_char]
|
13
|
+
end
|
14
|
+
|
15
|
+
def rewritten_source(node, code)
|
16
|
+
code.gsub(/{{(.+?)}}/m) do
|
17
|
+
old_code = Regexp.last_match(1)
|
18
|
+
evaluated = child_node_by_name(node, old_code)
|
19
|
+
case evaluated
|
20
|
+
when SyntaxTree::Node
|
21
|
+
get_source(evaluated)
|
22
|
+
when Array
|
23
|
+
if evaluated.size > 0
|
24
|
+
source = get_source(evaluated)
|
25
|
+
lines = source.split "\n"
|
26
|
+
lines_count = lines.length
|
27
|
+
if lines_count > 1 && lines_count == evaluated.size
|
28
|
+
new_code = []
|
29
|
+
lines.each_with_index { |line, index|
|
30
|
+
new_code << (index == 0 ? line : line[evaluated.first.indent - 2..-1])
|
31
|
+
}
|
32
|
+
new_code.join("\n")
|
33
|
+
else
|
34
|
+
source
|
35
|
+
end
|
36
|
+
end
|
37
|
+
when String, Symbol, Integer, Float
|
38
|
+
evaluated
|
39
|
+
when NilClass
|
40
|
+
''
|
41
|
+
else
|
42
|
+
raise "can not parse \"#{code}\""
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def child_node_range(node, child_name)
|
48
|
+
child_node = child_node_by_name(node, child_name)
|
49
|
+
return nil if child_node.nil?
|
50
|
+
|
51
|
+
if child_node.is_a?(Array)
|
52
|
+
return NodeMutation::Struct::Range.new(child_node.first.location.start_char, child_node.last.location.end_char)
|
53
|
+
end
|
54
|
+
|
55
|
+
return NodeMutation::Struct::Range.new(child_node.location.start_char, child_node.location.end_char)
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_start(node, child_name = nil)
|
59
|
+
node = child_node_by_name(node, child_name) if child_name
|
60
|
+
node.location.start_char
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_end(node, child_name = nil)
|
64
|
+
node = child_node_by_name(node, child_name) if child_name
|
65
|
+
node.location.end_char
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_start_loc(node, child_name = nil)
|
69
|
+
node = child_node_by_name(node, child_name) if child_name
|
70
|
+
NodeMutation::Struct::Location.new(node.location.start_line, node.location.start_column)
|
71
|
+
end
|
72
|
+
|
73
|
+
def get_end_loc(node, child_name = nil)
|
74
|
+
node = child_node_by_name(node, child_name) if child_name
|
75
|
+
NodeMutation::Struct::Location.new(node.location.end_line, node.location.end_column)
|
76
|
+
end
|
77
|
+
|
78
|
+
def get_indent(node)
|
79
|
+
node.location.start_column
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def child_node_by_name(node, child_name)
|
85
|
+
direct_child_name, nested_child_name = child_name.to_s.split('.', 2)
|
86
|
+
|
87
|
+
if node.is_a?(Array)
|
88
|
+
if direct_child_name =~ INDEX_REGEXP
|
89
|
+
child_node = node[direct_child_name.to_i]
|
90
|
+
raise NodeMutation::MethodNotSupported,
|
91
|
+
"#{direct_child_name} is not supported for #{get_source(node)}" unless child_node
|
92
|
+
return child_node_by_name(child_node, nested_child_name) if nested_child_name
|
93
|
+
|
94
|
+
return child_node
|
95
|
+
end
|
96
|
+
|
97
|
+
raise NodeMutation::MethodNotSupported,
|
98
|
+
"#{direct_child_name} is not supported for #{get_source(node)}" unless node.respond_to?(direct_child_name)
|
99
|
+
|
100
|
+
child_node = node.send(direct_child_name)
|
101
|
+
return child_node_by_name(child_node, nested_child_name) if nested_child_name
|
102
|
+
|
103
|
+
return child_node
|
104
|
+
end
|
105
|
+
|
106
|
+
if node.respond_to?(direct_child_name)
|
107
|
+
child_node = node.send(direct_child_name)
|
108
|
+
elsif direct_child_name.include?('(') && direct_child_name.include?(')')
|
109
|
+
child_node = node.instance_eval(direct_child_name)
|
110
|
+
else
|
111
|
+
raise NodeMutation::MethodNotSupported, "#{direct_child_name} is not supported for #{get_source(node)}"
|
112
|
+
end
|
113
|
+
|
114
|
+
return child_node_by_name(child_node, nested_child_name) if nested_child_name
|
115
|
+
|
116
|
+
child_node
|
117
|
+
end
|
118
|
+
end
|
data/lib/node_mutation.rb
CHANGED
@@ -7,7 +7,8 @@ class NodeMutation
|
|
7
7
|
class ConflictActionError < StandardError; end
|
8
8
|
|
9
9
|
autoload :Adapter, "node_mutation/adapter"
|
10
|
-
autoload :ParserAdapter, "node_mutation/
|
10
|
+
autoload :ParserAdapter, "node_mutation/adapter/parser"
|
11
|
+
autoload :SyntaxTreeAdapter, "node_mutation/adapter/syntax_tree"
|
11
12
|
autoload :Action, 'node_mutation/action'
|
12
13
|
autoload :AppendAction, 'node_mutation/action/append_action'
|
13
14
|
autoload :DeleteAction, 'node_mutation/action/delete_action'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: node_mutation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.17.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Huang
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: ast node mutation apis
|
14
14
|
email:
|
@@ -37,7 +37,8 @@ files:
|
|
37
37
|
- lib/node_mutation/action/replace_action.rb
|
38
38
|
- lib/node_mutation/action/replace_with_action.rb
|
39
39
|
- lib/node_mutation/adapter.rb
|
40
|
-
- lib/node_mutation/
|
40
|
+
- lib/node_mutation/adapter/parser.rb
|
41
|
+
- lib/node_mutation/adapter/syntax_tree.rb
|
41
42
|
- lib/node_mutation/result.rb
|
42
43
|
- lib/node_mutation/strategy.rb
|
43
44
|
- lib/node_mutation/struct.rb
|