1# Copyright (c) 2024 Huawei Device Co., Ltd. 2# Licensed under the Apache License, Version 2.0 (the "License"); 3# you may not use this file except in compliance with the License. 4# You may obtain a copy of the License at 5# 6# http://www.apache.org/licenses/LICENSE-2.0 7# 8# Unless required by applicable law or agreed to in writing, software 9# distributed under the License is distributed on an "AS IS" BASIS, 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11# See the License for the specific language governing permissions and 12# limitations under the License. 13 14require_relative 'types' 15 16module ESChecker 17 UNMANGLE = {"#__NaN" => "NaN", "#__null" => "null", "#__Inf" => "Infinity", "#__NegInf" => "-Infinity", "#__undefined" => "undefined"} 18 class ValueDumper 19 def initialize(conf) 20 @name = 0 21 @conf = conf 22 end 23 24 def parse_type(str) 25 ESChecker::Types::Parser.new(str).run 26 end 27 28 def unmangle(x) 29 toh = Proc.new { |i, off| 30 ((i >> (off * 8)) % 256).to_s(16).rjust(2, '0') 31 } 32 if x.kind_of? Array 33 x.map { |e| unmangle e } 34 elsif x.kind_of? Hash 35 case x["__kind"] 36 when "str" 37 res = x["data"].map { |c| "\\u#{toh.(c, 1)}#{toh.(c, 0)}" }.join 38 "\"#{res}\"" 39 when "num" 40 "Double.bitCastFromLong(#{x["data"]} as long) /* #{x["dbg"]} */" 41 when "bigint" 42 "#{x["data"]}n" 43 else 44 raise "unknown kind for #{x}" 45 end 46 elsif x.kind_of? String 47 old = x 48 x = UNMANGLE[x] || x 49 if x != old 50 x 51 else 52 x.inspect 53 end 54 elsif x.kind_of?(Float) 55 hex = [x].pack('G').split('').map { |ds| ds[0] }.map { |a| sprintf("%02x", a.ord) }.join() 56 "Double.bitCastFromLong(0x#{hex}) /* #{x} */" 57 else 58 UNMANGLE[x] || x 59 end 60 end 61 62 def get_array_type_from(x) 63 match = /^\s*(Array|Iterable)<(?<elem>.*)>\s*$/.match(x) 64 if match 65 match[:elem] 66 else 67 nil 68 end 69 end 70 71 def dump_value(buf, rb_obj, exp_type) 72 case exp_type[:kind] 73 when :array, :iterable 74 buf << "Array.of<" << ESChecker::Types::dump(exp_type[:el]) << ">(" 75 rb_obj.each_with_index { |v, i| 76 if i != 0 77 buf << ", " 78 end 79 dump_value(buf, v, exp_type[:el]) 80 } 81 buf << ")" 82 when :tuple 83 buf << "[" 84 rb_obj.zip(exp_type[:els]).each_with_index { |v, i| 85 if i != 0 86 buf << ", " 87 end 88 dump_value buf, v[0], v[1] 89 } 90 buf << "] as " << ESChecker::Types::dump(exp_type) 91 when :trivial 92 buf << "#{rb_obj} as #{exp_type[:str]}" 93 else 94 raise "unknown type kind #{exp_type.kind}" 95 end 96 end 97 98 def dump(rb_obj, is_self: false) 99 typ = if is_self 100 ESChecker::Types::detect(rb_obj, dflt: @conf.self_type) 101 else 102 ESChecker::Types::detect(rb_obj, dflt: @conf.ret_type) 103 end 104 rb_obj = unmangle(rb_obj) 105 @buf = String.new 106 dump_value(@buf, rb_obj, typ) 107 r = @buf 108 @buf = String.new 109 r 110 end 111 end 112end 113