Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update implementation and tests for Julia 1.10, 1.11 #130

Merged
merged 8 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
version:
- '1.6' # latest LTS
- '1'
- 'pre'
- 'nightly'
os:
- ubuntu-latest
Expand All @@ -43,7 +44,7 @@ jobs:
Pkg.test("Revise")
'
- name: Test while running Revise
if: ${{ matrix.os == 'ubuntu-latest' && matrix.version != '1.0' }}
if: ${{ matrix.os == 'ubuntu-latest' && (matrix.version == '1.6' || matrix.version == '1') }}
run: |
TERM="xterm" julia --project -i --code-coverage -e '
using InteractiveUtils, REPL, Revise, Pkg
Expand Down
8 changes: 8 additions & 0 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,15 @@ function is_func_expr(@nospecialize(ex), meth::Method)
end
end
found && break
if isexpr(whereex, :(::))
typeex = whereex.args[end]
if isexpr(typeex, :curly) && typeex.args[1] === :Type
fname = typeex.args[2]
break
end
end
whereex = whereex.args[1]
isa(whereex, Expr) || return false
end
end
# match the function name
Expand Down
49 changes: 33 additions & 16 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ isdefined(Main, :Revise) ? Main.Revise.includet("script.jl") : include("script.j
@test startswith(src, "@inline")
@test line == 16
@test @code_string(multilinesig(1, "hi")) == src
@test_throws ErrorException("no unique matching method found for the specified argument types") @code_string(multilinesig(1, 2))
if Base.VERSION < v"1.11.0-0"
@test_throws ErrorException("no unique matching method found for the specified argument types") @code_string(multilinesig(1, 2))
else
@test_throws "but no method is defined for this combination of argument types" @code_string(multilinesig(1, 2))
end

m = first(methods(f50))
src, line = definition(String, m)
Expand All @@ -78,7 +82,8 @@ isdefined(Main, :Revise) ? Main.Revise.includet("script.jl") : include("script.j
io = PipeBuffer()
show(io, info)
str = read(io, String)
@test startswith(str, "PkgFiles(CodeTracking [da1fd8a2-8d9e-5ec2-8556-3022fb5608a2]):\n basedir:")
@test startswith(str, "PkgFiles(CodeTracking [da1fd8a2-8d9e-5ec2-8556-3022fb5608a2]):\n basedir:") ||
startswith(str, "PkgFiles(Base.PkgId(Base.UUID(\"da1fd8a2-8d9e-5ec2-8556-3022fb5608a2\"), \"CodeTracking\")):\n basedir:")
ioctx = IOContext(io, :compact=>true)
show(ioctx, info)
str = read(io, String)
Expand Down Expand Up @@ -132,7 +137,9 @@ isdefined(Main, :Revise) ? Main.Revise.includet("script.jl") : include("script.j
idx = findfirst(lin -> String(lin.file) != @__FILE__, src.linetable)
lin = src.linetable[idx]
file, line = whereis(lin, m)
@test endswith(file, String(lin.file))
if !Sys.iswindows()
@test endswith(file, String(lin.file))
end

# Issues raised in #48
m = @which(sum([1]; dims=1))
Expand Down Expand Up @@ -247,6 +254,12 @@ isdefined(Main, :Revise) ? Main.Revise.includet("script.jl") : include("script.j
src, line = definition(String, m)
@test occursin("(::Type{T})(itr) where {T<:Invert}", src)
@test line == 126
m = @which MyArray1{Float64, 1}(undef, 5)
src, line = definition(String, m)
@test occursin("(self::Type{MyArray1{T,1}})(::UndefInitializer", src)
m = @which MyArray2{Float64, 1}(undef, 5)
src, line = definition(String, m)
@test occursin("(::Type{MyArray2{T,1}})(::UndefInitializer", src)

# Invalidation-insulating methods used by Revise and perhaps others
d = IdDict{Union{String,Symbol},Union{Function,Vector{Function}}}()
Expand All @@ -256,13 +269,13 @@ isdefined(Main, :Revise) ? Main.Revise.includet("script.jl") : include("script.j
# Issue 115, Cthulhu issue 404
m = @which (Vector)(Int[])
src, line = definition(String, m)
@test occursin("(Array{T,N} where T)(x::AbstractArray{S,N}) where {S,N}", src)
@test occursin(filter(!isspace, "(Array{T,N} where T)(x::AbstractArray{S,N}) where {S,N}"), filter(!isspace, src))
@test line == m.line

# Issue 115, Cthulhu issue 474
m = @which NamedTuple{(),Tuple{}}(())
m = @which MyNamedTuple{(),Tuple{}}(())
src, line = definition(String, m)
@test occursin("NamedTuple{names, T}(args::T) where {names, T <: Tuple}", src)
@test occursin("MyNamedTuple{names, T}(args::T) where {names, T <: Tuple}", src)
@test line == m.line

# Parsed result gives a symbol instead of expression
Expand Down Expand Up @@ -293,11 +306,13 @@ end
@test occursin(String(m.file), String(body.args[idx].file))
@test ex == code_expr(gcd, Tuple{Int,Int})

m = first(methods(edit))
sigs = signatures_at(String(m.file), m.line)
@test !isempty(sigs)
sigs = signatures_at(Base.find_source_file(String(m.file)), m.line)
@test !isempty(sigs)
if Base.VERSION < v"1.11.0-0"
m = first(methods(edit))
sigs = signatures_at(String(m.file), m.line)
@test !isempty(sigs)
sigs = signatures_at(Base.find_source_file(String(m.file)), m.line)
@test !isempty(sigs)
end

# issue #23
@test !isempty(signatures_at("script.jl", 9))
Expand Down Expand Up @@ -384,7 +399,9 @@ end
return m
end"""
body, _ = CodeTracking.definition(String, @which Foo.Bar.fit(1, 2))
@test body == "Foo.Bar.fit(a, b) = a + b"
if Base.VERSION < v"1.10"
@test body == "Foo.Bar.fit(a, b) = a + b"
end
end

struct CallOverload
Expand All @@ -403,10 +420,10 @@ end

@testset "kwfuncs" begin
body, _ = CodeTracking.definition(String, @which fkw(; x=1))
@test body == """
@test startswith(body, """
function fkw(; x=1)
x
end"""
end""")
end

@testset "Decorated args" begin
Expand All @@ -425,12 +442,12 @@ end
body, _ = CodeTracking.definition(String, which(hasdefault, (Int, Float32)))
@test body == "hasdefault(xd, yd=2) = xd + yd"
body, _ = CodeTracking.definition(String, which(hasdefaulttypearg, (Type{Float32},)))
@test body == "hasdefaulttypearg(::Type{T}=Rational{Int}) where T = zero(T)"
@test startswith(body, "hasdefaulttypearg(::Type{T}=Rational{Int}) where T = zero(T)")
end

@testset "tuple-destructured args" begin
body, _ = CodeTracking.definition(String, which(diffminmax, (Any,)))
@test body == "diffminmax((min, max)) = max - min"
@test startswith(body, "diffminmax((min, max)) = max - min")
end

@testset "strip_gensym with unicode" begin
Expand Down
20 changes: 20 additions & 0 deletions test/script.jl
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,23 @@ only(methods(wrongline)).line = 9999 # unclear how it happened in the wild, bu
# Nested `where`s
struct Parametric{N} end
(::Type{P})(x::Int) where P<:Parametric{N} where N = P()

# `where`s that are not simply `(::Type{T})(args...) where T<:SomeSpecialType`
struct MyArray1{T,N}
data::T
end
function (self::Type{MyArray1{T,1}})(::UndefInitializer, m::Int) where {T}
return nothing
end
struct MyArray2{T,N}
data::T
end
function (::Type{MyArray2{T,1}})(::UndefInitializer, m::Int) where {T}
return nothing
end

# Issue #115
struct MyNamedTuple{names, T} end
@eval (MyNamedTuple{names, T}(args::T) where {names, T <: Tuple}) = begin
$(Expr(:splatnew, :(MyNamedTuple{names, T}), :args))
end
Loading