Class: R3EXS::StringsInjector
- Inherits:
-
Prism::Visitor
- Object
- Prism::Visitor
- R3EXS::StringsInjector
- Defined in:
- lib/R3EXS/ast.rb
Overview
用来替换源码里面的字符串和符号
Defined Under Namespace
Classes: Location
Instance Attribute Summary collapse
-
#content_loc ⇒ Array<Location>
readonly
字符串在二进制源文件中的位置.
-
#root_node ⇒ Prism::Node
readonly
AST 根节点.
-
#script ⇒ String
readonly
Ruby 源码.
-
#strings_hash ⇒ Hash{String => String}
readonly
字符串翻译表.
Class Method Summary collapse
-
.inject(script, hash) ⇒ String
将 script 源码中的字符串替换成 @strings_hash 翻译后的字符串.
Instance Method Summary collapse
-
#initialize(script, hash) ⇒ StringsInjector
constructor
初始化 StringsInjector.
-
#inject ⇒ String
将 script 源码中的字符串替换成 @strings_hash 翻译后的字符串.
-
#visit_string_node(node) ⇒ void
处理类型为 StringNode 的节点.
-
#visit_symbol_node(node) ⇒ void
处理类型为 SymbolNode 的节点.
Constructor Details
#initialize(script, hash) ⇒ StringsInjector
初始化 StringsInjector
134 135 136 137 138 139 140 |
# File 'lib/R3EXS/ast.rb', line 134 def initialize(script, hash) super() @content_loc = [] @script = script @strings_hash = hash @root_node = Prism.parse(script).value end |
Instance Attribute Details
#content_loc ⇒ Array<Location> (readonly)
字符串在二进制源文件中的位置
80 81 82 |
# File 'lib/R3EXS/ast.rb', line 80 def content_loc @content_loc end |
#root_node ⇒ Prism::Node (readonly)
AST 根节点
95 96 97 |
# File 'lib/R3EXS/ast.rb', line 95 def root_node @root_node end |
#script ⇒ String (readonly)
Ruby 源码
85 86 87 |
# File 'lib/R3EXS/ast.rb', line 85 def script @script end |
Class Method Details
.inject(script, hash) ⇒ String
将 script 源码中的字符串替换成 @strings_hash 翻译后的字符串
204 205 206 207 |
# File 'lib/R3EXS/ast.rb', line 204 def self.inject(script, hash) injector = new(script, hash) injector.inject end |
Instance Method Details
#inject ⇒ String
将 script 源码中的字符串替换成 @strings_hash 翻译后的字符串
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/R3EXS/ast.rb', line 176 def inject code = [] # 首先遍历一遍,找到所有需要替换的字符串的位置 visit(@root_node) # 然后开始替换 code 中的字符串 # 先将 @content_loc 按照 start_offset 从小到大排序 @content_loc.sort_by!(&:start_offset) # 然后将 code 切片,将字符串替换成新的字符串 # 注意 Prism.parse 得到的位置是字节的偏移量,而 UTF-8 是变长编码,所以需要使用 byteslice 来切片 start_offset = 0 @content_loc.each do |loc| code << @script.byteslice(start_offset...loc.start_offset) code << @strings_hash[loc.content] start_offset = loc.start_offset + loc.length end code << @script.byteslice(start_offset..) code.join end |
#visit_string_node(node) ⇒ void
This method returns an undefined value.
处理类型为 StringNode 的节点
147 148 149 150 151 152 153 154 |
# File 'lib/R3EXS/ast.rb', line 147 def visit_string_node(node) location = node.content_loc value = location.slice if @strings_hash.key?(value) && @strings_hash[value].to_s != '' @content_loc << Location.new(location.start_offset, location.length, value) end super end |
#visit_symbol_node(node) ⇒ void
This method returns an undefined value.
处理类型为 SymbolNode 的节点
161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/R3EXS/ast.rb', line 161 def visit_symbol_node(node) location = node.value_loc # 如果 location 不为 nil,说明这个符号是一个字符串 if location value = location.slice if @strings_hash.key?(value) && @strings_hash[value].to_s != '' @content_loc << Location.new(location.start_offset, location.length, value) end end super end |