@@ -76,7 +76,8 @@ function TypedSyntaxNode(rootnode::SyntaxNode, src::CodeInfo, mappings, symtyps)
7676 # There may be ambiguous assignments back to the source; preserve just the unambiguous ones
7777 node2ssa = IdDict {SyntaxNode,Int} (only (list) => i for (i, list) in pairs (mappings) if length (list) == 1 )
7878 # Copy `rootnode`, adding type annotations
79- trootnode = TypedSyntaxNode (nothing , nothing , TypedSyntaxData (rootnode. data:: SyntaxData , src, gettyp (node2ssa, rootnode, src)))
79+ typ = gettyp (node2ssa, rootnode, src)
80+ trootnode = TypedSyntaxNode (nothing , nothing , TypedSyntaxData (rootnode. data:: SyntaxData , src, typ))
8081 addchildren! (trootnode, rootnode, src, node2ssa, symtyps, mappings)
8182 # Add argtyps to signature
8283 fnode = get_function_def (trootnode)
@@ -439,6 +440,76 @@ function collect_symbol_nodes!(symlocs::AbstractDict, node)
439440 return symlocs
440441end
441442
443+ # # utility function to extract the line number at a particular program counter (ignoring inlining).
444+ # # return <= 0 if there is no line number change caused by this statement
445+ @static if VERSION ≥ v " 1.12.0-DEV.173"
446+ function getline (lt:: Core.DebugInfo , i:: Int )
447+ while true
448+ codeloc = Base. IRShow. getdebugidx (lt, i)
449+ line:: Int = codeloc[1 ]
450+ line < 0 && return 0 # broken or disabled debug info?
451+ line == 0 && return 0 # no line number update (though maybe inlining changed)
452+ ltnext = lt. linetable
453+ if ltnext === nothing
454+ return line
455+ end
456+ i = line
457+ lt = ltnext
458+ end
459+ end
460+ function getnextline (lt:: Core.DebugInfo , i:: Int , Δline)
461+ while true
462+ codeloc = Base. IRShow. getdebugidx (lt, i)
463+ line:: Int = codeloc[1 ]
464+ line < 0 && return typemax (Int) # broken or disabled debug info?
465+ if line == 0
466+ i += 1
467+ continue
468+ end
469+ ltnext = lt. linetable
470+ if ltnext === nothing
471+ break
472+ end
473+ i = line
474+ lt = ltnext
475+ end
476+ # now that we have line i and a list of all lines with code on them lt
477+ # find the next largest line number in this list greater than i, or return typemax(Int)
478+ j = i+ 1
479+ currline = Base. IRShow. getdebugidx (lt, i)[1 ]
480+ while j ≤ typemax (Int)
481+ codeloc = Base. IRShow. getdebugidx (lt, j)
482+ line:: Int = codeloc[1 ]
483+ line < 0 && break
484+ if line == 0 || currline == line
485+ j += 1
486+ else
487+ return line + Δline
488+ end
489+ end
490+ return typemax (Int)
491+ end
492+
493+ else # VERSION < v"1.12.0-DEV.173"
494+ function getline (lt, j)
495+ linfo = (j == 0 ? first (lt) : lt[j]):: Core.LineInfoNode
496+ linfo. inlined_at == 0 && return linfo. line
497+ @assert linfo. method === Symbol (" macro expansion" )
498+ linfo = lt[linfo. inlined_at]:: Core.LineInfoNode
499+ return linfo. line
500+ end
501+ function getnextline (lt, j, Δline)
502+ j == 0 && return typemax (Int)
503+ j += 1
504+ while j <= length (lt)
505+ linfo = lt[j]:: Core.LineInfoNode
506+ linfo. inlined_at == 0 && return linfo. line + Δline
507+ j += 1
508+ end
509+ return typemax (Int)
510+ end
511+ end # @static if
512+
442513# Main logic for mapping `src.code[i]` to node(s) in the SyntaxNode tree
443514# Success: when we map it to a unique node
444515# Δline is the (Revise) offset of the line number
@@ -471,8 +542,13 @@ function map_ssas_to_source(src::CodeInfo, mi::MethodInstance, rootnode::SyntaxN
471542 # Append (to `mapped`) all nodes in `targets` that are consistent with the line number of the `i`th stmt
472543 # (Essentially `copy!(mapped, filter(predicate, targets))`)
473544 function append_targets_for_line! (mapped#= ::Vector{nodes}=# , i:: Int , targets#= ::Vector{nodes}=# )
474- j = src. codelocs[i]
475- lt = src. linetable:: Vector
545+ @static if VERSION ≥ v " 1.12.0-DEV.173"
546+ j = i
547+ lt = src. debuginfo
548+ else
549+ j = src. codelocs[i]
550+ lt = src. linetable:: Vector
551+ end
476552 start = getline (lt, j) + Δline
477553 stop = getnextline (lt, j, Δline) - 1
478554 linerange = start : stop
@@ -853,25 +929,6 @@ function symloc_key(sym::Symbol)
853929 return sym
854930end
855931
856- function getline (lt, j)
857- linfo = (j == 0 ? first (lt) : lt[j]):: Core.LineInfoNode
858- linfo. inlined_at == 0 && return linfo. line
859- @assert linfo. method === Symbol (" macro expansion" )
860- linfo = lt[linfo. inlined_at]:: Core.LineInfoNode
861- return linfo. line
862- end
863-
864- function getnextline (lt, j, Δline)
865- j == 0 && return typemax (Int)
866- j += 1
867- while j <= length (lt)
868- linfo = lt[j]:: Core.LineInfoNode
869- linfo. inlined_at == 0 && return linfo. line + Δline
870- j += 1
871- end
872- return typemax (Int)
873- end
874-
875932function find_identifier_or_tuplechild (node:: AbstractSyntaxNode , sym)
876933 kind (node) == K " Identifier" && node. val === sym && return node, true
877934 if kind (node) == K " tuple" # tuple destructuring
0 commit comments