From b86fa137c4fee6fcc365820964af820b342eff0a Mon Sep 17 00:00:00 2001 From: TEC Date: Mon, 29 Apr 2024 21:44:58 +0800 Subject: [PATCH] Implement eval-able AnnotatedString 2-arg show The generic/fallback AbstractString 2-arg show omits the annotations, meaning that eval(Meta.parse(repr(::AnnotatedString))) doesn't round-trip. The resolution to this is fairly simple, we just need to implement a specialised show method. The implementation is fairly obvious, we're just also able to get away with hiding the vector type annotation since the constructor is fine without it. --- base/strings/annotated.jl | 16 ++++++++++++++++ test/strings/annotated.jl | 4 ++++ 2 files changed, 20 insertions(+) diff --git a/base/strings/annotated.jl b/base/strings/annotated.jl index 2a331c5133f838..bf510cab82052a 100644 --- a/base/strings/annotated.jl +++ b/base/strings/annotated.jl @@ -159,6 +159,22 @@ function getindex(s::AnnotatedString, i::Integer) end end +# To make `AnnotatedString`s repr-evaluable, we need to override +# the generic `AbstractString` 2-arg show method. + +function show(io::IO, s::A) where {A <: AnnotatedString} + show(io, A) + print(io, '(') + show(io, s.string) + print(io, ", ") + show(IOContext(io, :typeinfo => typeof(annotations(s))), annotations(s)) + print(io, ')') +end + +# But still use the generic `AbstractString` fallback for the 3-arg show. +show(io::IO, ::MIME"text/plain", s::AnnotatedString) = + invoke(show, Tuple{IO, AbstractString}, io, s) + ## AbstractChar interface ## ncodeunits(c::AnnotatedChar) = ncodeunits(c.char) diff --git a/test/strings/annotated.jl b/test/strings/annotated.jl index b70a2350757a27..d6d1153fd92cbf 100644 --- a/test/strings/annotated.jl +++ b/test/strings/annotated.jl @@ -58,6 +58,10 @@ (3:3, :val => 2)])), Base.AnnotatedString("abc", [(1:2, :val => 1), (2:3, :val => 2)])) + @test chopprefix(sprint(show, str), "Base.") == + "AnnotatedString{String}(\"some string\", [(1:4, :thing => 0x01), (1:11, :all => 0x03), (6:11, :other => 0x02)])" + @test eval(Meta.parse(repr(str))) == str + @test sprint(show, str, MIME("text/plain")) == "\"some string\"" end @testset "AnnotatedChar" begin