|
10 | 10 | [taoensso.timbre :as log])) |
11 | 11 |
|
12 | 12 | (def ^:private go-handler (atom nil)) |
13 | | -(def ^:private breakpoint-id-counter (atom 1)) |
14 | | -(def ^:private stackframe-id-counter (atom 1)) |
15 | | -(def ^:private vars-id-counter (atom 1)) |
16 | | -(def ^:private var-index (atom {})) |
17 | 13 |
|
18 | 14 | (defn- create-handler [adapter] |
19 | 15 | {:adapter adapter |
|
23 | 19 | :breakpoints {} |
24 | 20 | :channels {:to-handler (chan) |
25 | 21 | :to-debug-server nil} |
26 | | - :stackframes (atom [])}) |
| 22 | + :counter {:breakpoint (atom 0) |
| 23 | + :stackframe (atom 0) |
| 24 | + :vars (atom 0)} |
| 25 | + :stackframes (atom []) |
| 26 | + :var-index (atom {})}) |
27 | 27 |
|
28 | 28 | (defn- to-int [value] |
29 | 29 | (if (int? value) |
|
65 | 65 | (first))))) |
66 | 66 |
|
67 | 67 | (defn- find-source-relative-file [handler filepath] |
68 | | - (log/info "SOURCE DIRS" (:source-dirs handler)) |
69 | | - (log/info "ORIG FILE" filepath) |
70 | | - (log/info "DIR" (find-source-dir handler filepath)) |
71 | | - (log/info "FILE" (find-source-file handler filepath)) |
72 | 68 | (let [source-dir (.getCanonicalPath (io/file (find-source-dir handler filepath))) |
73 | 69 | filepath (.getCanonicalPath (io/file filepath))] |
74 | 70 | (assert (some? source-dir)) |
|
157 | 153 | {:type (keyword type) |
158 | 154 | :addr addr})) |
159 | 155 |
|
160 | | -(defn- parse-value [_ packed-value] |
| 156 | +(defn- parse-inner-value [handler name value] |
| 157 | + (cond |
| 158 | + (vector? value) |
| 159 | + {:id (swap! (get-in handler [:counter :vars]) inc) |
| 160 | + :name name |
| 161 | + :type :table |
| 162 | + :addr nil |
| 163 | + :value (vec (map (partial parse-inner-value handler nil) value))} |
| 164 | + |
| 165 | + (map? value) |
| 166 | + {:id (swap! (get-in handler [:counter :vars]) inc) |
| 167 | + :name name |
| 168 | + :type :table |
| 169 | + :addr nil |
| 170 | + :value (map-over-map (fn [k v] (parse-inner-value handler k v)) value)} |
| 171 | + |
| 172 | + :else |
| 173 | + {:name name |
| 174 | + :type :constant |
| 175 | + :value value})) |
| 176 | + |
| 177 | +(defn- parse-value [handler var-name packed-value] |
161 | 178 | (case (count packed-value) |
162 | | - 1 {:id (swap! vars-id-counter inc) |
| 179 | + 1 {:name var-name |
163 | 180 | :type :constant |
164 | 181 | :value nil} |
165 | 182 | 2 (let [[value ident] packed-value] |
166 | 183 | (if-let [{type :type addr :addr} (parse-heap-value ident)] |
167 | | - {:id (swap! vars-id-counter inc) |
| 184 | + {:id (swap! (get-in handler [:counter :vars]) inc) |
| 185 | + :name var-name |
168 | 186 | :type type |
169 | 187 | :addr addr |
170 | | - :value value} |
171 | | - {:id (swap! vars-id-counter inc) |
| 188 | + :value (case type |
| 189 | + :table (if (vector? value) |
| 190 | + (vec (map-indexed (partial parse-inner-value handler) value)) |
| 191 | + (map-over-map (fn [k v] (parse-inner-value handler k v)) value)) |
| 192 | + value)} |
| 193 | + {:name var-name |
172 | 194 | :type :constant |
173 | 195 | :value value})) |
174 | 196 | (do (log/error "Could not unpack" packed-value) |
175 | 197 | nil))) |
176 | 198 |
|
| 199 | +(defn- register-vars [handler vars] |
| 200 | + (log/error "VARS?" vars) |
| 201 | + (doseq [[_ v] (if (map? vars) vars (zipmap (range (count vars)) vars))] |
| 202 | + (when (:id v) |
| 203 | + (swap! (:var-index handler) assoc (:id v) v)) |
| 204 | + (when (= :table (:type v)) |
| 205 | + (register-vars handler (:value v))))) |
| 206 | + |
177 | 207 | (defn- transform-stack-trace [handler stack-trace] |
178 | 208 | (map-indexed |
179 | 209 | (fn [_ [frame-info stack upvalues]] |
180 | | - (let [stack (map-over-map parse-value stack) |
181 | | - upvalues (map-over-map parse-value upvalues)] |
182 | | - |
183 | | - ; register vars from stack |
184 | | - (doseq [[k v] stack] |
185 | | - (swap! var-index assoc k v)) |
| 210 | + (let [parse-value (partial parse-value handler) |
| 211 | + stack (map-over-map parse-value stack) |
| 212 | + upvalues (map-over-map parse-value upvalues)] |
186 | 213 |
|
187 | | - ; register vars from upvalues |
188 | | - (doseq [[k v] upvalues] |
189 | | - (swap! var-index assoc k v)) |
| 214 | + (register-vars handler stack) |
| 215 | + (register-vars handler upvalues) |
190 | 216 |
|
191 | 217 | (case (count frame-info) |
192 | 218 | ; example of the frame header (6): |
|
196 | 222 | ; 3: "Lua" - Lua (thats where it comes from ig) |
197 | 223 | ; 4: "field" - ??? this can also be "upvalue" |
198 | 224 | ; 5: "modules/tbl.lua" - file location again |
199 | | - 6 {:id (swap! stackframe-id-counter inc) |
| 225 | + 6 {:id (swap! (get-in handler [:counter :stackframe]) inc) |
200 | 226 | :name "" |
201 | 227 | :source {:path (find-source-file handler (frame-info 0))} |
202 | 228 | :line (parse-long (frame-info 2)) |
203 | 229 | :column 0 |
204 | 230 | :extras {:scope-start (parse-long (frame-info 1)) |
205 | | - :stack {:id (swap! vars-id-counter inc) |
| 231 | + :stack {:id (swap! (get-in handler [:counter :vars]) inc) |
206 | 232 | :values stack} |
207 | | - :upvalues {:id (swap! vars-id-counter inc) |
| 233 | + :upvalues {:id (swap! (get-in handler [:counter :vars]) inc) |
208 | 234 | :values upvalues} |
209 | 235 | :type (frame-info 4)}} |
210 | 236 |
|
|
216 | 242 | ; 4: "Lua" - Lua (thats where it comes from ig) |
217 | 243 | ; 5: "field" - ??? this can also be "upvalue" |
218 | 244 | ; 6: "modules/tbl.lua" - file location again |
219 | | - 7 {:id (swap! stackframe-id-counter inc) |
| 245 | + 7 {:id (swap! (get-in handler [:counter :stackframe]) inc) |
220 | 246 | :name (or (frame-info 0) "") |
221 | 247 | :source {:path (find-source-file handler (frame-info 1))} |
222 | 248 | :line (parse-long (frame-info 3)) |
223 | 249 | :column 0 |
224 | 250 | :extras {:scope-start (parse-long (frame-info 2)) |
225 | | - :stack {:id (swap! vars-id-counter inc) |
| 251 | + :stack {:id (swap! (get-in handler [:counter :vars]) inc) |
226 | 252 | :values stack} |
227 | | - :upvalues {:id (swap! vars-id-counter inc) |
| 253 | + :upvalues {:id (swap! (get-in handler [:counter :vars]) inc) |
228 | 254 | :values upvalues} |
229 | 255 | :type (frame-info 5)}} |
230 | 256 |
|
|
311 | 337 | {:keys [source breakpoints]} (:arguments message) |
312 | 338 | source-path (:path source) |
313 | 339 | filename (find-source-relative-file handler source-path) |
314 | | - breakpoints (mapv #(assoc % :verified true :id (swap! breakpoint-id-counter inc)) breakpoints)] |
| 340 | + breakpoints (mapv #(assoc % :verified true :id (swap! (get-in handler [:counter :breakpoint]) inc)) breakpoints)] |
315 | 341 | (adapter/send-message! adapter (success (:seq message) "setBreakpoints" {:breakpoints breakpoints})) |
316 | 342 | (-> handler |
317 | 343 | (assoc-in [:breakpoints (str filename)] breakpoints)))) |
|
373 | 399 | (get-in m [:extras :upvalues])))) |
374 | 400 | data)) |
375 | 401 |
|
376 | | -(defn- table-remove-types-not-to-be-shown [table] |
377 | | - (filter #(not (#{:function} (second %))) table)) |
378 | | - |
379 | 402 | (defn- float-to-string [n] |
380 | 403 | (.replaceAll (format "%.16f" n) "\\.?0*$" "")) |
381 | 404 |
|
382 | | -(defn- create-variables [vars] |
| 405 | +(defn- var-name [n] |
| 406 | + (cond |
| 407 | + (keyword? n) (name n) |
| 408 | + (string? n) n |
| 409 | + (number? n) (str n) |
| 410 | + :else (str n))) |
| 411 | + |
| 412 | +(defn- var-value [v] |
| 413 | + (cond |
| 414 | + (string? v) (str v) |
| 415 | + (int? v) (format "%i" v) |
| 416 | + (float? v) (float-to-string v) |
| 417 | + (number? v) (float-to-string v) |
| 418 | + (boolean? v) (str v) |
| 419 | + (vector? v) (format "[%s]" (string/join ", " (map #(var-value (:value %)) v))) |
| 420 | + (map? v) (format "{%s}" (string/join ", " (map (fn [[k v]] (str (var-name k) " = " (var-value (:value v)))) v))) |
| 421 | + :else (str v))) |
| 422 | + |
| 423 | +(defn- var-type [v] |
| 424 | + (cond |
| 425 | + (string? v) "string" |
| 426 | + (int? v) "int" |
| 427 | + (float? v) "float" |
| 428 | + (number? v) "number" |
| 429 | + (boolean? v) "boolean" |
| 430 | + (nil? v) "null" |
| 431 | + :else nil)) |
| 432 | + |
| 433 | +(defn- var-value-table [v] |
| 434 | + (cond |
| 435 | + (vector? v) |
| 436 | + (format |
| 437 | + "[%s]" |
| 438 | + (string/join ", " (map #(var-value (:value %)) v))) |
| 439 | + |
| 440 | + (map? v) |
| 441 | + (format |
| 442 | + "{%s}" |
| 443 | + (string/join ", " (map (fn [[k v]] (str (var-name k) " = " (var-value (:value v)))) v))) |
| 444 | + |
| 445 | + (empty? v) |
| 446 | + "{}" |
| 447 | + |
| 448 | + :else (throw (ex-info (str "expected vector or map, got: " (pr-str v)) {:value v})))) |
| 449 | + |
| 450 | +(defn- create-scope-variables [vars] |
383 | 451 | (map |
384 | 452 | (fn [[k v]] |
385 | 453 | (case (:type v) |
386 | | - :constant {:name (name k) |
387 | | - :value (cond |
388 | | - (string? (:value v)) (:value v) |
389 | | - (int? (:value v)) (format "%i" (:value v)) |
390 | | - (float? (:value v)) (float-to-string (:value v)) |
391 | | - (number? (:value v)) (float-to-string (:value v)) |
392 | | - (boolean? (:value v)) (str (:value v)) |
393 | | - :else (str (:value v))) |
394 | | - :type (cond |
395 | | - (string? (:value v)) "string" |
396 | | - (int? (:value v)) "int" |
397 | | - (float? (:value v)) "float" |
398 | | - (number? (:value v)) "number" |
399 | | - (boolean? (:value v)) "boolean" |
400 | | - :else nil) |
401 | | - :evaluateName (name k) |
402 | | - :variablesReference (:id v) |
| 454 | + :constant {:name (var-name k) |
| 455 | + :value (var-value (:value v)) |
| 456 | + :type (var-type (:value v)) |
| 457 | + :evaluateName (var-name k) |
| 458 | + :variablesReference 0 |
403 | 459 | :namedVariables 0 |
404 | 460 | :indexedVariables 0 |
405 | 461 | :presentationHint {:kind "data" |
406 | 462 | :attributes ["constant"]}} |
407 | | - :table {:name (name k) |
408 | | - :value |
409 | | - (if (vector? (:value v)) |
410 | | - (format |
411 | | - "[ %s ]" |
412 | | - (string/join ", " (:value v))) |
413 | | - (format |
414 | | - "{ %s }" |
415 | | - (string/join ", " (map (fn [[k v]] (str (name k) " = " v)) (table-remove-types-not-to-be-shown (:value v)))))) |
416 | | - :type |
417 | | - (if (vector? (:value v)) "array" "object") |
418 | | - :evaluateName (name k) |
| 463 | + |
| 464 | + :table {:name (var-name k) |
| 465 | + :value (var-value-table (:value v)) |
| 466 | + :type (if (vector? (:value v)) "array" "object") |
| 467 | + :evaluateName (var-name k) |
419 | 468 | :variablesReference (:id v) |
420 | | - :namedVariables (if (map? (:value v)) (count (table-remove-types-not-to-be-shown (:value v))) 0) |
421 | | - :indexedVariables (if (vector? (:value v)) (count (:value v)) 0) |
| 469 | + :namedVariables (if (map? (:value v)) (count (:value v)) 0) |
| 470 | + :indexedVariables (if (vector? (:value v)) (count (:value v)) 0) |
422 | 471 | :presentationHint {:kind "data" |
423 | 472 | :attributes (if (vector? (:value v)) "array" "rawObject")}} |
424 | | - :function nil |
425 | | - (do (log/error "Unknown variable type:" (:type v) v) |
426 | | - nil))) |
| 473 | + |
| 474 | + :function {:name (var-name k) |
| 475 | + :value (format "function: %s" (:addr v)) |
| 476 | + :type "function" |
| 477 | + :variablesReference 0 |
| 478 | + :presentationHint {:kind "method"}} |
| 479 | + |
| 480 | + (do (log/warn "Unknown variable type found:" k v) |
| 481 | + {:name (var-name k) |
| 482 | + :value (format "%s: %s" (var-name (:type v)) (:addr v)) |
| 483 | + :variablesReference 0 |
| 484 | + :type "unknown"}))) |
427 | 485 | vars)) |
428 | 486 |
|
| 487 | +(defn- make-var [pname indexed? n value] |
| 488 | + (let [fstr (str (var-name pname) (if indexed? "[%s]" ".%s")) |
| 489 | + v (:value value)] |
| 490 | + (log/info "MAKE VARS HAPPEN" n v (:id v)) |
| 491 | + (cond |
| 492 | + (vector? v) |
| 493 | + {:name (var-name n) |
| 494 | + :value (var-value-table v) |
| 495 | + :type "array" |
| 496 | + :evaluateName (format fstr n) |
| 497 | + :variablesReference (:id value) |
| 498 | + :presentationHint {:kind "data" |
| 499 | + :attributes ["array"]}} |
| 500 | + |
| 501 | + (map? v) |
| 502 | + {:name (var-name n) |
| 503 | + :value (var-value-table v) |
| 504 | + :type "object" |
| 505 | + :evaluateName (format fstr n) |
| 506 | + :variablesReference (:id value) |
| 507 | + :presentationHint {:kind "data" |
| 508 | + :attributes ["rawObject"]}} |
| 509 | + |
| 510 | + :else |
| 511 | + {:name (var-name n) |
| 512 | + :value (var-value v) |
| 513 | + :type (var-type v) |
| 514 | + :evaluateName (format fstr n) |
| 515 | + :variablesReference 0 |
| 516 | + :presentationHint {:kind "data"}}))) |
| 517 | + |
| 518 | +(defn- create-variables [vars] |
| 519 | + (log/info "CREATE VARS?" vars) |
| 520 | + (case (:type vars) |
| 521 | + :table (map-indexed |
| 522 | + (if (vector? (:value vars)) |
| 523 | + (fn [idx v] (make-var (:name vars) true (str idx) v)) |
| 524 | + (fn [_ [k v]] (make-var (:name vars) false (var-name k) v))) |
| 525 | + (:value vars)) |
| 526 | + [nil])) |
| 527 | + |
| 528 | +(defn- find-var-by-id [handler var-id] |
| 529 | + (let [scope (:values (find-vars-scope-by-id @(:stackframes handler) var-id)) |
| 530 | + vars (@(:var-index handler) var-id)] |
| 531 | + (cond |
| 532 | + scope [scope :scope] |
| 533 | + vars [vars :vars] |
| 534 | + :else [nil nil]))) |
| 535 | + |
429 | 536 | (defn handle-variables [handler message] |
430 | | - (let [vars-id (get-in message [:arguments :variablesReference]) |
431 | | - vars (or (:values (find-vars-scope-by-id @(:stackframes handler) vars-id)) |
432 | | - (@var-index vars-id))] |
433 | | - (adapter/send-message! |
434 | | - (:adapter handler) |
435 | | - (success (:seq message) |
436 | | - "variables" |
437 | | - {:variables (filter some? (create-variables vars))})) |
| 537 | + (let [vars-id (get-in message [:arguments :variablesReference]) |
| 538 | + [vars type] (find-var-by-id handler vars-id)] |
| 539 | + (assert (and (some? vars) (some? type))) |
| 540 | + |
| 541 | + (let [variables |
| 542 | + (filter some? (case type |
| 543 | + :scope (create-scope-variables vars) |
| 544 | + :vars (create-variables vars) |
| 545 | + :else []))] |
| 546 | + |
| 547 | + (adapter/send-message! |
| 548 | + (:adapter handler) |
| 549 | + (success (:seq message) |
| 550 | + "variables" |
| 551 | + {:variables variables}))) |
438 | 552 | handler)) |
439 | 553 |
|
440 | 554 | (defn handle-continue [handler message] |
|
0 commit comments