Binding WalkTo(SymbolExpression expression, out string[] missingTokens) { ValidateThatRecursionIsNotOccuring(expression); symbolStack.Push(expression); try { var val = binding; missingTokens = new string[0]; expression = CopyExpression(expression); foreach (var step in expression.Steps) { var iss = step as Identifier; if (iss != null) { Binding newVal; if (val.TryGetValue(iss.Text, out newVal)) { val = newVal; continue; } if (TryCustomParsers(val, iss.Text, out newVal)) { val = newVal; continue; } } else { var ix = step as Indexer; if (ix != null) { if (ix.IsSymbol) { // Substitution should have taken place in previous CopyExpression above. // If not then it must not be found. return(null); } if (ix.Index == "*" && val.Indexable.Count > 0) { val = val.Indexable.First().Value; continue; } Binding newVal; if (val.Indexable.TryGetValue(ix.Index, out newVal)) { val = newVal; continue; } if (TryCustomParsers(val, ix.Index, out newVal)) { val = newVal; continue; } } else { throw new NotImplementedException("Unknown step type: " + step); } } if (parent == null) { return(null); } return(parent.WalkTo(expression, out missingTokens)); } return(ParseTemplate(val, out missingTokens)); } finally { symbolStack.Pop(); } }
Binding WalkTo(SymbolExpression expression, out string[] missingTokens) { ValidateNoRecursion(expression); symbolStack.Push(expression); try { var val = binding; missingTokens = new string[0]; //any indexers that are lookups, do them now so we are in the right context //take a copy so the lookup version remains for later use expression = new SymbolExpression(expression.Steps.Select(s => { var indexer = s as Indexer; if (indexer != null && indexer.IsSymbol) { string[] missing; var index = WalkTo(indexer.Symbol, out missing); return(new Indexer(index.Item)); } return(s); })); foreach (var step in expression.Steps) { var iss = step as Identifier; if (iss != null) { if (val.TryGetValue(iss.Text, out val)) { continue; } } else { var ix = step as Indexer; if (ix != null && !ix.IsSymbol) { if (ix.Index == "*" && val.Indexable.Count > 0) { val = val.Indexable.First().Value; continue; } if (val.Indexable.TryGetValue(ix.Index, out val)) { continue; } } else { throw new NotImplementedException("Unknown step type: " + step); } } if (parent == null) { return(null); } return(parent.WalkTo(expression, out missingTokens)); } if (val != null && val.Item != null) { Template template; string error; if (TemplateParser.TryParseTemplate(val.Item, out template, out error)) { using (var x = new StringWriter()) { var context = new EvaluationContext(new Binding(), x, this); TemplateEvaluator.Evaluate(template, context, out missingTokens); x.Flush(); return(new Binding(x.ToString())); } } } return(val); } finally { symbolStack.Pop(); } }