-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Add callsuper macro. #20131
Add callsuper macro. #20131
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1382,6 +1382,7 @@ export | |
@polly, | ||
|
||
@assert, | ||
@callsuper, | ||
@enum, | ||
@label, | ||
@goto, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -750,3 +750,47 @@ kwdef_val(::Type{Cwstring}) = Cwstring(C_NULL) | |
kwdef_val{T<:Integer}(::Type{T}) = zero(T) | ||
|
||
kwdef_val{T}(::Type{T}) = T() | ||
|
||
""" | ||
@callsuper f(x::T, y::S, ...) | ||
|
||
Call the method of function `f` with parameter signature specified by `T`, `S`, etc. | ||
""" | ||
macro callsuper(ex) | ||
ex.head == :call || error("@invoke requires a call expression") | ||
fname = ex.args[1] | ||
args = ex.args[2:end] | ||
types = Symbol[] | ||
vals = Symbol[] | ||
kwargs = Any[] | ||
blk = quote end | ||
for arg in args | ||
if isa(arg,Expr) && arg.head == :kw | ||
push!(kwargs, QuoteNode(arg.args[1])) | ||
push!(kwargs, esc(arg.args[2])) | ||
elseif isa(arg,Expr) && arg.head == :parameters | ||
for aarg in arg.args | ||
push!(kwargs, QuoteNode(aarg.args[1])) | ||
push!(kwargs, esc(aarg.args[2])) | ||
end | ||
else | ||
val = gensym() | ||
typ = gensym() | ||
push!(vals, val) | ||
push!(types, typ) | ||
if isa(arg,Expr) && arg.head == :(::) && length(arg.args) == 2 | ||
push!(blk.args, :($typ = $(esc(arg.args[2])))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, |
||
push!(blk.args, :($val = $(esc(arg.args[1]))::$typ)) | ||
else | ||
push!(blk.args, :($val = $(esc(arg)))) | ||
push!(blk.args, :($typ = typeof($val))) | ||
end | ||
end | ||
end | ||
if isempty(kwargs) | ||
push!(blk.args, :(invoke($(esc(fname)), Tuple{$(types...)}, $(vals...)))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually,
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a lowering bug. The lowering code should emit a temporary variable to hold |
||
else | ||
push!(blk.args, :(invoke(Core.kwfunc($(esc(fname))), Tuple{Vector{Any}, typeof($(esc(fname))), $(types...)}, [$(kwargs...)], $(esc(fname)), $(vals...)))) | ||
end | ||
return blk | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -123,6 +123,7 @@ Core.applicable | |
Core.invoke | ||
Base.:(|>) | ||
Base.:(∘) | ||
Base.@callsuper | ||
``` | ||
|
||
## Syntax | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not entirely correct. A few cases that should be handled and possibly tested are. (These are the reason I started but didn't finish the pr yet...)
Evaluation order
Currently
:parameters
are always evaluated the first. It's not necessarily the best choice but this should be consisent with normal calls.:parameters
can have...
:parameters
can have non:kw
in itpositional arguments can also have
...
if
parameter
only have...
s and all of them are empty, the non-kw version should be called.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what non-
:kw
can a:parameters
have other than...
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any, iterable objects
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yuyichao, wouldn't be easier all around if you just did this PR? There was a similar back and forth when I proposed a possible implementation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe. I started an implementation but haven't finished it yet (collecting data of what input should/can be supported and what generic fallback path I can use).....