masamune-ast 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1ee5dca320a96035fcea4f73effbc3fceff2ee531808bf94d99aa21086186ce5
4
- data.tar.gz: 3f170766c1e97a15e9c550e61fc5f2048b28b48a5f12e2b4841a31b0dad6ebbb
3
+ metadata.gz: a00f60e535cf2096a37cd6efd639aa7c132c70e58c3b422a23538128368b5c85
4
+ data.tar.gz: 5d548fc4b9d5cf25c1099a2b446542f57342694d7b414052df004dcd2cf311c2
5
5
  SHA512:
6
- metadata.gz: 7650eff09ecb23034c236363ee70a971f003736a967f8efd5ae8f36e68d598f73a4239a38d839f478b4aa6b36662d7114834dedf501acfed6bd2adcb6494890e
7
- data.tar.gz: fbd0fc4a505b03dc38304abdfadd9cb31fccf5f746bbb325056c63e9a790d7814bd7292d40c95da7441731cf3ab0613f2e9879c4c27f07f61445370a499665a2
6
+ metadata.gz: c80bcefac510bfd4103d56fd13f39a46d1e4531eceb678d620709b97fe0c941f20f1e7ffddc6058e77aab46ab093d1d4ba768b6860649c5a57197e36f89bf109
7
+ data.tar.gz: 731a46f94d655a820acdd949d7d7fa03f3fc37277858b5b5daea3c0c13444720b3b1ca829d0f304d5aecb3f390e3055168503ce6655653268cb89fcf19ab28e3
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- masamune-ast (1.1.0)
4
+ masamune-ast (1.1.1)
5
5
  activesupport
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -13,8 +13,38 @@ Or add the following to your Gemfile and run `bundle install`
13
13
  gem "masamune-ast"
14
14
  ```
15
15
 
16
+ Then require the gem in a file like this:
17
+ ```ruby
18
+ require "masamune"
19
+ ```
20
+
16
21
  ## Usage
17
22
 
23
+ Isolate and replace variables, methods, or strings in your Ruby source code according to the specific tokens allotted when the code is intially parsed:
24
+ ```ruby
25
+ code = <<~CODE
26
+ 10.times do |n|
27
+ puts n
28
+ end
29
+
30
+ def n
31
+ "n"
32
+ end
33
+ CODE
34
+
35
+ msmn = Masamune::AbstractSyntaxTree.new(code)
36
+ msmn.replace(type: :variables, old_token: "n", new_token: "foo")
37
+
38
+ # This will produce the following code in string form.
39
+ 10.times do |foo|
40
+ puts foo
41
+ end
42
+
43
+ def n
44
+ "n"
45
+ end
46
+ ```
47
+
18
48
  Pinpoint variables and methods in your source code even when other tokens have the same or similar spelling:
19
49
  ```ruby
20
50
  code = <<CODE
@@ -14,7 +14,7 @@ module Masamune
14
14
  # nice to find out and implement it document/implement it somewhere.
15
15
  def extract_data_nodes
16
16
  @contents[1][1].map do |content|
17
- Masamune::AbstractSyntaxTree::DataNode.new(content, @ast_id)
17
+ DataNode.new(content, @ast_id)
18
18
  end
19
19
  end
20
20
  end
@@ -11,7 +11,7 @@ module Masamune
11
11
 
12
12
  def params
13
13
  # This node should exist already, so we search for it in the ast object.
14
- block_var = Masamune::AbstractSyntaxTree::BlockVar.new(contents[1], ast_id)
14
+ block_var = BlockVar.new(contents[1], ast_id)
15
15
  ast.node_list.find {|node| node.contents == block_var.contents}
16
16
  end
17
17
  end
@@ -9,7 +9,7 @@ module Masamune
9
9
 
10
10
  def extract_data_nodes
11
11
  [
12
- Masamune::AbstractSyntaxTree::DataNode.new(@contents.last, @ast_id)
12
+ DataNode.new(@contents.last, @ast_id)
13
13
  ]
14
14
  end
15
15
  end
@@ -9,7 +9,7 @@ module Masamune
9
9
 
10
10
  def extract_data_nodes
11
11
  [
12
- Masamune::AbstractSyntaxTree::DataNode.new(@contents[1], @ast_id)
12
+ DataNode.new(@contents[1], @ast_id)
13
13
  ]
14
14
  end
15
15
  end
