In [1]:
using SemanticModels
using SemanticModels.ModelTools
In [2]:
expr =quote
    function f(a::Int64, b::Int64)
    c = a + b
    d = g(float(c))
    
    return d
end
function g(res::Float64)
    res = abs(res)
    res -= 1
    
    while res > 0
        res = g(res)
    end

    return res
end
@show f(1,2)
end
Out[2]:
quote
    #= In[2]:2 =#
    function f(a::Int64, b::Int64)
        #= In[2]:3 =#
        c = a + b
        #= In[2]:4 =#
        d = g(float(c))
        #= In[2]:6 =#
        return d
    end
    #= In[2]:8 =#
    function g(res::Float64)
        #= In[2]:9 =#
        res = abs(res)
        #= In[2]:10 =#
        res -= 1
        #= In[2]:12 =#
        while res > 0
            #= In[2]:13 =#
            res = g(res)
        end
        #= In[2]:16 =#
        return res
    end
    #= In[2]:18 =#
    #= In[2]:18 =# @show f(1, 2)
end
In [3]:
funcs = Expr[]
for ex in expr.args
    if isa(ex, LineNumberNode)
        continue
    end
    if ex.head == :function
        push!(funcs, ex)
    end
end

funcs
Out[3]:
2-element Array{Expr,1}:
 :(function f(a::Int64, b::Int64)
      #= In[2]:3 =#
      c = a + b
      #= In[2]:4 =#
      d = g(float(c))
      #= In[2]:6 =#
      return d
  end)                                                                                               
 :(function g(res::Float64)
      #= In[2]:9 =#
      res = abs(res)
      #= In[2]:10 =#
      res -= 1
      #= In[2]:12 =#
      while res > 0
          #= In[2]:13 =#
          res = g(res)
      end
      #= In[2]:16 =#
      return res
  end)
In [4]:
nametype(ex::Expr) = begin
    ex.head == :(::) || error("$ex is not a type assertion")
    avar = ex.args[1]
    atyp = ex.args[2]
    return avar, atyp
end

nametype(s::Symbol) = (s, :Any)

function describeargs(fu::Expr)
    f = fu
    @show argl = f.args[1].args[2:end]
    @show argl
    @show body = f.args[2].args
    fname = string(f.args[1])
    for a in reverse(argl)
        avar, atyp = nametype(a)
        varname = string(avar)
        pushfirst!(body,
            :(println("F: ", $fname,";",
                $varname,"=", $avar,"::",typeof($avar), "<:", $atyp))
        )
    end
    return f
end

for f in funcs
    describeargs(f)
    body = f.args[2].args
    fname = string(f.args[1])
    for ex in body
        if isa(ex,LineNumberNode)
            continue
        end
        if ex.head == :(=)
            @show a = ex.args[1]
            varname = string(a)
            insert!(body, length(body)-1,:(println("A: ", $fname,";",$varname, "=", $a)))
        end
    end
end
expr
argl = (f.args[1]).args[2:end] = Any[:(a::Int64), :(b::Int64)]
argl = Any[:(a::Int64), :(b::Int64)]
body = (f.args[2]).args = Any[:(#= In[2]:3 =#), :(c = a + b), :(#= In[2]:4 =#), :(d = g(float(c))), :(#= In[2]:6 =#), :(return d)]
a = ex.args[1] = :c
a = ex.args[1] = :d
argl = (f.args[1]).args[2:end] = Any[:(res::Float64)]
argl = Any[:(res::Float64)]
body = (f.args[2]).args = Any[:(#= In[2]:9 =#), :(res = abs(res)), :(#= In[2]:10 =#), :(res -= 1), :(#= In[2]:12 =#), :(while res > 0
      #= In[2]:13 =#
      res = g(res)
  end), :(#= In[2]:16 =#), :(return res)]
a = ex.args[1] = :res
Out[4]:
quote
    #= In[2]:2 =#
    function f(a::Int64, b::Int64)
        println("F: ", "f(a::Int64, b::Int64)", ";", "a", "=", a, "::", typeof(a), "<:", Int64)
        println("F: ", "f(a::Int64, b::Int64)", ";", "b", "=", b, "::", typeof(b), "<:", Int64)
        #= In[2]:3 =#
        c = a + b
        #= In[2]:4 =#
        d = g(float(c))
        println("A: ", "f(a::Int64, b::Int64)", ";", "c", "=", c)
        println("A: ", "f(a::Int64, b::Int64)", ";", "d", "=", d)
        #= In[2]:6 =#
        return d
    end
    #= In[2]:8 =#
    function g(res::Float64)
        println("F: ", "g(res::Float64)", ";", "res", "=", res, "::", typeof(res), "<:", Float64)
        #= In[2]:9 =#
        res = abs(res)
        #= In[2]:10 =#
        res -= 1
        #= In[2]:12 =#
        while res > 0
            #= In[2]:13 =#
            res = g(res)
        end
        println("A: ", "g(res::Float64)", ";", "res", "=", res)
        #= In[2]:16 =#
        return res
    end
    #= In[2]:18 =#
    #= In[2]:18 =# @show f(1, 2)
end
In [5]:
eval(expr)
F: f(a::Int64, b::Int64);a=1::Int64<:Int64
F: f(a::Int64, b::Int64);b=2::Int64<:Int64
F: g(res::Float64);res=3.0::Float64<:Float64
F: g(res::Float64);res=2.0::Float64<:Float64
F: g(res::Float64);res=1.0::Float64<:Float64
A: g(res::Float64);res=0.0
A: g(res::Float64);res=0.0
A: g(res::Float64);res=0.0
A: f(a::Int64, b::Int64);c=3
A: f(a::Int64, b::Int64);d=0.0
f(1, 2) = 0.0
Out[5]:
0.0