Esempio n. 1
0
 protected internal virtual void evaluateArguments(StringTemplate self)
 {
     StringTemplateAST argumentsAST = self.getArgumentsAST();
     if (argumentsAST == null || argumentsAST.getFirstChild() == null)
     {
         // return immediately if missing tree or no actual args
         return ;
     }
     ActionEvaluator eval = new ActionEvaluator(self, this, null);
     try
     {
         // using any initial argument context (such as when obj is set),
         // evaluate the arg list like bold(item=obj).  Since we pass
         // in any existing arg context, that context gets filled with
         // new values.  With bold(item=obj), context becomes:
         // {[obj=...],[item=...]}.
         IDictionary ac = eval.argList(argumentsAST, self.getArgumentContext());
         self.setArgumentContext(ac);
     }
     catch (RecognitionException re)
     {
         self.error("can't evaluate tree: " + argumentsAST.ToStringList(), re);
     }
 }
Esempio n. 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;
        }
Esempio n. 3
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;
 }
Esempio n. 4
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();
            }
        }
Esempio n. 5
0
 /// <summary>Call a string template with args and return result.  Do not convert
 /// to a string yet.  It may need attributes that will be available after
 /// this is inserted into another template.
 /// </summary>
 public virtual StringTemplate getTemplateInclude(StringTemplate enclosing, String templateName, StringTemplateAST argumentsAST)
 {
     StringTemplateGroup group = enclosing.getGroup();
     StringTemplate embedded = group.getEmbeddedInstanceOf(enclosing, templateName);
     if (embedded == null)
     {
         enclosing.error("cannot make embedded instance of " + templateName + " in template " + enclosing.getName());
         return null;
     }
     embedded.setArgumentsAST(argumentsAST);
     evaluateArguments(embedded);
     return embedded;
 }
Esempio n. 6
0
        /// <summary>Return o.getPropertyName() given o and propertyName.  If o is
        /// a stringtemplate then access it's attributes looking for propertyName
        /// instead (don't check any of the enclosing scopes; look directly into
        /// that object).  Also try isXXX() for booleans.  Allow HashMap,
        /// Hashtable as special case (grab value for key).
        /// </summary>
        /// <summary>
        /// Return o.getPropertyName() given o and propertyName.  If o is
        /// a stringtemplate then access it's attributes looking for propertyName
        /// instead (don't check any of the enclosing scopes; look directly into
        /// that object).  Also try isXXX() for booleans.  Allow HashMap,
        /// Hashtable as special case (grab value for key).
        /// </summary>
        public virtual Object getObjectProperty(StringTemplate self, object o, string propertyName)
        {
            if (o == null || propertyName == null) {
                return null;
            }

            Type c = o.GetType();
            Object value = null;

            // Special case: our automatically created Aggregates via
            // attribute name: "{obj.{prop1,prop2}}"
            if (c == typeof(StringTemplate.Aggregate)) {
                value = ((StringTemplate.Aggregate) o).get(propertyName);
            }
                // Special case: if it's a template, pull property from
                // it's attribute table.
                // TODO: TJP just asked himself why we can't do inherited attr here?
            else if (c == typeof(StringTemplate)) {
                IDictionary attributes = ((StringTemplate) o).getAttributes();
                if ( attributes!=null ) {
                    value = attributes[propertyName];
                }
            }
                // Special case: if it's a HashMap, Hashtable then pull using
                // key not the property method.  Do NOT allow general Map interface
                // as people could pass in their database masquerading as a Map.
            else if ( isValidMapInstance(c) ) {
                IDictionary map = (IDictionary)o;
                value = map[propertyName];
            }

            else {
                // lookup as property or accessor-method
                string lookupName = Char.ToUpper(propertyName[0])+
                    propertyName.Substring(1);

                //see if it's a property
                PropertyInfo pi = c.GetProperty(lookupName,
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase,
                    null, null, new Type[0], null);

                if (pi != null) {
                    value = pi.GetValue(o, null);
                }
                else {
                    //see if it's a method
                    String methodName = "Get" + lookupName;
                    MethodInfo mi = c.GetMethod(methodName,
                        BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase,
                        null, new Type[0], null);

                    if (mi == null) {
                        mi = c.GetMethod("Is" + lookupName,
                            BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase,
                            null, new Type[0], null);
                    }

                    if (mi == null) {
                        self.error("Can't get property " +propertyName+ " as C# property '" +lookupName+
                            "' or as C# methods 'Get" +lookupName+ "' or 'Is" +lookupName+
                            "' from " +c.FullName+ " instance");
                    }
                    else {
                        value = mi.Invoke(o, null);
                    }
                }
            }

            return value;
        }
Esempio n. 7
0
 protected void setSoleFormalArgumentToIthValue(StringTemplate embedded, IDictionary argumentContext, Object ithValue)
 {
     IDictionary formalArgs = embedded.getFormalArguments();
     if ( formalArgs!=null )
     {
         String soleArgName = null;
         bool isAnonymous = embedded.getName().Equals(StringTemplate.ANONYMOUS_ST_NAME);
         if ( formalArgs.Count==1 || (isAnonymous&&formalArgs.Count>0) )
         {
             if ( isAnonymous && formalArgs.Count>1 )
             {
                 embedded.error("too many arguments on {...} template: "+formalArgs);
             }
             // if exactly 1 arg or anonymous, give that the value of
             // "it" as a convenience like they said
             // $list:template(arg=it)$
             ICollection argNames = formalArgs.Keys;
             string[] argNamesArray = new string[argNames.Count];
             argNames.CopyTo(argNamesArray,0);
             soleArgName = argNamesArray[0];
             argumentContext[soleArgName] = ithValue;
         }
     }
 }
