[stringtemplate-interest] bug? calling template with null argument

John Snyders jjsnyders at rcn.com
Fri Jan 12 19:32:58 PST 2007


I think I have the fix for this bug but I would like a second opinion if
possible.

In StringTemplate.java method
public Object get(StringTemplate self, String attribute)

I changed this:
  if ( o==null && self.enclosingInstance!=null ) {
      Object valueFromEnclosing = get(self.enclosingInstance, attribute);
      if ( valueFromEnclosing==null ) {
        checkNullAttributeAgainstFormalArguments(self, attribute);
      }
      o = valueFromEnclosing;
  }
To this:
  // not locally defined, check enclosingInstance if embedded
  if ( o==null && self.enclosingInstance!=null ) {
      Object valueFromEnclosing = get(self.enclosingInstance, attribute);
      if ( valueFromEnclosing==null ) {
        checkNullAttributeAgainstFormalArguments(this, attribute);
      }
      o = valueFromEnclosing;
  }

The only change is replacing self with this when calling
checkNullAttributeAgainstFormatArguments.

The get method is called with this being the inner most template in the
example below it is template input. The code above is invoked when there is
still no value for the attribute and it recursively goes up the call stack
looking for a value. When no value is found the checkNull... method is used
just to make sure the attribute is defined by some template in the call
stack. It is purely for runtime correctness checking. The problem is that
self has no meaning at this point. The reason is that the get recursion ends
when self is the second template from the top of the stack. The fix is to
start looking for the attribute in the arguments starting with the template
you are in which is this.

Not sure I explained that well but take a look. So far I have not noticed
any problems from this change but I have not run the unit tests.

-John


  -----Original Message-----
  From: John Snyders [mailto:jjsnyders at rcn.com]
  Sent: Friday, January 12, 2007 10:38 AM
  To: stringtemplate-interest at antlr.org
  Subject: bug? calling template with null argument


  Hi all,
  I am finding that I can't call a template with a null argument either
explicitly or by omission unless the call is made from the top level
template.

  Here is an example of what I am trying to do:

  page(name, value) ::= <<
   $input(name=name, value=value, size="22", ...)$
   $input(name=name, value=value, size="23", required="t", ...)$
  >>

  input(name, value, size, required) ::= <<
    <input type="text" name="$name$" size="$size$" value="$value$">
    $if(required)$
    <span class="required">*</span>
    $endif$
  >>

  This example works as intended. The output is
     <input type="text" name="input1" size="22" value="value 1">
     <input type="text" name="input1" size="23" value="value 1">
     <span class="required">*</span>

  However, and here is the bug, when I nest the call to input in another
template (named or anonymous) I get an exception.
  Example:
  page(name, value) ::= <<
   $t2()$
   $input(name=name, value=value, size="22", ...)$
   $input(name=name, value=value, size="23", required="t", ...)$
  >>

  t2() ::= <<
   named template
   $input(name=name, value=value, size="21", ...)$
  >>

  Now I get this exception:
  java.util.NoSuchElementException: no such attribute: required in template
context [page t2(...) input(...)]

  I think this is a bug because the behavior of passing parameters to a
template should not depend on the nesting depth.

  The problem seems to be in
StringTemplate.checkNullAttributeAgainstFormalArguments at the call to
lookupFormalArgument
      FormalArgument formalArg = self.lookupFormalArgument(attribute);
  In the case where input is called from the top level the lookup finds the
argument required but when called from t2 it doesn't. It seems to be looking
in the wrong place. I need to do some more debugging. I'm a bit unclear on
the use of self vs. this. Can someone give an overview of what self is for.

  Now if I remove the ... from the call to input in t2 it works. This
example doesn't need the ... but in my real work I do need to use the ...
  The reason it works without the ... is because of this code in
StringTemplate.get which makes sense
   if ( o==null &&
     !self.passThroughAttributes &&
     self.getFormalArgument(attribute)!=null )
  The call to checkNullAttributeAgainstFormalArguments is never made.

  Any comments? Anyone seen this or can confirm that this is a bug or have a
fix?

  Thanks,
  -John
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org:8080/pipermail/stringtemplate-interest/attachments/20070112/de0d6daa/attachment.html 


More information about the stringtemplate-interest mailing list