Class: R3EXS::StringsInjector
- Inherits:
-
Prism::Visitor
- Object
- Prism::Visitor
- R3EXS::StringsInjector
- Defined in:
- lib/R3EXS/ast.rb
Overview
用来替换源码里面的字符串和符号
Defined Under Namespace
Classes: Location
Instance Method Summary collapse
- #initialize(hash) ⇒ StringsInjector constructor
-
#rewrite(script, ast_root) ⇒ String
将 script 源码中的字符串替换成 @strings_hash 翻译后的字符串.
-
#visit_string_node(node) ⇒ void
处理类型为 StringNode 的节点.
-
#visit_symbol_node(node) ⇒ void
处理类型为 SymbolNode 的节点.
Constructor Details
#initialize(hash) ⇒ StringsInjector
85 86 87 88 89 |
# File 'lib/R3EXS/ast.rb', line 85 def initialize(hash) @strings_hash = hash @content_loc = [] @code = [] end |
Instance Method Details
#rewrite(script, ast_root) ⇒ String
将 script 源码中的字符串替换成 @strings_hash 翻译后的字符串
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/R3EXS/ast.rb', line 125 def rewrite(script, ast_root) # 首先遍历一遍,找到所有需要替换的字符串的位置 visit(ast_root) # 然后开始替换 code 中的字符串 # 先将 @content_loc 按照 start_offset 从小到大排序 @content_loc.sort_by! { |loc| loc.start_offset } # 然后将 code 切片,将字符串替换成新的字符串 start_offset = 0 @content_loc.each do |loc| @code << script[start_offset...loc.start_offset] @code << @strings_hash[loc.content] start_offset = loc.start_offset + loc.length end @code << script[start_offset..-1] # 将 @code 里面的字符串全部改为二进制编码 @code.map! { |str| str.force_encoding('ASCII-8BIT') unless str.nil? } @code.join end |
#visit_string_node(node) ⇒ void
This method returns an undefined value.
处理类型为 StringNode 的节点
95 96 97 98 99 100 101 102 |
# File 'lib/R3EXS/ast.rb', line 95 def visit_string_node(node) location = node.content_loc value = location.slice if @strings_hash.has_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 的节点
108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/R3EXS/ast.rb', line 108 def visit_symbol_node(node) location = node.value_loc # 如果 location 不为 nil,说明这个符号是一个字符串 if location value = location.slice if @strings_hash.has_key?(value) && @strings_hash[value].to_s != '' @content_loc << Location.new(location.start_offset, location.length, value) end end super end |