Esempio n. 8
0
        /// <summary>
        /// Evaluate an argument list within the context of the enclosing
        /// template but store the values in the context of self, the
        /// new embedded template.  For example, bold(item=item) means
        /// that bold.item should get the value of enclosing.item.
        ///	</summary>
        protected internal virtual void evaluateArguments(StringTemplate self)
        {
            StringTemplateAST argumentsAST = self.getArgumentsAST();
            if (argumentsAST == null || argumentsAST.getFirstChild() == null)
            {
                // return immediately if missing tree or no actual args
                return ;
            }
            // Evaluate args in the context of the enclosing template, but we
            // need the predefined args like 'it', 'attr', and 'i' to be
            // available as well so we put a dummy ST between the enclosing
            // context and the embedded context.  The dummy has the predefined
            // context as does the embedded.
            StringTemplate enclosing = self.getEnclosingInstance();
            StringTemplate argContextST = new StringTemplate(self.getGroup(), "");
            argContextST.setName("<invoke "+self.getName()+" arg context>");
            argContextST.setEnclosingInstance(enclosing);
            argContextST.setArgumentContext(self.getArgumentContext());

            ActionEvaluator eval = new ActionEvaluator(argContextST, this, null);
            try
            {
                // using any initial argument context (such as when obj is set),
                // evaluate the arg list like bold(item=obj).  Since we pass
                // in any existing arg context, that context gets filled with
                // new values.  With bold(item=obj), context becomes:
                // {[obj=...],[item=...]}.
                IDictionary ac = eval.argList(argumentsAST, self, self.getArgumentContext());
                self.setArgumentContext(ac);
            }
            catch (RecognitionException re)
            {
                self.error("can't evaluate tree: " + argumentsAST.ToStringList(), re);
            }
        }
Esempio n. 9
0
        // HELP ROUTINES CALLED BY EVALUATOR TREE WALKER
        /// <summary>
        /// For names,phones:{n,p | ...} treat the names, phones as lists
        /// to be walked in lock step as n=names[i], p=phones[i].
        /// </summary>
        public virtual Object applyTemplateToListOfAttributes(StringTemplate self, IList attributes, StringTemplate templateToApply)
        {
            if ( attributes==null || templateToApply==null || attributes.Count==0 )
            {
                return null; // do not apply if missing templates or empty values
            }
            IDictionary argumentContext = null;
            IList results = new ArrayList();

            // convert all attributes to iterators even if just one value
            for (int a = 0; a < attributes.Count; a++)
            {
                Object o = attributes[a];
                o = convertAnythingToIterator(o);
                attributes[a] = o;
            }

            int numAttributes = attributes.Count;

            // ensure arguments line up
            IDictionary formalArguments = templateToApply.getFormalArguments();
            if ( formalArguments==null || formalArguments.Count==0 )
            {
                self.error("missing arguments in anonymous"+
                    " template in context "+self.getEnclosingInstanceStackString());
                return null;
            }
            ICollection keys = formalArguments.Keys;
            Object[] formalArgumentNames = new object[keys.Count];
            keys.CopyTo(formalArgumentNames,0);
            if ( formalArgumentNames.Length!=numAttributes )
            {
                self.error("number of arguments "+SupportClass.CollectionToString(formalArguments.Keys)+
                    " mismatch between attribute list and anonymous"+
                    " template in context "+self.getEnclosingInstanceStackString());
                // truncate arg list to match smaller size
                int shorterSize = Math.Min(formalArgumentNames.Length, numAttributes);
                numAttributes = shorterSize;
                Object[] newFormalArgumentNames = new Object[shorterSize];
                System.Array.Copy(formalArgumentNames, 0,
                    newFormalArgumentNames, 0,
                    shorterSize);
                formalArgumentNames = newFormalArgumentNames;
            }

            // keep walking while at least one attribute has values
            while ( true )
            {
                argumentContext = new Hashtable();
                // get a value for each attribute in list; put into arg context
                // to simulate template invocation of anonymous template
                int numEmpty = 0;
                for (int a = 0; a < numAttributes; a++)
                {
                    IEnumerator it = (IEnumerator)attributes[a];
                    if ( it.MoveNext() )
                    {
                        String argName = (String)formalArgumentNames[a];
                        Object iteratedValue = it.Current;
                        argumentContext[argName] = iteratedValue;
                    }
                    else
                    {
                        numEmpty++;
                    }
                }
                if ( numEmpty==numAttributes )
                {
                    break;
                }
                StringTemplate embedded = templateToApply.getInstanceOf();
                embedded.setEnclosingInstance(self);
                embedded.setArgumentContext(argumentContext);
                results.Add(embedded);
            }

            return results;
        }