Class: MilkTea::DebugMap
- Inherits:
-
Object
- Object
- MilkTea::DebugMap
- Defined in:
- lib/milk_tea/tooling/debug_map.rb
Defined Under Namespace
Constant Summary collapse
- VERSION =
1
Instance Attribute Summary collapse
-
#binary_path ⇒ Object
readonly
Returns the value of attribute binary_path.
-
#functions ⇒ Object
readonly
Returns the value of attribute functions.
-
#program_source_path ⇒ Object
readonly
Returns the value of attribute program_source_path.
Class Method Summary collapse
- .absolute_path_string?(path) ⇒ Boolean
- .from_ir(ir_program, binary_path:) ⇒ Object
- .load(path) ⇒ Object
- .load_for_binary(binary_path) ⇒ Object
- .path_for_payload(path, base_dir) ⇒ Object
- .path_from_payload(path, base_dir) ⇒ Object
- .sidecar_path_for(binary_path) ⇒ Object
Instance Method Summary collapse
- #function_for_c_name(c_name) ⇒ Object
-
#initialize(binary_path:, program_source_path:, functions:) ⇒ DebugMap
constructor
A new instance of DebugMap.
- #source_variable_for(function_c_name, source_name) ⇒ Object
- #to_h(base_dir: nil) ⇒ Object
- #variable_for(function_c_name, c_name) ⇒ Object
- #write(path) ⇒ Object
Constructor Details
#initialize(binary_path:, program_source_path:, functions:) ⇒ DebugMap
Returns a new instance of DebugMap.
39 40 41 42 43 44 45 46 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 39 def initialize(binary_path:, program_source_path:, functions:) @binary_path = binary_path ? File.(binary_path) : nil @program_source_path = program_source_path ? File.(program_source_path) : nil @functions = functions @functions_by_c_name = functions.each_with_object({}) do |function, memo| memo[function.linkage_name] ||= function end end |
Instance Attribute Details
#binary_path ⇒ Object (readonly)
Returns the value of attribute binary_path.
37 38 39 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 37 def binary_path @binary_path end |
#functions ⇒ Object (readonly)
Returns the value of attribute functions.
37 38 39 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 37 def functions @functions end |
#program_source_path ⇒ Object (readonly)
Returns the value of attribute program_source_path.
37 38 39 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 37 def program_source_path @program_source_path end |
Class Method Details
.absolute_path_string?(path) ⇒ Boolean
163 164 165 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 163 def self.absolute_path_string?(path) path.start_with?("/") || path.start_with?("\\\\") || path.match?(/\A[A-Za-z]:[\\\/]/) end |
.from_ir(ir_program, binary_path:) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 83 def self.from_ir(ir_program, binary_path:) functions = ir_program.functions.map do |function| source_path = first_statement_source_path(function.body) || ir_program.source_path Function.new( name: function.name.to_s, linkage_name: function.linkage_name.to_s, source_path: source_path ? File.(source_path) : nil, line: first_statement_line(function.body), params: function.params.map { |param| Entry.new(name: param.name.to_s, linkage_name: param.linkage_name.to_s, line: nil) }, locals: collect_locals(function.body) ) end new(binary_path:, program_source_path: ir_program.source_path, functions:) end |
.load(path) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 52 def self.load(path) resolved_path = File.(path) base_dir = File.dirname(resolved_path) payload = JSON.parse(File.read(resolved_path)) functions = Array(payload["functions"]).map do |function| Function.new( name: function.fetch("name"), linkage_name: function.fetch("cName"), source_path: path_from_payload(function["sourcePath"], base_dir), line: function["line"], params: load_entries(function["params"]), locals: load_entries(function["locals"]) ) end new( binary_path: path_from_payload(payload["binaryPath"], base_dir), program_source_path: path_from_payload(payload["programSourcePath"], base_dir), functions: ) end |
.load_for_binary(binary_path) ⇒ Object
74 75 76 77 78 79 80 81 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 74 def self.load_for_binary(binary_path) path = sidecar_path_for(binary_path) return nil unless File.file?(path) load(path) rescue JSON::ParserError nil end |
.path_for_payload(path, base_dir) ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 142 def self.path_for_payload(path, base_dir) return nil unless path return path.tr("\\", "/") unless base_dir = File.(path) begin Pathname.new().relative_path_from(Pathname.new(base_dir)).to_s.tr("\\", "/") rescue ArgumentError .tr("\\", "/") end end |
.path_from_payload(path, base_dir) ⇒ Object
154 155 156 157 158 159 160 161 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 154 def self.path_from_payload(path, base_dir) return nil unless path return path if path.empty? return path if absolute_path_string?(path) return path unless base_dir File.(path, base_dir) end |
.sidecar_path_for(binary_path) ⇒ Object
48 49 50 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 48 def self.sidecar_path_for(binary_path) "#{File.(binary_path)}.mtdbg.json" end |
Instance Method Details
#function_for_c_name(c_name) ⇒ Object
106 107 108 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 106 def function_for_c_name(c_name) @functions_by_c_name[c_name.to_s] end |
#source_variable_for(function_c_name, source_name) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 118 def source_variable_for(function_c_name, source_name) function = function_for_c_name(function_c_name) return nil unless function matches = (function.params + function.locals).select { |entry| entry.name == source_name.to_s } return nil if matches.empty? return matches.first if matches.map(&:linkage_name).uniq.one? nil end |
#to_h(base_dir: nil) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 130 def to_h(base_dir: nil) payload = { "version" => VERSION, "functions" => functions.map { |function| function.to_h(base_dir:) }, } serialized_binary_path = self.class.path_for_payload(binary_path, base_dir) payload["binaryPath"] = serialized_binary_path if serialized_binary_path serialized_program_source_path = self.class.path_for_payload(program_source_path, base_dir) payload["programSourcePath"] = serialized_program_source_path if serialized_program_source_path payload end |
#variable_for(function_c_name, c_name) ⇒ Object
110 111 112 113 114 115 116 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 110 def variable_for(function_c_name, c_name) function = function_for_c_name(function_c_name) return nil unless function function.params.find { |entry| entry.linkage_name == c_name.to_s } || function.locals.find { |entry| entry.linkage_name == c_name.to_s } end |
#write(path) ⇒ Object
99 100 101 102 103 104 |
# File 'lib/milk_tea/tooling/debug_map.rb', line 99 def write(path) resolved_path = File.(path) base_dir = File.dirname(resolved_path) FileUtils.mkdir_p(base_dir) File.write(resolved_path, JSON.pretty_generate(to_h(base_dir:)) + "\n") end |