/// <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; }
public StringTemplateTreeView(System.String label, StringTemplate st) : base() { this.Text = label; JTreeStringTemplatePanel tp = new JTreeStringTemplatePanel(new JTreeStringTemplateModel(st), null); //UPGRADE_TODO: Method 'javax.swing.JFrame.getContentPane' was converted to 'System.Windows.Forms.Form' which has a different behavior. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1073_javaxswingJFramegetContentPane_3"' System.Windows.Forms.Control content = ((System.Windows.Forms.ContainerControl) this); //UPGRADE_TODO: Method 'java.awt.Container.add' was converted to 'System.Windows.Forms.ContainerControl.Controls.Add' which has a different behavior. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1073_javaawtContaineradd_javaawtComponent_javalangObject_3"' content.Controls.Add(tp); tp.Dock = System.Windows.Forms.DockStyle.Fill; tp.BringToFront(); //UPGRADE_NOTE: Some methods of the 'java.awt.event.WindowListener' class are not used in the .NET Framework. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1308_3"' Closing += new System.ComponentModel.CancelEventHandler(new AnonymousClassWindowAdapter(this).windowClosing); //UPGRADE_TODO: Method 'java.awt.Component.setSize' was converted to 'System.Windows.Forms.Control.Size' which has a different behavior. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1073_javaawtComponentsetSize_int_int_3"' Size = new System.Drawing.Size(WIDTH, HEIGHT); }
/// <summary>Make the 'to' template look exactly like the 'from' template /// except for the attributes. This is like creating an instance /// of a class in that the executable code is the same (the template /// chunks), but the instance data is blank (the attributes). Do /// not copy the enclosingInstance pointer since you will want this /// template to eval in a context different from the examplar. /// </summary> protected internal virtual void dup(StringTemplate from, StringTemplate to) { if (debugMode) debug("dup template ID " + from.getTemplateID() + " to get " + to.getTemplateID()); to.pattern = from.pattern; to.chunks = from.chunks; to.formalArguments = from.formalArguments; to.name = from.name; to.group = from.group; to.listener = from.listener; }
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; }
/// <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(); } }
/// <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; }
/// <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; }
//throws RecognitionException public void singleTemplateArg(AST _t, StringTemplate embedded, IDictionary argumentContext ) { antlr.stringtemplate.language.StringTemplateAST singleTemplateArg_AST_in = (antlr.stringtemplate.language.StringTemplateAST)_t; Object e = null; try { // for error handling AST __t41 = _t; antlr.stringtemplate.language.StringTemplateAST tmp22_AST_in = (_t==ASTNULL) ? null : (antlr.stringtemplate.language.StringTemplateAST)_t; match((AST)_t,SINGLEVALUEARG); _t = _t.getFirstChild(); e=expr(_t); _t = retTree_; _t = __t41; _t = _t.getNextSibling(); if ( e!=null ) { String soleArgName = null; // find the sole defined formal argument for embedded bool error = false; IDictionary formalArgs = embedded.getFormalArguments(); if ( formalArgs!=null ) { ICollection argNames = formalArgs.Keys; if ( argNames.Count==1 ) { string[] argNamesArray = new string[argNames.Count]; argNames.CopyTo(argNamesArray,0); soleArgName = argNamesArray[0]; //System.out.println("sole formal arg of "+embedded.getName()+" is "+soleArgName); } else { error=true; } } else { error=true; } if ( error ) { self.error("template "+embedded.getName()+ " must have exactly one formal arg in template context "+ self.getEnclosingInstanceStackString()); } else { self.rawSetArgumentAttribute(embedded,argumentContext,soleArgName,e); } } } catch (RecognitionException ex) { reportError(ex); if (null != _t) { _t = _t.getNextSibling(); } } retTree_ = _t; }
//throws RecognitionException public void argumentAssignment(AST _t, StringTemplate embedded, IDictionary argumentContext ) { antlr.stringtemplate.language.StringTemplateAST argumentAssignment_AST_in = (antlr.stringtemplate.language.StringTemplateAST)_t; antlr.stringtemplate.language.StringTemplateAST arg = null; Object e = null; try { // for error handling if (null == _t) _t = ASTNULL; switch ( _t.Type ) { case ASSIGN: { AST __t43 = _t; antlr.stringtemplate.language.StringTemplateAST tmp20_AST_in = (_t==ASTNULL) ? null : (antlr.stringtemplate.language.StringTemplateAST)_t; match((AST)_t,ASSIGN); _t = _t.getFirstChild(); arg = (_t==ASTNULL) ? null : (antlr.stringtemplate.language.StringTemplateAST)_t; match((AST)_t,ID); _t = _t.getNextSibling(); e=expr(_t); _t = retTree_; _t = __t43; _t = _t.getNextSibling(); if ( e!=null ) { self.rawSetArgumentAttribute(embedded,argumentContext,arg.getText(),e); } break; } case DOTDOTDOT: { antlr.stringtemplate.language.StringTemplateAST tmp21_AST_in = (_t==ASTNULL) ? null : (antlr.stringtemplate.language.StringTemplateAST)_t; match((AST)_t,DOTDOTDOT); _t = _t.getNextSibling(); embedded.setPassThroughAttributes(true); break; } default: { throw new NoViableAltException(_t); } } } catch (RecognitionException ex) { reportError(ex); if (null != _t) { _t = _t.getNextSibling(); } } retTree_ = _t; }
public static void Main(System.String[] args) { StringTemplateGroup group = new StringTemplateGroup("dummy"); StringTemplate bold = group.defineTemplate("bold", "<b>$attr$</b>"); StringTemplate banner = group.defineTemplate("banner", "the banner"); StringTemplate st = new StringTemplate(group, "<html>\n" + "$banner(a=b)$" + "<p><b>$name$:$email$</b>" + "$if(member)$<i>$fontTag$member</font></i>$endif$"); st.setAttribute("name", "Terence"); st.setAttribute("name", "Tom"); st.setAttribute("email", "*****@*****.**"); st.setAttribute("templateAttr", bold); StringTemplateTreeView frame = new StringTemplateTreeView("StringTemplate JTree Example", st); //UPGRADE_TODO: Method 'java.awt.Component.setVisible' was converted to 'System.Windows.Forms.Control.Visible' which has a different behavior. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1073_javaawtComponentsetVisible_boolean_3"' //UPGRADE_TODO: 'System.Windows.Forms.Application.Run' must be called to start a main form. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1135_3"' frame.Visible = true; }
public NewlineRef(StringTemplate enclosingTemplate, String str) : base(enclosingTemplate, str) { }
public virtual void setEnclosingInstance(StringTemplate enclosingInstance) { if (this == enclosingInstance) { throw new System.ArgumentException("cannot embed template " + getName() + " in itself"); } // set the parent for this template this.enclosingInstance = enclosingInstance; // make the parent track this template as an embedded template this.enclosingInstance.addEmbeddedInstance(this); }
/// <summary>Resolve an attribute reference. It can be in three possible places: /// /// 1. the attribute list for the current template /// 2. if self is an embedded template, somebody invoked us possibly /// with arguments--check the argument context /// 3. if self is an embedded template, the attribute list for the enclosing /// instance (recursively up the enclosing instance chain) /// /// Attribute references are checked for validity. If an attribute has /// a value, its validity was checked before template rendering. /// If the attribute has no value, then we must check to ensure it is a /// valid reference. Somebody could reference any random value like $xyz$; /// formal arg checks before rendering cannot detect this--only the ref /// can initiate a validity check. So, if no value, walk up the enclosed /// template tree again, this time checking formal parameters not /// attributes Map. The formal definition must exist even if no value. /// /// To avoid infinite recursion in toString(), we have another condition /// to check regarding attribute values. If your template has a formal /// argument, foo, then foo will hide any value available from "above" /// in order to prevent infinite recursion. /// /// This method is not static so people can overrided functionality. /// </summary> public virtual Object get(StringTemplate self, String attribute) { //System.out.println("get("+self.getName()+", "+attribute+")"); if (self == null) { return null; } if (lintMode) { self.trackAttributeReference(attribute); } // is it here? Object o = null; if (self.attributes != null) { o = self.attributes[attribute]; } // nope, check argument context in case embedded if (o == null) { IDictionary argContext = self.getArgumentContext(); if (argContext != null) { o = argContext[attribute]; } } if (o == null && self.getFormalArgument(attribute) != null) { // if you've defined attribute as formal arg for this // template and it has no value, do not look up the // enclosing dynamic scopes. This avoids potential infinite // recursion. return null; } // not locally defined, check enclosingInstance if embedded if (o == null && self.enclosingInstance != null) { /* System.out.println("looking for "+getName()+"."+attribute+" in super="+ enclosingInstance.getName()); */ Object valueFromEnclosing = get(self.enclosingInstance, attribute); if (valueFromEnclosing == null) { checkNullAttributeAgainstFormalArguments(self, attribute); } o = valueFromEnclosing; } return o; }
public virtual void addEmbeddedInstance(StringTemplate embeddedInstance) { if (this.embeddedInstances == null) { this.embeddedInstances = new ArrayList(); } this.embeddedInstances.Add(embeddedInstance); }
/// <summary>Look up the enclosing instance chain (and include this) to see /// if st is a template already in the enclosing instance chain. /// </summary> public static bool isRecursiveEnclosingInstance(StringTemplate st) { if (st == null) { return false; } StringTemplate p = st.enclosingInstance; if (p == st) { return true; // self-recursive } // now look for indirect recursion while (p != null) { if (p == st) { return true; } p = p.enclosingInstance; } return false; }
/** Create an evaluator using attributes from self */ public ActionEvaluator(StringTemplate self, ASTExpr chunk, StringTemplateWriter @out) { this.self = self; this.chunk = chunk; this.@out = @out; }
//throws RecognitionException /** self is assumed to be the enclosing context as foo(x=y) must find y in * the template that encloses the ref to foo(x=y). We must pass in * the embedded template (the one invoked) so we can check formal args * in rawSetArgumentAttribute. */ public IDictionary argList(AST _t, StringTemplate embedded, IDictionary initialContext ) { IDictionary argumentContext=null; antlr.stringtemplate.language.StringTemplateAST argList_AST_in = (antlr.stringtemplate.language.StringTemplateAST)_t; argumentContext = initialContext; if ( argumentContext==null ) { argumentContext=new Hashtable(); } try { // for error handling if (null == _t) _t = ASTNULL; switch ( _t.Type ) { case ARGS: { AST __t37 = _t; antlr.stringtemplate.language.StringTemplateAST tmp19_AST_in = (_t==ASTNULL) ? null : (antlr.stringtemplate.language.StringTemplateAST)_t; match((AST)_t,ARGS); _t = _t.getFirstChild(); { // ( ... )* for (;;) { if (_t == null) _t = ASTNULL; if ((_t.Type==ASSIGN||_t.Type==DOTDOTDOT)) { argumentAssignment(_t,embedded,argumentContext); _t = retTree_; } else { goto _loop39_breakloop; } } _loop39_breakloop: ; } // ( ... )* _t = __t37; _t = _t.getNextSibling(); break; } case SINGLEVALUEARG: { singleTemplateArg(_t,embedded,argumentContext); _t = retTree_; break; } default: { throw new NoViableAltException(_t); } } } catch (RecognitionException ex) { reportError(ex); if (null != _t) { _t = _t.getNextSibling(); } } retTree_ = _t; return argumentContext; }
// 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; }
//throws RecognitionException public Object attribute(AST _t) { Object value=null; antlr.stringtemplate.language.StringTemplateAST attribute_AST_in = (antlr.stringtemplate.language.StringTemplateAST)_t; antlr.stringtemplate.language.StringTemplateAST prop = null; antlr.stringtemplate.language.StringTemplateAST i3 = null; antlr.stringtemplate.language.StringTemplateAST i = null; antlr.stringtemplate.language.StringTemplateAST s = null; antlr.stringtemplate.language.StringTemplateAST at = null; Object obj = null; String propName = null; Object e = null; try { // for error handling if (null == _t) _t = ASTNULL; switch ( _t.Type ) { case DOT: { AST __t33 = _t; antlr.stringtemplate.language.StringTemplateAST tmp6_AST_in = (_t==ASTNULL) ? null : (antlr.stringtemplate.language.StringTemplateAST)_t; match((AST)_t,DOT); _t = _t.getFirstChild(); obj=expr(_t); _t = retTree_; { if (null == _t) _t = ASTNULL; switch ( _t.Type ) { case ID: { prop = (_t==ASTNULL) ? null : (antlr.stringtemplate.language.StringTemplateAST)_t; match((AST)_t,ID); _t = _t.getNextSibling(); propName = prop.getText(); break; } case VALUE: { AST __t35 = _t; antlr.stringtemplate.language.StringTemplateAST tmp7_AST_in = (_t==ASTNULL) ? null : (antlr.stringtemplate.language.StringTemplateAST)_t; match((AST)_t,VALUE); _t = _t.getFirstChild(); e=expr(_t); _t = retTree_; _t = __t35; _t = _t.getNextSibling(); if (e!=null) {propName=e.ToString();} break; } default: { throw new NoViableAltException(_t); } } } _t = __t33; _t = _t.getNextSibling(); value = chunk.getObjectProperty(self,obj,propName); break; } case ID: { i3 = (_t==ASTNULL) ? null : (antlr.stringtemplate.language.StringTemplateAST)_t; match((AST)_t,ID); _t = _t.getNextSibling(); value=self.getAttribute(i3.getText()); break; } case INT: { i = (_t==ASTNULL) ? null : (antlr.stringtemplate.language.StringTemplateAST)_t; match((AST)_t,INT); _t = _t.getNextSibling(); value=Int32.Parse(i.getText()); break; } case STRING: { s = (_t==ASTNULL) ? null : (antlr.stringtemplate.language.StringTemplateAST)_t; match((AST)_t,STRING); _t = _t.getNextSibling(); value=s.getText(); break; } case ANONYMOUS_TEMPLATE: { at = (_t==ASTNULL) ? null : (antlr.stringtemplate.language.StringTemplateAST)_t; match((AST)_t,ANONYMOUS_TEMPLATE); _t = _t.getNextSibling(); value=at.getText(); if ( at.getText()!=null ) { StringTemplate valueST =new StringTemplate(self.getGroup(), at.getText()); valueST.setEnclosingInstance(self); valueST.setName("<anonymous template argument>"); value = valueST; } break; } default: { throw new NoViableAltException(_t); } } } catch (RecognitionException ex) { reportError(ex); if (null != _t) { _t = _t.getNextSibling(); } } retTree_ = _t; return value; }
/// <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); } }
// HELP ROUTINES CALLED BY EVALUATOR TREE WALKER public virtual Object applyListOfAlternatingTemplates(StringTemplate self, Object attributeValue, IList templatesToApply) { if (attributeValue == null || templatesToApply == null || templatesToApply.Count == 0) { return null; // do not apply if missing templates or empty value } StringTemplate embedded = null; IDictionary argumentContext = null; // normalize collections and such to use iterators // anything iteratable can be used for "APPLY" attributeValue = convertAnythingIteratableToIterator(attributeValue); if (attributeValue is IEnumerator) { IList resultVector = new ArrayList(); IEnumerator iter = (IEnumerator) attributeValue; int i = 0; while (iter.MoveNext()) { Object ithValue = iter.Current; if (ithValue == null) { // weird...a null value in the list; ignore continue; } // rotate through int templateIndex = i % templatesToApply.Count; embedded = (StringTemplate) templatesToApply[templateIndex]; // template to apply is an actual StringTemplate (created in // eval.g), but that is used as the examplar. We must create // a new instance of the embedded template to apply each time // to get new attribute sets etc... StringTemplateAST args = embedded.getArgumentsAST(); embedded = embedded.getInstanceOf(); // make new instance embedded.setEnclosingInstance(self); embedded.setArgumentsAST(args); argumentContext = new Hashtable(); argumentContext[DEFAULT_ATTRIBUTE_NAME] = ithValue; argumentContext[DEFAULT_ATTRIBUTE_NAME_DEPRECATED] = ithValue; argumentContext[DEFAULT_INDEX_VARIABLE_NAME] = i + 1; embedded.setArgumentContext(argumentContext); evaluateArguments(embedded); /* System.err.println("i="+i+": applyTemplate("+embedded.getName()+ ", args="+argumentContext+ " to attribute value "+ithValue); */ resultVector.Add(embedded); i++; } return resultVector; } else { /* Console.WriteLine("setting attribute "+DefaultAttributeName+" in arg context of "+ embedded.getName()+ " to "+attributeValue); */ embedded = (StringTemplate) templatesToApply[0]; argumentContext = new Hashtable(); argumentContext[DEFAULT_ATTRIBUTE_NAME] = attributeValue; argumentContext[DEFAULT_ATTRIBUTE_NAME_DEPRECATED] = attributeValue; argumentContext[DEFAULT_INDEX_VARIABLE_NAME] = 1; embedded.setArgumentContext(argumentContext); evaluateArguments(embedded); return embedded; } }
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; } } }
/// <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; }
public virtual StringTemplate getEmbeddedInstanceOf(StringTemplate enclosingInstance, String name) { StringTemplate st = getInstanceOf(name); st.setEnclosingInstance(enclosingInstance); return st; }
/// <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); }
public override String ToString() { System.Text.StringBuilder buf = new System.Text.StringBuilder(); IEnumerator iter = templates.Keys.GetEnumerator(); buf.Append("group " + getName() + ";\n"); StringTemplate formalArgs = new StringTemplate("$args;separator=\",\"$"); while (iter.MoveNext()) { String tname = (String) iter.Current; StringTemplate st = (StringTemplate) templates[tname]; if (st != NOT_FOUND_ST) { formalArgs = formalArgs.getInstanceOf(); formalArgs.setAttribute("args", st.getFormArguments()); buf.Append(tname + "(" + formalArgs + ") ::= "); buf.Append("<<"); buf.Append(st.getTemplate()); buf.Append(">>\n"); } } return buf.ToString(); }
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); } }
public StringRef(StringTemplate enclosingTemplate, String str) : base(enclosingTemplate) { this.str = str; }
public ASTExpr(StringTemplate enclosingTemplate, AST exprTree, IDictionary options) : base(enclosingTemplate) { this.exprTree = exprTree; this.options = options; }
/// <summary>Find "missing attribute" and "cardinality mismatch" errors. /// Excecuted before a template writes its chunks out. /// When you find a problem, throw an IllegalArgumentException. /// We must check the attributes as well as the incoming arguments /// in argumentContext. /// protected void checkAttributesAgainstFormalArguments() { /// Set args = formalArguments.keySet(); /// /* /// if ( (attributes==null||attributes.size()==0) && /// (argumentContext==null||argumentContext.size()==0) && /// formalArguments.size()!=0 ) /// { /// throw new IllegalArgumentException("missing argument(s): "+args+" in template "+getName()); /// } /// Iterator iter = args.iterator(); /// while ( iter.hasNext() ) { /// String argName = (String)iter.next(); /// FormalArgument arg = getFormalArgument(argName); /// int expectedCardinality = arg.getCardinality(); /// Object value = getAttribute(argName); /// int actualCardinality = getActualArgumentCardinality(value); /// // if intersection of expected and actual is empty, mismatch /// if ( (expectedCardinality&actualCardinality)==0 ) { /// throw new IllegalArgumentException("cardinality mismatch: "+ /// argName+"; expected "+ /// FormalArgument.getCardinalityName(expectedCardinality)+ /// " found cardinality="+getObjectLength(value)); /// } /// } /// } /// </summary> /// <summary>A reference to an attribute with no value, must be compared against /// the formal parameter to see if it exists; if it exists all is well, /// but if not, throw an exception. /// /// Don't do the check if no formal parameters exist for this template; /// ask enclosing. /// </summary> protected internal virtual void checkNullAttributeAgainstFormalArguments(StringTemplate self, String attribute) { if (self.getFormArguments() == FormalArgument.UNKNOWN) { // bypass unknown arg lists if (self.enclosingInstance != null) { checkNullAttributeAgainstFormalArguments(self.enclosingInstance, attribute); } return ; } FormalArgument formalArg = lookupFormalArgument(attribute); if (formalArg == null) { throw new ArgumentOutOfRangeException("attribute", "no such attribute: " + attribute); } }