velocity-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nbu...@apache.org
Subject svn commit: r735156 - in /velocity/engine/trunk/src: changes/ java/org/apache/velocity/context/ java/org/apache/velocity/runtime/ java/org/apache/velocity/runtime/defaults/ java/org/apache/velocity/runtime/directive/ java/org/apache/velocity/runtime/pa...
Date Fri, 16 Jan 2009 22:13:11 GMT
Author: nbubna
Date: Fri Jan 16 14:13:10 2009
New Revision: 735156

URL: http://svn.apache.org/viewvc?rev=735156&view=rev
Log:
VELOCITY-666 add support for calling macros with a body (thanks to Jarkko Viinamki)

Modified:
    velocity/engine/trunk/src/changes/changes.xml
    velocity/engine/trunk/src/java/org/apache/velocity/context/ProxyVMContext.java
    velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeConstants.java
    velocity/engine/trunk/src/java/org/apache/velocity/runtime/defaults/velocity.properties
    velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java
    velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java
    velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.java
    velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.jj
    velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/ParserTokenManager.java
    velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTDirective.java
    velocity/engine/trunk/src/parser/Parser.jjt

Modified: velocity/engine/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/changes/changes.xml?rev=735156&r1=735155&r2=735156&view=diff
==============================================================================
--- velocity/engine/trunk/src/changes/changes.xml (original)
+++ velocity/engine/trunk/src/changes/changes.xml Fri Jan 16 14:13:10 2009
@@ -27,6 +27,15 @@
   <body>
     <release version="1.7" date="In Subversion">
 
+      
+      <action type="add" dev="byron" issue="VELOCITY-666" due-to="Jarkko Viinamaki">
+        Add support for calling velocimacros with body content by prefixing the macro
+        name with @.
+        (e.g. #macro( bold )<strong>$bodyContent</strong>#end #@bold()any valid
VTL here#end)
+        The $bodyContent reference may be renamed via a velocimacro.body.reference
+        setting in your velocity.properties.
+      </action>
+
       <action type="fix" dev="nbubna" issue="VELOCITY-661" due-to="Jarkko Viinamaki">
         Added #[[this is included in output but not parsed]]# syntax to replace
         and deprecate the much more limited #literal directive

Modified: velocity/engine/trunk/src/java/org/apache/velocity/context/ProxyVMContext.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/context/ProxyVMContext.java?rev=735156&r1=735155&r2=735156&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/context/ProxyVMContext.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/context/ProxyVMContext.java Fri Jan
16 14:13:10 2009
@@ -32,6 +32,7 @@
 import org.apache.velocity.runtime.parser.ParserTreeConstants;
 import org.apache.velocity.runtime.parser.node.ASTReference;
 import org.apache.velocity.runtime.parser.node.Node;
+import org.apache.velocity.runtime.parser.node.ASTBlock;
 import org.apache.velocity.runtime.resource.Resource;
 import org.apache.velocity.util.introspection.IntrospectionCacheData;
 
@@ -56,7 +57,7 @@
     Map vmproxyhash = new HashMap(8, 0.8f);
 
     /** container for any local or constant macro arguments. Size must be power of 2. */
-    Map localcontext = new HashMap(8, 0.8f);;
+    Map localcontext = new HashMap(8, 0.8f);
 
     /** support for local context scope feature, where all references are local */
     private boolean localContextScope;
@@ -123,6 +124,7 @@
             case ParserTreeConstants.JJTMAP:
             case ParserTreeConstants.JJTSTRINGLITERAL:
             case ParserTreeConstants.JJTTEXT:
+            case ParserTreeConstants.JJTBLOCK:
                 return (false);
             default:
                 return (true);
@@ -218,6 +220,28 @@
                     return obj;
                 }
             }
