Пример #1
0
 /// <summary>Just print out the string; no reference to self because this
 /// is a literal--not sensitive to attribute values.
 /// </summary>
 public override int write(StringTemplate self, StringTemplateWriter outWriter)
 {
     if (str != null)
     {
         int n = outWriter.write(str);
         return n;
     }
     return 0;
 }
Пример #2
0
        protected internal virtual int write(StringTemplate self, Object o, StringTemplateWriter outWriter, Object separator)
        {
            if (o == null)
            {
                return 0;
            }
            int n = 0;
            try
            {
                if (o is StringTemplate)
                {
                    StringTemplate stToWrite = (StringTemplate) o;
                    stToWrite.setEnclosingInstance(self);
                    // if self is found up the enclosing instance chain, then
                    // infinite recursion
                    if (StringTemplate.inLintMode() && StringTemplate.isRecursiveEnclosingInstance(stToWrite))
                    {
                        // throw exception since sometimes eval keeps going
                        // even after I ignore this write of o.
                        throw new System.SystemException("infinite recursion to " + stToWrite.getTemplateDeclaratorString() + " referenced in " + stToWrite.getEnclosingInstance().getTemplateDeclaratorString() + "; stack trace:\n" + stToWrite.getEnclosingInstanceStackTrace());
                    }
                    else
                    {
                        n = stToWrite.write(outWriter);
                    }
                    return n;
                }
                // normalize anything iteratable to iterator
                o = convertAnythingIteratableToIterator(o);
                if (o is IEnumerator)
                {
                    IEnumerator iter = (IEnumerator) o;
                    String separatorString = null;
                    if (separator != null)
                    {
                        separatorString = computeSeparator(self, outWriter, separator);
                    }

                    int i = 0;
                    int charWrittenForValue = 0;
                    Object iterValue = null;

                    while (iter.MoveNext())
                    {
                        if (i > 0)
                        {
                            bool valueIsPureConditional = false;
                            if (iterValue is StringTemplate)
                            {
                                StringTemplate iterValueST = (StringTemplate) iterValue;
                                IList chunks = (IList) iterValueST.getChunks();
                                Expr firstChunk = (Expr) chunks[0];
                                valueIsPureConditional = firstChunk is ConditionalExpr && ((ConditionalExpr) firstChunk).getElseSubtemplate() == null;
                            }
                            bool emptyIteratedValue = valueIsPureConditional && charWrittenForValue == 0;
                            if (!emptyIteratedValue && separator != null)
                            {
                                n += outWriter.write(separatorString);
                            }
                        }

                        iterValue = iter.Current;
                        charWrittenForValue = write(self, iterValue, outWriter, separator);
                        n += charWrittenForValue;
                        i++;
                    }
                }
                else
                {
                    n = outWriter.write(o.ToString());
                    return n;
                }
            }
            catch (System.IO.IOException io)
            {
                self.error("problem writing object: " + o, io);
            }
            return n;
        }
Пример #3
0
        /// <summary>A separator is normally just a string literal, but is still an AST that
        /// we must evaluate.  The separator can be any expression such as a template
        /// include or string cat expression etc...
        /// </summary>
        protected internal virtual String computeSeparator(StringTemplate self, StringTemplateWriter outWriter, Object separator)
        {
            if (separator == null)
            {
                return null;
            }
            if (separator is StringTemplateAST)
            {
                StringTemplateAST separatorTree = (StringTemplateAST) separator;
                // must evaluate, writing to a string so we can hand on to it
                ASTExpr e = new ASTExpr(getEnclosingTemplate(), separatorTree, null);
                System.IO.StringWriter buf = new System.IO.StringWriter();
                // create a new instance of whatever StringTemplateWriter
                // implementation they are using.  Default is AutoIndentWriter.
                // Defalut behavior is to indent but without
                // any prior indents surrounding this attribute expression
                StringTemplateWriter sw = null;
                System.Type writerClass = outWriter.GetType();
                try
                {
                    System.Reflection.ConstructorInfo ctor = writerClass.GetConstructor(new System.Type[]{typeof(System.IO.TextWriter)});
                    sw = (StringTemplateWriter) ctor.Invoke(new Object[]{buf});
                }
                catch (System.Exception exc)
                {
                    // default new AutoIndentWriter(buf)
                    self.error("cannot make implementation of StringTemplateWriter", exc);
                    sw = new AutoIndentWriter(buf);
                }

                try
                {
                    e.write(self, sw);
                }
                catch (System.IO.IOException ioe)
                {
                    self.error("can't evaluate separator expression", ioe);
                }
                return buf.ToString();
            }
            else
            {
                // just in case we expand in the future and it's something else
                return separator.ToString();
            }
        }
