예제 #1
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;
                    // failsafe: perhaps enclosing instance not set
                    // Or, it could be set to another context!  This occurs
                    // when you store a template instance as an attribute of more
                    // than one template (like both a header file and C file when
                    // generating C code).  It must execute within the context of
                    // the enclosing template.
                    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
                {
                    AttributeRenderer renderer = self.getAttributeRenderer(o.GetType());
                    if ( renderer!=null )
                    {
                        n = outWriter.write(renderer.ToString(o));
                    }
                    else
                    {
                        n = outWriter.write(o.ToString());
                    }
                    return n;
                }
            }
            catch (System.IO.IOException io)
            {
                self.error("problem writing object: " + o, io);
            }
            return n;
        }