From d2d23fbbd7439e4f8b8409e988fa69d2970dc997 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Fri, 3 Jan 2020 07:12:53 -0600 Subject: [PATCH] Add full module context to types (fixes #40) --- src/parcel_snoopi.jl | 20 ++++++++++++++++++-- test/snoopi.jl | 11 +++++++++++ test/snoopreachable.jl | 2 ++ test/testmodules/Reachable.jl | 14 ++++++++++++++ 4 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 test/snoopreachable.jl create mode 100644 test/testmodules/Reachable.jl diff --git a/src/parcel_snoopi.jl b/src/parcel_snoopi.jl index 659a38fed..19ce1f44e 100644 --- a/src/parcel_snoopi.jl +++ b/src/parcel_snoopi.jl @@ -153,6 +153,22 @@ function add_if_evals!(pclist, mod::Module, fstr, params, tt; prefix = "") return pclist end +function reprcontext(mod::Module, @nospecialize(T::Type)) + # First try without the full module context + rplain = repr(T) + try + ex = Meta.parse(rplain) + Core.eval(mod, ex) + return rplain + catch + # Add full module context + rdec = repr(T; context=:module=>nothing) + ex = Meta.parse(rdec) + Core.eval(mod, ex) + return rdec + end +end + function handle_kwbody(topmod::Module, m::Method, paramrepr, tt, fstr="fbody") nameparent = Symbol(match(r"^#([^#]*)#", String(m.name)).captures[1]) if !isdefined(m.module, nameparent) # TODO: replace debugging with error-handling @@ -213,7 +229,7 @@ function parcel(tinf::AbstractVector{Tuple{Float64,Core.MethodInstance}}; subst= # Create the string representation of the signature # Use special care with keyword functions, anonymous functions p = tt.parameters[1] # the portion of the signature related to the function itself - paramrepr = map(repr, Iterators.drop(tt.parameters, 1)) # all the rest of the args + paramrepr = map(T->reprcontext(topmod, T), Iterators.drop(tt.parameters, 1)) # all the rest of the args if any(str->occursin('#', str), paramrepr) @debug "Skipping $tt due to argument types having anonymous bindings" continue @@ -279,7 +295,7 @@ function parcel(tinf::AbstractVector{Tuple{Float64,Core.MethodInstance}}; subst= fstr = "getfield($mmod, Symbol(\"$mname\"))" # this is universal, var is Julia 1.3+ add_if_evals!(pc[topmodname], topmod, fstr, paramrepr, tt; prefix=prefix) else - add_if_evals!(pc[topmodname], topmod, repr(p), paramrepr, tt) + add_if_evals!(pc[topmodname], topmod, reprcontext(topmod, p), paramrepr, tt) end end return pc diff --git a/test/snoopi.jl b/test/snoopi.jl index 3ae3b3185..a5c8d3571 100644 --- a/test/snoopi.jl +++ b/test/snoopi.jl @@ -5,6 +5,8 @@ push!(LOAD_PATH, joinpath(@__DIR__, "testmodules")) using A using E using FuncKinds +using Reachable.ModuleA +using Reachable.ModuleB pop!(LOAD_PATH) @testset "topmodule" begin @@ -174,6 +176,15 @@ end end +@testset "Reachable" begin + tinf = @snoopi begin + include("snoopreachable.jl") + end + pc = SnoopCompile.parcel(tinf) + pcd = pc[:Reachable] + @test length(pcd) == 2 +end + @testset "@snoopi docs" begin # docstring is present (weird Docs bug) dct = Docs.meta(SnoopCompile) diff --git a/test/snoopreachable.jl b/test/snoopreachable.jl new file mode 100644 index 000000000..9f0d9046c --- /dev/null +++ b/test/snoopreachable.jl @@ -0,0 +1,2 @@ +a = RchA() +rchb(a) diff --git a/test/testmodules/Reachable.jl b/test/testmodules/Reachable.jl new file mode 100644 index 000000000..6313650de --- /dev/null +++ b/test/testmodules/Reachable.jl @@ -0,0 +1,14 @@ +module Reachable + +module ModuleA +export RchA +struct RchA end +end # ModuleA + +module ModuleB +using Reachable.ModuleA +export rchb +rchb(::RchA) = "hello" +end # ModuleB + +end # Reachable