Пример #4
0
 /// <summary>How to spit out an object.  If it's not a StringTemplate nor a
 /// List, just do o.toString().  If it's a StringTemplate,
 /// do o.write(out).  If it's a Vector, do a write(out,
 /// o.elementAt(i)) for all elements.  Note that if you do
 /// something weird like set the values of a multivalued tag
 /// to be vectors, it will effectively flatten it.
 /// 
 /// If self is an embedded template, you might have specified
 /// a separator arg; used when is a vector.
 /// </summary>
 public virtual int writeAttribute(StringTemplate self, Object o, StringTemplateWriter outWriter)
 {
     Object separator = null;
     if (options != null)
     {
         separator = options["separator"];
     }
     return write(self, o, outWriter, separator);
 }
Пример #5
0
 /// <summary>To write out the value of an ASTExpr, invoke the evaluator in eval.g
 /// to walk the tree writing out the values.  For efficiency, don't
 /// compute a bunch of strings and then pack them together.  Write out directly.
 /// </summary>
 public override int write(StringTemplate self, StringTemplateWriter outWriter)
 {
     if (exprTree == null || self == null || outWriter == null)
     {
         return 0;
     }
     outWriter.pushIndentation(getIndentation());
     //System.out.println("evaluating tree: "+exprTree.toStringList());
     ActionEvaluator eval = new ActionEvaluator(self, this, outWriter);
     int n = 0;
     try
     {
         n = eval.action(exprTree); // eval and write out tree
     }
     catch (RecognitionException re)
     {
         self.error("can't evaluate tree: " + exprTree.ToStringList(), re);
     }
     outWriter.popIndentation();
     return n;
 }
 /** Create an evaluator using attributes from self */
 public ActionEvaluator(StringTemplate self, ASTExpr chunk, StringTemplateWriter @out)
 {
     this.self = self;
     this.chunk = chunk;
     this.@out = @out;
 }
Пример #7
0
 /// <summary>Walk the chunks, asking them to write themselves out according
 /// to attribute values of 'this.attributes'.  This is like evaluating or
 /// interpreting the StringTemplate as a program using the
 /// attributes.  The chunks will be identical (point at same list)
 /// for all instances of this template.
 /// </summary>
 public virtual int write(StringTemplateWriter outWriter)
 {
     int n = 0;
     setPredefinedAttributes();
     for (int i = 0; chunks != null && i < chunks.Count; i++)
     {
         Expr a = (Expr) chunks[i];
         int chunkN = a.write(this, outWriter);
         // NEWLINE expr-with-no-output NEWLINE => NEWLINE
         // Indented $...$ have the indent stored with the ASTExpr
         // so the indent does not come out as a StringRef
         if (chunkN == 0 && (i - 1) >= 0 && chunks[i - 1] is NewlineRef && (i + 1) < chunks.Count && chunks[i + 1] is NewlineRef)
         {
             //System.out.println("found pure \\n blank \\n pattern");
             i++; // make it skip over the next chunk, the NEWLINE
         }
         n += chunkN;
     }
     if (lintMode)
     {
         checkForTrouble();
     }
     return n;
 }