-
Notifications
You must be signed in to change notification settings - Fork 640
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
fix: macro parameter with default value overshadowed by unrelated macro #791
Conversation
Hi, thanks for working on this! I haven't looked at this as closely as you have, I'm sure, but this fix doesn't feel right to me. I wonder if the real problem is that in |
The compile-time frame can not have the same value with run-time frame. Because the macro parameter is dynamic, the parameter will have a value only when macro calling. So, the parameter can only run on run-time. In compile-time the parameter should be a normal variable. I tried set frame variable, but I found that I can only set it as a string or some other type value. I don't find a way to set frame value as a variable. So I change the |
Yeah, but I mean instead of |
Oh, yes I tried that just replace This solution is seems more useful, which do not need to hack the |
'{% endmacro %}' + | ||
'' + | ||
'{# calling macro2 #}' + | ||
'{{macro2("this should be outputted") }}', {}, {}, function(err, res) { |
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 a bit misleading, this text in fact should not be output, in this case
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 test output asset to equal foo
. my last post code is
{# macro1 and macro2 definition #}
{% macro macro1() %}
{% endmacro %}
{% macro macro2(text="default") %}
{{macro1}}
{% endmacro %}
{# calling macro2 #}
{{macro2("this should be outputted") }}
in this case, output will be the macro1
source code. But this output have no problem, because {{macro1}}
should output this function toString. so I delete that post, which is mistake.
After I change it to {{macro1()}}
.
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.
my comment here was just that using the text "this should be outputted" in your test, when that text actually shouldn't be output, is confusing :-) the test and the assert are both correct.
Hmm, well that's interesting. I was convinced by your last post (now deleted?) about why that wouldn't work :-) Do you understand how your second test still passes here? |
What I mean is, after this change to an isolated frame inside the macro, I don't quite understand how |
First, let us take a look how this bug happen. When parse
compiler will output code like this // this is macro function body
var macro_t_1 = runtime.makeMacro([], [], () => ());
context.addExport("macro1");
context.setVariable("macro1", macro_t_1); At the same time, compile-time frame will add varibale var funcId = this._compileMacro(node, frame);
// Expose the macro to the templates
var name = node.name.value;
frame.set(name, funcId); So, compiler continue parse, when deal with
When symbol frame.set("macro1", kwargs.hasOwnProperty("macro1") ? kwargs["macro1"] : "default");
var t_4 = "";
_4 += runtime.suppressValue(macro_t_1, env.opts.autoescape); First macro1 argument will add to run-time frame, but the Now, why the second test will pass. When compileMacro compile-time frame is a new frame, so when var t_4 = "";
t_4 += runtime.suppressValue((lineno = 0,
colno = 96,
runtime.callWrap(runtime.contextOrFrameLookup(context, frame, "macro1"), "macro1", context, [])), env.opts.autoescape); In my first test case, code generate is just the same as the next one. Only diff difference is the local argument value set
So, at the first test, symbol |
Thanks for the explanation! Looks great, merging. |
close #774
There is only a little code to fix that issue. If their is some problem, I will fix soon. Or maybe their is some more good solution, I don't sure if this realization is good or not.