dpinol / closure-templates

Automatically exported from code.google.com/p/closure-templates
Apache License 2.0
0 stars 0 forks source link

Unwanted args are passed to nested templates. #55

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Create the following soy file:

{namespace bugs}

/**
 * @param? arg1
 * @param? arg2
 * @param? arg3
 */
{template .nested}
    {if $arg1}Arg1<br/>{/if}
    {if $arg2}Arg2<br/>{/if}
    {if $arg3}Arg3<br/>{/if}
{/template}

/**
 * @param? arg1
 * @param? arg2
 * @param? arg3
 */
{template .root}
    {call .nested}
        {param arg1: $arg1 /}
        {param arg2: $arg2 /}
    {/call}
    {if $arg3}
    // I don't actually care.
    {/if}
{/template}

2. Compile to JS

3. console.log(bugs.root({ arg1:true, arg2:true, arg3: true}))

What is the expected output? What do you see instead?

Expected:
"Arg1<br/>Arg2<br/>"

Actual:
"Arg1<br/>Arg2<br/>Arg3<br/>"

What version of the product are you using? On what operating system?
Windows, Soy V2

Please provide any additional information below.

The compiler is trying to optimize and is passing through the whole opt_data 
object to the nested template.  This is causing arg3 to be sent to .nested when 
it shouldn't be.

Original issue reported on code.google.com by hitsthi...@gmail.com on 25 Mar 2012 at 10:45

GoogleCodeExporter commented 8 years ago
While we agree that this behavior is odd, we also feel the optimization here is 
too valuable to remove. This is a corner case that is easily handled by passing 
arg3 = false.

Original comment by kai.hu...@gmail.com on 26 Mar 2012 at 6:28

GoogleCodeExporter commented 8 years ago
That's fair - it's a good optimization in most cases.

The problem is it's wrong behavior that is hard to notice (I only noticed 
because I went overboard and actually wrote tests for my templates).  I would 
imagine most people won't be able to implement the workaround simply because 
they won't see the problem, and will find subtle bugs later on.

Is there some halfway we can find?

1. Is it possible to disable the optimization only if the callee has matching 
params to the caller that aren't passed in? Should just be a compile-time 
check, and would only affect optimization where it is unwanted.

2. Is there a flag we can set on the compiler to disable the optimization?

If you guys accept patches, I'm happy to give this a try myself.  Which method 
would you prefer (or is there something else you'd recommend)?

Original comment by hitsthi...@gmail.com on 26 Mar 2012 at 8:47

GoogleCodeExporter commented 8 years ago
Sure, we could consider adding #1 to the task list.

We're not taking patches at this time, but you can of course feel free to 
modify it and use your own version. This will be low priority because no one 
else has reported running into this problem (not even all the projects within 
Google).

Original comment by kai.hu...@gmail.com on 27 Mar 2012 at 6:29

GoogleCodeExporter commented 8 years ago
Ok - I'll try patching it, and if I succeed I'll post the patch here in case it 
helps (though it will be hard as a non-Java guy =( ).

Would love to see this get fixed in the core though so I don't have to fork. 
Plus, I'd bet projects in Google _have_ hit this. IMO, it's more likely that 
they either just haven't noticed yet ("why is this title attribute on all the 
child elements as well..."), or ended up using the workaround. It seems like 
it'd be pretty easy to hit if you have composable templates and standard @param 
names for things like $innerHTML|$content|$body, $href, $title, etc.

Original comment by hitsthi...@gmail.com on 27 Mar 2012 at 11:20