diff --git a/TypedSyntax/src/show.jl b/TypedSyntax/src/show.jl index f3bfbe05..6e086b30 100644 --- a/TypedSyntax/src/show.jl +++ b/TypedSyntax/src/show.jl @@ -32,7 +32,8 @@ end function Base.printstyled(io::IO, rootnode::MaybeTypedSyntaxNode; type_annotations::Bool=true, iswarn::Bool=true, hide_type_stable::Bool=true, with_linenumber::Bool=true, - idxend = last_byte(rootnode)) + idxend = last_byte(rootnode) + ) rt = gettyp(rootnode) nd = with_linenumber ? ndigits_linenumbers(rootnode, idxend) : 0 rootnode = get_function_def(rootnode) @@ -116,9 +117,14 @@ end function show_annotation(io, @nospecialize(T), post, node, position; iswarn::Bool) diagnostics = get(io, :diagnostics, nothing) inlay_hints = get(io, :inlay_hints, nothing) + maxtypedepth = get(io, :maxtypedepth, nothing) print(io, post) T_str = string(T) + if maxtypedepth !== nothing + sz = get(io, :displaysize, displaysize(io))::Tuple{Int, Int} + T_str = Base.type_depth_limit(T_str, max(sz[2], 120); maxdepth=maxtypedepth) + end if iswarn && is_type_unstable(T) color = is_small_union_or_tunion(T) ? :yellow : :red printstyled(io, "::", T_str; color) diff --git a/src/Cthulhu.jl b/src/Cthulhu.jl index e3db6de1..0c4b6531 100644 --- a/src/Cthulhu.jl +++ b/src/Cthulhu.jl @@ -47,6 +47,7 @@ Base.@kwdef mutable struct CthulhuConfig inlay_types_vscode::Bool = true diagnostics_vscode::Bool = true jump_always::Bool = false + type_depth_limit::Union{Nothing, Int} = 2 end """ @@ -411,6 +412,7 @@ function _descend(term::AbstractTerminal, interp::AbstractInterpreter, curs::Abs inlay_types_vscode::Bool = CONFIG.inlay_types_vscode, # default is true diagnostics_vscode::Bool = CONFIG.diagnostics_vscode, # default is true jump_always::Bool = CONFIG.jump_always, # default is false + type_depth_limit::Union{Nothing, Int} = CONFIG.type_depth_limit, # default is 2 ) if isnothing(hide_type_stable) @@ -651,7 +653,7 @@ function _descend(term::AbstractTerminal, interp::AbstractInterpreter, curs::Abs remarks, with_effects, exception_type, inline_cost, type_annotations, annotate_source, inlay_types_vscode, diagnostics_vscode, - jump_always) + jump_always, type_depth_limit) elseif toggle === :warn iswarn ⊻= true diff --git a/src/codeview.jl b/src/codeview.jl index bc55aa42..a61078e6 100644 --- a/src/codeview.jl +++ b/src/codeview.jl @@ -118,7 +118,8 @@ function cthulhu_typed(io::IO, debuginfo::Symbol, debuginfo = IRShow.debuginfo(debuginfo) lineprinter = __debuginfo[debuginfo] rettype = ignorelimited(rt) - lambda_io = IOContext(io, :limit=>true) + maxtypedepth = CONFIG.type_depth_limit + lambda_io = IOContext(io, :limit=>true, :maxtypedepth => maxtypedepth) if annotate_source && isa(src, CodeInfo) tsn, _ = get_typed_sourcetext(mi, src, rt) @@ -143,7 +144,8 @@ function cthulhu_typed(io::IO, debuginfo::Symbol, vscode_io = IOContext( jump_always && inlay_types_vscode ? devnull : lambda_io, :inlay_hints => inlay_types_vscode ? Dict{String,Vector{TypedSyntax.InlayHint}}() : nothing , - :diagnostics => diagnostics_vscode ? TypedSyntax.Diagnostic[] : nothing + :diagnostics => diagnostics_vscode ? TypedSyntax.Diagnostic[] : nothing, + :maxtypedepth => maxtypedepth ) if istruncated @@ -154,7 +156,7 @@ function cthulhu_typed(io::IO, debuginfo::Symbol, callsite_diagnostics = TypedSyntax.Diagnostic[] if (diagnostics_vscode || inlay_types_vscode) - vscode_io = IOContext(devnull, :inlay_hints=>vscode_io[:inlay_hints], :diagnostics=>vscode_io[:diagnostics]) + vscode_io = IOContext(devnull, :inlay_hints=>vscode_io[:inlay_hints], :diagnostics=>vscode_io[:diagnostics], maxtypedepth=CONFIG.type_depth_limit) callsite_mis = Dict() # type annotation is a bit long so I skipped it, doesn't seem to affect performance visited_mis = Set{MethodInstance}((mi,)) add_callsites!(callsite_mis, visited_mis, callsite_diagnostics, mi; optimize, annotate_source, interp) @@ -186,6 +188,7 @@ function cthulhu_typed(io::IO, debuginfo::Symbol, show_variables(io, src, slotnames) end end + maxtypedepth = CONFIG.type_depth_limit # preprinter configuration preprinter = if src isa IRCode && inline_cost @@ -215,7 +218,7 @@ function cthulhu_typed(io::IO, debuginfo::Symbol, idx == -1 ? lpad(total_cost, nd+1) : " "^(nd+1) str = sprint(; context=:color=>true) do @nospecialize io - printstyled(io, str; color=:green) + printstyled(io, str; color=:green, maxtypedepth) end if debuginfo === :source str *= " " @@ -263,7 +266,7 @@ function cthulhu_typed(io::IO, debuginfo::Symbol, function (io::IO; idx::Int, @nospecialize(kws...)) _postprinter(io; idx, kws...) for i = searchsorted(pc2remarks, idx=>"", by=((idx,msg),)->idx) - printstyled(io, ' ', pc2remarks[i].second; color=:light_black) + printstyled(io, ' ', pc2remarks[i].second; color=:light_black, maxtypedepth) end end else @@ -301,8 +304,9 @@ function descend_into_callsite!(io::IO, tsn::TypedSyntaxNode; # We empty the body when filling kwargs istruncated = isempty(children(body)) idxend = istruncated ? JuliaSyntax.last_byte(sig) : lastindex(tsn.source) + maxtypedepth = CONFIG.type_depth_limit if !istruncated # If method only fills in default arguments - printstyled(io, tsn; type_annotations, iswarn, hide_type_stable, idxend) + printstyled(io, tsn; type_annotations, iswarn, hide_type_stable, idxend, maxtypedepth) end end diff --git a/src/ui.jl b/src/ui.jl index 18ff7ee9..a3fc435b 100644 --- a/src/ui.jl +++ b/src/ui.jl @@ -65,7 +65,8 @@ function build_options(callsites, with_effects::Bool, exception_type::Bool, opti end str = string(chomp( sprint(node; context=:color=>true) do io, node - limiter = TextWidthLimiter(io, reduced_displaysize) + ioc = IOContext(io, :maxtypedepth=>CONFIG.type_depth_limit) + limiter = TextWidthLimiter(ioc, reduced_displaysize) if TypedSyntax.is_runtime(node) if iswarn printstyled(limiter, "runtime "; color=:red) diff --git a/test/runtests.jl b/test/runtests.jl index f956e3ef..752ce79f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,8 @@ using Test, PerformanceTestTools +using Cthulhu +Cthulhu.CONFIG.type_depth_limit = nothing # disable type-depth limit printing in tests + @testset "runtests.jl" begin @testset "test_Cthulhu.jl" begin include("test_Cthulhu.jl") diff --git a/test/test_depth_limited_type_printing.jl b/test/test_depth_limited_type_printing.jl new file mode 100644 index 00000000..7e9123c4 --- /dev/null +++ b/test/test_depth_limited_type_printing.jl @@ -0,0 +1,45 @@ +#= +using Revise; include(joinpath("test", "test_depth_limited_type_printing.jl")) +=# +import Cthulhu + +Base.@kwdef struct Nested{A,B} + num::Int = 1 +end +bar(x) = rand() > 0.5 ? x : Any[0][1] +mysum(x) = sum(y-> bar(x.num), 1:5; init=0) +nest_val(na, nb, ::Val{1}) = Nested{na, nb}() +nest_val(na, nb, ::Val{n}) where {n} = nest_val(Nested{na, nb}, Nested{na, nb}, Val(n-1)) +nest_val(na, nb, n::Int) = nest_val(na, nb, Val(n)) +nest_val(n) = nest_val(1, 1, n) +const NV = nest_val(5) + +# f = nest_val(5) +# a = Any[f]; +# mysum(a[1]) # make sure it runs +# Cthulhu.@descend mysum(a[1]) # navigate to sum -> sum, and Nested will be there +using Test +include("setup.jl") +@testset "hide type-stable statements" begin + let # optimize code + # f = nest_val(5) + # a = Any[f]; + # mysum(a[1]) # make sure it runs + # Cthulhu.@descend mysum(a[1]) # navigate to sum -> sum, and Nested will be there + (; src, infos, mi, rt, exct, effects, slottypes) = @eval Module() begin + $cthulhu_info($mysum, ($(typeof(NV)),)) + end; + function prints(; kwargs...) + io = IOBuffer() + ioc = IOContext(io, :maxtypedepth => Cthulhu.CONFIG.type_depth_limit) + Cthulhu.cthulhu_typed(ioc, :none, src, rt, exct, effects, mi; kwargs...) + return String(take!(io)) + end; + + let # by default, should print every statement + s = prints() + println(s) + # @test occursin("::Nested{Nested{…}, Nested{…}}", s) + end + end +end