+            else if (type == ParserTreeConstants.JJTBLOCK)
+            {
+                // this happens for #@someMacro($arg1 $arg2) bodyAST #end calls
+                try
+                {
+                    // astNode is actually BlockMacro.BlockMacroContainer which contains
a Writer internally although
+                    // we seem to pass null here
+                    astNode.render(innerContext, null);
+                    // return an empty string because the Node already rendered all content
+                    return "";
+                }
+                catch (RuntimeException e)
+                {
+                    throw e;
+                }
+                catch (Exception e)
+                {
+                    String msg = "ProxyVMContext.get() : error rendering reference";
+                    rsvc.getLog().error(msg, e);
+                    throw new VelocityException(msg, e);
+                }
+            }
             else if (type == ParserTreeConstants.JJTTEXT)
             {
                 // this really shouldn't happen. text is just a throwaway arg for #foreach()

Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeConstants.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeConstants.java?rev=735156&r1=735155&r2=735156&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeConstants.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeConstants.java Fri Jan
16 14:13:10 2009
@@ -164,7 +164,6 @@
      */
     String EVALUATE_CONTEXT_CLASS = "directive.evaluate.context.class";
 
-
     /*
      * ----------------------------------------------------------------------
      *  R E S O U R C E   M A N A G E R   C O N F I G U R A T I O N
@@ -280,6 +279,12 @@
      * @since 1.6
      */
     String VM_MAX_DEPTH = "velocimacro.max.depth";
+
+    /**
+     * Defines name of the reference that can be used to get the AST block passed to block
marco call.
+     * @since 1.7
+     */
+    String VM_BODY_REFERENCE = "velocimacro.body.reference";
     
     /*
      * ----------------------------------------------------------------------

Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/defaults/velocity.properties
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/defaults/velocity.properties?rev=735156&r1=735155&r2=735156&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/defaults/velocity.properties
(original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/defaults/velocity.properties
Fri Jan 16 14:13:10 2009
@@ -127,6 +127,14 @@
 velocimacro.arguments.strict = false
 
 # ----------------------------------------------------------------------------
+# VELOCIMACRO BODY REFERENCE 
+# ----------------------------------------------------------------------------
+# Defines name of the reference that can be used to render the AST block passed to
+# block macro call as an argument inside a macro.
+# ----------------------------------------------------------------------------
+velocimacro.body.reference=bodyContent
+
+# ----------------------------------------------------------------------------
 # STRICT REFERENCE MODE
 # ----------------------------------------------------------------------------
 # if true, will throw a MethodInvocationException for references

Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java?rev=735156&r1=735155&r2=735156&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java
(original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java
Fri Jan 16 14:13:10 2009
@@ -201,7 +201,7 @@
      * @param context
      * @param writer
      * @param node
-     * @return true if the rendering is successfull
+     * @return true if the rendering is successful
      * @throws IOException
      * @throws ResourceNotFoundException
      * @throws ParseErrorException
@@ -212,6 +212,27 @@
             throws IOException, ResourceNotFoundException,
             ParseErrorException, MethodInvocationException
     {
+        return render(context, writer, node, null);
+    }
+    
+    /**
+     * This method is used with BlockMacro when we want to render a macro with a body AST.
+     *
+     * @param context
+     * @param writer
+     * @param node
+     * @param body AST block that was enclosed in the macro body.
+     * @return true if the rendering is successful
+     * @throws IOException
+     * @throws ResourceNotFoundException
+     * @throws ParseErrorException
+     * @throws MethodInvocationException
+     */
+    public boolean render(InternalContextAdapter context, Writer writer,
+                          Node node, Node body)
+            throws IOException, ResourceNotFoundException,
+            ParseErrorException, MethodInvocationException
+    {
         VelocimacroProxy vmProxy = null;
         String renderingTemplate = context.getCurrentTemplateName();
         
@@ -271,7 +292,7 @@
 
             try
             {
-                return vmProxy.render(context, writer, node);
+                return vmProxy.render(context, writer, node, body);
             }
             catch (RuntimeException e)
             {

Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java?rev=735156&r1=735155&r2=735156&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java
(original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java
Fri Jan 16 14:13:10 2009
@@ -55,6 +55,7 @@
     private boolean strictArguments;
     private boolean localContextScope = false;
     private int maxCallDepth;
+    private String bodyReference;
 
     /**
      * Return name of this Velocimacro.
@@ -127,6 +128,12 @@
         return numMacroArgs;
     }
 
+    public boolean render(InternalContextAdapter context, Writer writer, Node node)
+            throws IOException, MethodInvocationException, MacroOverflowException
+    {
+        return render(context, writer, node, null);
+    }
+    
     /**
      * Renders the macro using the context.
      * 
@@ -138,7 +145,7 @@
      * @throws MethodInvocationException
      * @throws MacroOverflowException
      */
-    public boolean render(InternalContextAdapter context, Writer writer, Node node)
+    public boolean render(InternalContextAdapter context, Writer writer, Node node, Node
body)
             throws IOException, MethodInvocationException, MacroOverflowException
     {
         // wrap the current context and add the macro arguments
@@ -153,8 +160,6 @@
             // the 0th element is the macro name
             for (int i = 1; i < argArray.length && i <= callArguments; i++)
             {
-                Node macroCallArgument = node.jjtGetChild(i - 1);
-
                 /*
                  * literalArgArray[i] is needed for "render literal if null" functionality.
                  * The value is used in ASTReference render-method.
@@ -164,9 +169,15 @@
                  * This makes VMReferenceMungeVisitor obsolete and it would not work anyway

                  * when the macro AST is shared
                  */
-                vmc.addVMProxyArg(context, argArray[i], literalArgArray[i], macroCallArgument);
+                vmc.addVMProxyArg(context, argArray[i], literalArgArray[i], node.jjtGetChild(i
- 1));
             }
         }
+        
+        // if this macro was invoked by a call directive, we might have a body AST here.
Put it into context.
+        if( body != null )
+        {
+            vmc.addVMProxyArg(context, bodyReference, "", body);
+        }
 
         /*
          * check that we aren't already at the max call depth
@@ -242,6 +253,9 @@
 
         // get the macro call depth limit
         maxCallDepth = rsvc.getInt(RuntimeConstants.VM_MAX_DEPTH);
+
+        // get name of the reference that refers to AST block passed to block macro call
+        bodyReference = rsvc.getString(RuntimeConstants.VM_BODY_REFERENCE, "bodyContent");
     }
     
 

Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.java?rev=735156&r1=735155&r2=735156&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.java Fri Jan
16 14:13:10 2009
@@ -740,17 +740,24 @@
 
         if ( d == null)
         {
-            /*
-             *  if null, then not a real directive, but maybe a Velocimacro
-             */
-
-            isVM = rsvc.isVelocimacro(directiveName, currentTemplateName);
-
-            /*
-             *  Currently, all VMs are LINE directives
-             */
-
-            directiveType = Directive.LINE;
+            if( directiveName.startsWith("@") )
+            {
+                // block macro call of type: #@foobar($arg1 $arg2) astBody #end
+                directiveType = Directive.BLOCK;
+            }
+            else
+            {
+                /*
+                 *  if null, then not a real directive, but maybe a Velocimacro
+                 */
+
+                isVM = rsvc.isVelocimacro(directiveName, currentTemplateName);
+
+                /*
+                 * Currently, all VMs are LINE directives
+                 */
+                directiveType = Directive.LINE;
+            }
         }
         else
         {
@@ -2743,21 +2750,6 @@
     finally { jj_save(11, xla); }
   }
 
-  private boolean jj_3_8() {
-    if (jj_3R_33()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_40() {
-    if (jj_scan_token(INTEGER_LITERAL)) return true;
-    return false;
-  }
-
-  private boolean jj_3R_74() {
-    if (jj_3R_73()) return true;
-    return false;
-  }
-
   private boolean jj_3R_97() {
     if (jj_scan_token(COMMA)) return true;
     if (jj_3R_29()) return true;
@@ -2780,13 +2772,13 @@
     return false;
   }
 
-  private boolean jj_3R_67() {
-    if (jj_scan_token(FLOATING_POINT_LITERAL)) return true;
+  private boolean jj_3R_71() {
+    if (jj_scan_token(FALSE)) return true;
     return false;
   }
 
-  private boolean jj_3R_71() {
-    if (jj_scan_token(FALSE)) return true;
+  private boolean jj_3R_40() {
+    if (jj_scan_token(INTEGER_LITERAL)) return true;
     return false;
   }
 
@@ -2840,6 +2832,11 @@
     return false;
   }
 
+  private boolean jj_3R_67() {
+    if (jj_scan_token(FLOATING_POINT_LITERAL)) return true;
+    return false;
+  }
+
   private boolean jj_3R_84() {
     if (jj_3R_68()) return true;
     return false;
@@ -3068,13 +3065,13 @@
     return false;
   }
 
-  private boolean jj_3_2() {
-    if (jj_scan_token(DOUBLE_ESCAPE)) return true;
+  private boolean jj_3R_51() {
+    if (jj_3R_65()) return true;
     return false;
   }
 
-  private boolean jj_3R_51() {
-    if (jj_3R_65()) return true;
+  private boolean jj_3_2() {
+    if (jj_scan_token(DOUBLE_ESCAPE)) return true;
     return false;
   }
 
@@ -3185,13 +3182,13 @@
     return false;
   }
 
-  private boolean jj_3R_26() {
-    if (jj_3R_40()) return true;
+  private boolean jj_3R_98() {
+    if (jj_3R_24()) return true;
     return false;
   }
 
-  private boolean jj_3R_98() {
-    if (jj_3R_24()) return true;
+  private boolean jj_3R_26() {
+    if (jj_3R_40()) return true;
     return false;
   }
 
@@ -3241,11 +3238,6 @@
     return false;
   }
 
-  private boolean jj_3_1() {
-    if (jj_3R_24()) return true;
-    return false;
-  }
-
   private boolean jj_3R_69() {
     if (jj_scan_token(LBRACKET)) return true;
     Token xsp;
@@ -3255,6 +3247,11 @@
     return false;
   }
 
+  private boolean jj_3_1() {
+    if (jj_3R_24()) return true;
+    return false;
+  }
+
   private boolean jj_3R_77() {
     Token xsp;
     xsp = jj_scanpos;
@@ -3274,11 +3271,6 @@
     return false;
   }
 
-  private boolean jj_3R_50() {
-    if (jj_3R_71()) return true;
-    return false;
-  }
-
   private boolean jj_3R_68() {
     if (jj_scan_token(LEFT_CURLEY)) return true;
     Token xsp;
@@ -3295,6 +3287,11 @@
     return false;
   }
 
+  private boolean jj_3R_50() {
+    if (jj_3R_71()) return true;
+    return false;
+  }
+
   private boolean jj_3R_49() {
     if (jj_3R_70()) return true;
     return false;
@@ -3331,23 +3328,36 @@
     return false;
   }
 
+  private boolean jj_3R_90() {
+    if (jj_3R_73()) return true;
+    return false;
+  }
+
   private boolean jj_3R_45() {
     if (jj_3R_66()) return true;
     return false;
   }
 
-  private boolean jj_3R_90() {
+  private boolean jj_3R_89() {
     if (jj_3R_73()) return true;
     return false;
   }
 
+  private boolean jj_3R_37() {
+    if (jj_3R_40()) return true;
+    return false;
+  }
+
   private boolean jj_3R_44() {
     if (jj_3R_40()) return true;
     return false;
   }
 
-  private boolean jj_3R_89() {
-    if (jj_3R_73()) return true;
+  private boolean jj_3R_27() {
+    if (jj_scan_token(COMMA)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(31)) jj_scanpos = xsp;
     return false;
   }
 
@@ -3356,8 +3366,8 @@
     return false;
   }
 
-  private boolean jj_3R_37() {
-    if (jj_3R_40()) return true;
+  private boolean jj_3R_34() {
+    if (jj_3R_60()) return true;
     return false;
   }
 
@@ -3366,11 +3376,8 @@
     return false;
   }
 
-  private boolean jj_3R_27() {
-    if (jj_scan_token(COMMA)) return true;
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_scan_token(31)) jj_scanpos = xsp;
+  private boolean jj_3R_36() {
+    if (jj_3R_24()) return true;
     return false;
   }
 
@@ -3413,16 +3420,6 @@
     return false;
   }
 
-  private boolean jj_3R_34() {
-    if (jj_3R_60()) return true;
-    return false;
-  }
-
-  private boolean jj_3R_36() {
-    if (jj_3R_24()) return true;
-    return false;
-  }
-
   private boolean jj_3R_32() {
     if (jj_3R_60()) return true;
     return false;
@@ -3453,13 +3450,23 @@
     return false;
   }
 
-  private boolean jj_3R_65() {
-    if (jj_scan_token(STRING_LITERAL)) return true;
+  private boolean jj_3R_31() {
+    if (jj_3R_40()) return true;
     return false;
   }
 
-  private boolean jj_3R_31() {
-    if (jj_3R_40()) return true;
+  private boolean jj_3_8() {
+    if (jj_3R_33()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_74() {
+    if (jj_3R_73()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_65() {
+    if (jj_scan_token(STRING_LITERAL)) return true;
     return false;
   }
 

Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.jj
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.jj?rev=735156&r1=735155&r2=735156&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.jj (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.jj Fri Jan 16
14:13:10 2009
@@ -1094,8 +1094,8 @@
 TOKEN:
 {
     <#LETTER: [ "a"-"z", "A" - "Z" ] >
-|   <#DIRECTIVE_CHAR: [ "a"-"z", "A"-"Z", "0"-"9", "_" ] >
-|   <WORD:  ( <LETTER> | ["_"]) (<DIRECTIVE_CHAR>)* >
+|   <#DIRECTIVE_CHAR: [ "a"-"z", "A"-"Z", "0"-"9", "_", "@" ] >
+|   <WORD:  ( <LETTER> | ["_"] | ["@"]) (<DIRECTIVE_CHAR>)* >
 |   <BRACKETED_WORD:  "{" ( <LETTER> | ["_"]) (<DIRECTIVE_CHAR>)* "}" >
 
 }
@@ -1618,17 +1618,24 @@
 
         if ( d == null)
         {
-            /*
-             *  if null, then not a real directive, but maybe a Velocimacro
-             */
-
-            isVM = rsvc.isVelocimacro(directiveName, currentTemplateName);
-
-            /*
-             *  Currently, all VMs are LINE directives
-             */
-
-            directiveType = Directive.LINE;
+            if( directiveName.startsWith("@") )
+            {
+                // block macro call of type: #@foobar($arg1 $arg2) astBody #end
+                directiveType = Directive.BLOCK;
+            }
+            else
+            {
+                /*
+                 *  if null, then not a real directive, but maybe a Velocimacro
+                 */
+
+                isVM = rsvc.isVelocimacro(directiveName, currentTemplateName);
+
+                /*
+                 * Currently, all VMs are LINE directives
+                 */
+                directiveType = Directive.LINE;
+            }
         }
         else
         {

Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/ParserTokenManager.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/ParserTokenManager.java?rev=735156&r1=735155&r2=735156&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/ParserTokenManager.java
(original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/ParserTokenManager.java
Fri Jan 16 14:13:10 2009
@@ -805,7 +805,7 @@
             switch(jjstateSet[--i])
             {
                case 0:
-                  if ((0x7fffffe87fffffeL & l) != 0L)
+                  if ((0x7fffffe87ffffffL & l) != 0L)
                   {
                      if (kind > 62)
                         kind = 62;
@@ -914,7 +914,7 @@
                   break;
                case 62:
                case 63:
-                  if ((0x7fffffe87fffffeL & l) == 0L)
+                  if ((0x7fffffe87ffffffL & l) == 0L)
                      break;
                   if (kind > 62)
                      kind = 62;
@@ -925,10 +925,13 @@
                      jjstateSet[jjnewStateCnt++] = 65;
                   break;
                case 65:
-               case 66:
                   if ((0x7fffffe87fffffeL & l) != 0L)
                      jjCheckNAddTwoStates(66, 67);
                   break;
+               case 66:
+                  if ((0x7fffffe87ffffffL & l) != 0L)
+                     jjCheckNAddTwoStates(66, 67);
+                  break;
                case 67:
                   if (curChar == 125 && kind > 63)
                      kind = 63;
@@ -1563,7 +1566,7 @@
             switch(jjstateSet[--i])
             {
                case 3:
-                  if ((0x7fffffe87fffffeL & l) != 0L)
+                  if ((0x7fffffe87ffffffL & l) != 0L)
                   {
                      if (kind > 62)
                         kind = 62;
@@ -1616,7 +1619,7 @@
                   break;
                case 15:
                case 16:
-                  if ((0x7fffffe87fffffeL & l) == 0L)
+                  if ((0x7fffffe87ffffffL & l) == 0L)
                      break;
                   if (kind > 62)
                      kind = 62;
@@ -1627,10 +1630,13 @@
                      jjstateSet[jjnewStateCnt++] = 18;
                   break;
                case 18:
-               case 19:
                   if ((0x7fffffe87fffffeL & l) != 0L)
                      jjCheckNAddTwoStates(19, 20);
                   break;
+               case 19:
+                  if ((0x7fffffe87ffffffL & l) != 0L)
+                     jjCheckNAddTwoStates(19, 20);
+                  break;
                case 20:
                   if (curChar == 125 && kind > 63)
                      kind = 63;
@@ -2388,7 +2394,7 @@
                   break;
                case 21:
                case 22:
-                  if ((0x7fffffe87fffffeL & l) == 0L)
+                  if ((0x7fffffe87ffffffL & l) == 0L)
                      break;
                   if (kind > 13)
                      kind = 13;
@@ -2399,10 +2405,13 @@
                      jjstateSet[jjnewStateCnt++] = 24;
                   break;
                case 24:
-               case 25:
                   if ((0x7fffffe87fffffeL & l) != 0L)
                      jjCheckNAddTwoStates(25, 26);
                   break;
+               case 25:
+                  if ((0x7fffffe87ffffffL & l) != 0L)
+                     jjCheckNAddTwoStates(25, 26);
+                  break;
                case 26:
                   if (curChar == 125 && kind > 13)
                      kind = 13;

Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTDirective.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTDirective.java?rev=735156&r1=735155&r2=735156&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTDirective.java
(original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTDirective.java
Fri Jan 16 14:13:10 2009
@@ -30,6 +30,7 @@
 import org.apache.velocity.exception.TemplateInitException;
 import org.apache.velocity.runtime.directive.Directive;
 import org.apache.velocity.runtime.directive.RuntimeMacro;
+import org.apache.velocity.runtime.directive.BlockMacro;
 import org.apache.velocity.runtime.parser.ParseException;
 import org.apache.velocity.runtime.parser.Parser;
 import org.apache.velocity.util.ExceptionUtils;
@@ -124,6 +125,28 @@
                 directive.setLocation(getLine(), getColumn(), getTemplateName());
                 directive.init(rsvc, context,this);
             }
+            else if( directiveName.startsWith("@") )
+            {
+                // block macro call (normal macro call but has AST body)
+                directiveName = directiveName.substring(1);
+
+                directive = new BlockMacro(directiveName);
+                directive.setLocation(getLine(), getColumn(), getTemplateName());
+
+                try
+                {
+                    directive.init( rsvc, context, this );
+                }
+                catch (TemplateInitException die)
+                {
+                    throw new TemplateInitException(die.getMessage(),
+                            (ParseException) die.getWrappedThrowable(),
+                            die.getTemplateName(),
+                            die.getColumnNumber() + getColumn(),
+                            die.getLineNumber() + getLine());
+                }
+                isDirective = true;
+            }
             else
             {
                 /**

Modified: velocity/engine/trunk/src/parser/Parser.jjt
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/parser/Parser.jjt?rev=735156&r1=735155&r2=735156&view=diff
==============================================================================
--- velocity/engine/trunk/src/parser/Parser.jjt (original)
+++ velocity/engine/trunk/src/parser/Parser.jjt Fri Jan 16 14:13:10 2009
@@ -1090,8 +1090,8 @@
 TOKEN:
 {
     <#LETTER: [ "a"-"z", "A" - "Z" ] >
-|   <#DIRECTIVE_CHAR: [ "a"-"z", "A"-"Z", "0"-"9", "_" ] >
-|   <WORD:  ( <LETTER> | ["_"]) (<DIRECTIVE_CHAR>)* >
+|   <#DIRECTIVE_CHAR: [ "a"-"z", "A"-"Z", "0"-"9", "_", "@" ] >
+|   <WORD:  ( <LETTER> | ["_"] | ["@"]) (<DIRECTIVE_CHAR>)* >
 |   <BRACKETED_WORD:  "{" ( <LETTER> | ["_"]) (<DIRECTIVE_CHAR>)* "}" >
 
 }
@@ -1456,20 +1456,27 @@
          */
 
         jjtThis.setDirectiveName(directiveName);
-
+        
         if ( d == null)
         {
-            /*
-             *  if null, then not a real directive, but maybe a Velocimacro
-             */
-
-            isVM = rsvc.isVelocimacro(directiveName, currentTemplateName);
-
-            /*
-             *  Currently, all VMs are LINE directives
-             */
-
-            directiveType = Directive.LINE;
+            if( directiveName.startsWith("@") )
+            {
+                // block macro call of type: #@foobar($arg1 $arg2) astBody #end
+                directiveType = Directive.BLOCK;
+            }
+            else
+            {
+                /*
+                 *  if null, then not a real directive, but maybe a Velocimacro
+                 */
+
+                isVM = rsvc.isVelocimacro(directiveName, currentTemplateName);
+
+                /*
+                 * Currently, all VMs are LINE directives
+                 */
+                directiveType = Directive.LINE;
+            }
         }
         else
         {



Mime
View raw message