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
初始化 StringsInjector.
-
#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
初始化 StringsInjector
92 93 94 95 96 |
# File 'lib/R3EXS/ast.rb', line 92 def initialize(hash) @strings_hash = hash @content_loc = [] @code = [] end |
Instance Method Details
#rewrite(script, ast_root) ⇒ String
将 script 源码中的字符串替换成 @strings_hash 翻译后的字符串
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/R3EXS/ast.rb', line 135 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 的节点
103 104 105 106 107 108 109 110 |
# File 'lib/R3EXS/ast.rb', line 103 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 的节点
117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/R3EXS/ast.rb', line 117 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 |