@@ -11,7 +11,7 @@ module Masamune
11
11
 
12
12
  def params
13
13
  # This node should exist already, so we search for it in the ast object.
14
- block_var = Masamune::AbstractSyntaxTree::BlockVar.new(contents[1], ast_id)
14
+ block_var = BlockVar.new(contents[1], ast_id)
15
15
  ast.node_list.find {|node| node.contents == block_var.contents}
16
16
  end
17
17
  end
@@ -14,7 +14,7 @@ module Masamune
14
14
  # to ensure that it's being handled properly.
15
15
  unless @contents[1].nil?
16
16
  @contents[1].map do |content|
17
- Masamune::AbstractSyntaxTree::DataNode.new(content, @ast_id)
17
+ DataNode.new(content, @ast_id)
18
18
  end
19
19
  end
20
20
  end
@@ -9,7 +9,7 @@ module Masamune
9
9
 
10
10
  def extract_data_nodes
11
11
  [
12
- Masamune::AbstractSyntaxTree::DataNode.new(@contents[1], @ast_id)
12
+ DataNode.new(@contents[1], @ast_id)
13
13
  ]
14
14
  end
15
15
  end
@@ -9,7 +9,7 @@ module Masamune
9
9
 
10
10
  def extract_data_nodes
11
11
  [
12
- Masamune::AbstractSyntaxTree::DataNode.new(@contents[1], @ast_id)
12
+ DataNode.new(@contents[1], @ast_id)
13
13
  ]
14
14
  end
15
15
  end
@@ -11,7 +11,7 @@ module Masamune
11
11
 
12
12
  def extract_data_nodes
13
13
  [
14
- Masamune::AbstractSyntaxTree::DataNode.new(@contents[1], @ast_id)
14
+ DataNode.new(@contents[1], @ast_id)
15
15
  ]
16
16
  end
17
17
  end
@@ -9,7 +9,7 @@ module Masamune
9
9
 
10
10
  def extract_data_nodes
11
11
  [
12
- Masamune::AbstractSyntaxTree::DataNode.new(@contents[1], @ast_id)
12
+ DataNode.new(@contents[1], @ast_id)
13
13
  ]
14
14
  end
15
15
  end
@@ -1,13 +1,14 @@
1
1
  module Masamune
2
2
  class AbstractSyntaxTree
3
- attr_reader :tree
3
+ attr_reader :code, :tree
4
4
  attr_accessor :node_list, :data_node_list, :lex_nodes
5
5
 
6
6
  def initialize(code)
7
+ @code = code
7
8
  @tree = Ripper.sexp(code)
8
9
  raw_lex_nodes = Ripper.lex(code)
9
10
  @lex_nodes = raw_lex_nodes.map do |lex_node|
10
- Masamune::LexNode.new(raw_lex_nodes.index(lex_node), lex_node, self.__id__)
11
+ LexNode.new(raw_lex_nodes.index(lex_node), lex_node, self.__id__)
11
12
  end
12
13
 
13
14
  @node_list = []
@@ -21,7 +22,7 @@ module Masamune
21
22
  msmn_node = klass.new(tree_node, self.__id__)
22
23
  else
23
24
  # Create a general node if the node is a single value.
24
- msmn_node = Masamune::AbstractSyntaxTree::Node.new(tree_node, self.__id__)
25
+ msmn_node = Node.new(tree_node, self.__id__)
25
26
  end
26
27
 
27
28
  # Register nodes and any data nodes housed within it.
@@ -83,37 +84,48 @@ module Masamune
83
84
  # Ensure the classes are in an array
84
85
  token_classes = [token_classes].flatten
85
86
 
86
- var_nodes = []
87
+ nodes = []
87
88
  token_classes.each do |klass|
88
- var_nodes << @node_list.select {|node| node.class == klass}
89
+ nodes << @node_list.select {|node| node.class == klass}
89
90
  end
90
91
 
91
92
  # Searching for multiple classes will yield multi-dimensional arrays,
92
93
  # so we ensure everything is flattened out before moving forward.
93
- var_nodes.flatten!
94
+ nodes.flatten!
94
95
 
95
96
  if token
96
- var_nodes = var_nodes.select {|node| node.data_nodes.first.token == token}.flatten
97
+ # TODO: This most likely shouldn't be `node.data_nodes.first`.
98
+ # There are probably more data_nodes we need to check depending on the node class.
99
+ nodes = nodes.select {|node| node.data_nodes.first.token == token}.flatten
97
100
  end
