public IEnumerable <Binding> ResolveAll(SymbolExpression collection, out string[] missingTokens) { var val = WalkTo(collection, out missingTokens); if (val == null) { return(Enumerable.Empty <Binding>()); } if (val.Indexable.Count != 0) { return(val.Indexable.Select(c => c.Value)); } if (val.Item == null) { return(Enumerable.Empty <Binding>()); } Binding[] bindings; if (JsonParser.TryParse(new Binding(val.Item), out bindings)) { return(bindings); } return(val.Item.Split(',').Select(s => new Binding(s))); }
public string Resolve(SymbolExpression expression, out string[] missingTokens) { var val = WalkTo(expression, out missingTokens); if (val == null) { return(""); } return(val.Item ?? ""); }
internal static bool TryParseIdentifierPath(string path, out SymbolExpression expression) { var result = Symbol.TryParse(path); if (result.WasSuccessful) { expression = result.Value; return(true); } expression = null; return(false); }
private void ValidateThatRecursionIsNotOccuring(SymbolExpression expression) { var ancestor = this; while (ancestor != null) { if (ancestor.symbolStack.Contains(expression, SymbolExpression.StepsComparer)) { throw new RecursiveDefinitionException(expression, ancestor.symbolStack); } ancestor = ancestor.parent; } }
private void ValidateNoRecursion(SymbolExpression expression) { var ancestor = this; while (ancestor != null) { if (ancestor.symbolStack.Contains(expression)) { throw new InvalidOperationException(string.Format("An attempt to parse the variable symbol \"{0}\" appears to have resulted in a self referencing loop. Ensure that recursive loops do not exist in the variable values.", expression)); } ancestor = ancestor.parent; } }
private void ValidateThatRecursionIsNotOccuring(SymbolExpression expression) { var ancestor = this; while (ancestor != null) { if (ancestor.symbolStack.Contains(expression, SymbolExpression.StepsComparer)) { throw new InvalidOperationException(string.Format("An attempt to parse the variable symbol \"{0}\" appears to have resulted in a self referencing loop ({1}). Ensure that recursive loops do not exist in the variable values.", expression, string.Join(" -> ", ancestor.symbolStack.Select(x => x.ToString())))); } ancestor = ancestor.parent; } }
private SymbolExpression CopyExpression(SymbolExpression expression) { //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 return(new SymbolExpression(expression.Steps.Select(s => { if (s is Indexer indexer && indexer.IsSymbol) { var index = WalkTo(indexer.Symbol !, out string[] _); return index == null ? new Indexer(CopyExpression(indexer.Symbol !)) : new Indexer(index.Item); } return s; }))); }
public ConditionalSymbolExpressionToken(SymbolExpression leftSide, bool eq, SymbolExpression rightSide) : base(leftSide) { Equality = eq; RightSide = rightSide; }
public ConditionalExpressionToken(SymbolExpression leftSide) { LeftSide = leftSide; }
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(); } }
public Indexer(SymbolExpression expression) { Symbol = expression; }
public AnalysisContext BeginChild(Identifier ident, SymbolExpression expan) { return(new AnalysisContext(this, ident, expan)); }
public string Expand(SymbolExpression expression) { return(new SymbolExpression(Expand(expression.Steps)).ToString()); }
AnalysisContext(AnalysisContext parent, Identifier identifier, SymbolExpression expansion) { this.parent = parent; this.identifier = identifier; this.expansion = expansion; }
internal RecursiveDefinitionException(SymbolExpression symbol, Stack <SymbolExpression> ancestorSymbolStack) : base($"An attempt to parse the variable symbol \"{symbol}\" appears to have resulted in a self referencing " + $"loop ({string.Join(" -> ", ancestorSymbolStack.Reverse().Select(x => x.ToString()))} -> {symbol}). " + $"Ensure that recursive loops do not exist in the variable values.") { }
public string?ResolveOptional(SymbolExpression expression, out string[] missingTokens) { var val = WalkTo(expression, out missingTokens); return(val?.Item); }
Binding?WalkTo(SymbolExpression expression, out string[] missingTokens) { ValidateThatRecursionIsNotOccuring(expression); symbolStack.Push(expression); try { Binding?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 { if (step is Indexer ix) { if (ix.IsSymbol || ix.Index == null) { // 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; } if (val != null && val.Indexable.TryGetValue(ix.Index, out Binding? newVal)) { val = newVal; continue; } if (val != null && 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(); } }
public RepetitionToken(SymbolExpression collection, Identifier enumerator, IEnumerable <TemplateToken> template) { this.collection = collection; this.enumerator = enumerator; this.template = template.ToArray(); }