98
101
 
99
102
  final_result = []
100
- var_nodes.each do |node|
101
- node.data_nodes.each {|dn| final_result << dn.position_and_token}
103
+ nodes.each do |node|
104
+ node.data_nodes.each {|dn| final_result << dn.position_and_token} if node.data_nodes
102
105
  end
103
106
 
104
- Masamune::AbstractSyntaxTree::DataNode.order_results_by_position(final_result)
107
+ DataNode.order_results_by_position(final_result)
108
+ end
109
+
110
+ def replace(type:, old_token:, new_token:)
111
+ Slasher.replace(
112
+ type: type,
113
+ old_token: old_token,
114
+ new_token: new_token,
115
+ code: @code,
116
+ ast: self
117
+ )
105
118
  end
106
119
 
107
120
  private
108
121
 
109
122
  def get_node_class(type)
110
123
  begin
111
- class_name = "Masamune::AbstractSyntaxTree::#{type.to_s.camelize}"
112
- klass = class_name.constantize
124
+ "Masamune::AbstractSyntaxTree::#{type.to_s.camelize}".constantize
113
125
  rescue NameError
114
126
  # For all other nodes that we haven't covered yet, we just make a general class.
115
127
  # We can worry about adding the classes for other nodes as we go.
116
- msmn_node = Masamune::AbstractSyntaxTree::Node
128
+ Node
117
129
  end
118
130
  end
119
131
  end
@@ -0,0 +1,32 @@
1
+ module Masamune
2
+ module Slasher
3
+ def self.replace(type:, old_token:, new_token:, code:, ast:)
4
+ # `type` can either be a method from the ast like `method_definitions`,
5
+ # or it can be a list of Masamune::AbstractSyntaxTree node classes.
6
+ position_and_token_ary = if type.is_a?(Symbol) && ast.respond_to?(type)
7
+ ast.send(type)
8
+ elsif type.is_a?(Array)
9
+ type.map {|klass| ast.find_nodes(klass)}.flatten
10
+ end
11
+
12
+ tokens_to_replace = position_and_token_ary.select do |pos_and_tok|
13
+ pos_and_tok[:token] == old_token
14
+ end
15
+
16
+ # Build from lex nodes
17
+ result = ast.lex_nodes.map do |lex_node|
18
+ match_found = false
19
+ tokens_to_replace.each do |position_and_token|
20
+ if position_and_token[:position] == lex_node.position
21
+ match_found = true
22
+ break
23
+ end
24
+ end
25
+
26
+ match_found ? new_token : lex_node.token
27
+ end
28
+
29
+ result.join
30
+ end
31
+ end
32
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Masamune
4
- VERSION = "1.1.0"
4
+ VERSION = "1.1.1"
5
5
  end
data/lib/masamune.rb CHANGED
@@ -4,6 +4,7 @@ require_relative "masamune/version"
4
4
  require "ripper"
5
5
  require "active_support/core_ext/string/inflections"
6
6
  require "masamune/lex_node"
7
+ require "masamune/slasher"
7
8
  require "masamune/abstract_syntax_tree"
8
9
  require "masamune/abstract_syntax_tree/node"
9
10
  require "masamune/abstract_syntax_tree/data_node"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: masamune-ast
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabriel Zayas
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-02 00:00:00.000000000 Z
11
+ date: 2023-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -55,7 +55,7 @@ files:
55
55
  - lib/masamune/abstract_syntax_tree/var_ref.rb
56
56
  - lib/masamune/abstract_syntax_tree/vcall.rb
57
57
  - lib/masamune/lex_node.rb
58
- - lib/masamune/slicer.rb
58
+ - lib/masamune/slasher.rb
59
59
  - lib/masamune/version.rb
60
60
  - sig/masamune.rbs
61
61
  homepage: https://www.github.com/gazayas/masamune-ast
@@ -1,19 +0,0 @@
1
- module Masamune
2
- module Slicer
3
- def initialize(ast)
4
- @ast = ast
5
- end
6
-
7
- # TODO
8
-
9
- # def replace(type, token)
10
- # @ast.search(type, token)
11
- # end
12
-
13
- # def insert_inside_block
14
- # end
15
-
16
- # def append_to_block
17
- # end
18
- end
19
- end