internal override bool TryEvaluate(CompilationState state, out Context context) { //Copy Stack as identifier elements manipulate (push, pop) var cpContextStack = new Stack<Context>(); cpContextStack = new Stack<Context>(state.ContextStack.Reverse()); return Path.TryEvaluate(cpContextStack, state, out context); }
internal override bool TryEvaluate(Stack<Context> contextStack, CompilationState state, out Context context) { //Add the Identifier to the current context var memberSymbol = contextStack.Any() ? contextStack.Peek().Symbol.FindMember(_value) : state.Introspector.GetTypeSymbol(_value); if (memberSymbol != null) { var identifierContext = new Context(string.Join(".", contextStack.Peek().FullPath, _value), memberSymbol); if (_next == null) { //Last element => return IdentifierContext context = identifierContext; return true; } else { //Push the identifier on the contextStack and keep going contextStack.Push(identifierContext); return _next.TryEvaluate(contextStack, state, out context); } } else { state.AddTypeError($"Could not find Member '{_value}' in Type '{contextStack.Peek().Symbol.ToDisplayString()}'!", HandlebarsTypeErrorKind.UnknownMember); context = null; return false; } }
internal override bool TryEvaluate(CompilationState state, out Context context) { var ctLoopContext = IsCompileTimeLoop(state); if (ctLoopContext!=null) {//Inside CTLoop -> Return literal context = new Context(ctLoopContext.First.ToString().ToLower(), state.Introspector.GetBoolTypeSymbol()); return true; } else { context = new Context($"first{state.LoopLevel}", state.Introspector.GetBoolTypeSymbol()); return InsideEachLoopCheck(state); } }
internal override bool TryEvaluate(CompilationState state, out Context context) { var ctLoopContext = IsCompileTimeLoop(state); if (ctLoopContext!=null) { context = new Context($"\"{ctLoopContext.Key}\"", state.Introspector.GetStringTypeSymbol()); return true; } else { state.AddTypeError("KeyExpression outside a compiletime loop over an Object", HandlebarsTypeErrorKind.IllegalKeyExpression); context = null; return false; } }
internal abstract bool TryEvaluate(CompilationState state, out Context context);
internal override bool TryEvaluate(CompilationState state, out Context context) { context = new Context($"\"{_value}\"", state.Introspector.GetStringTypeSymbol()); return true; }
internal abstract bool TryEvaluate(Stack<Context> contextStack, CompilationState state, out Context context);
internal override bool TryEvaluate(Stack<Context> contextStack, CompilationState state, out Context context) { if (_next == null) { context = contextStack.Peek(); return true; } else return _next.TryEvaluate(contextStack, state, out context); }
internal override bool TryEvaluate(Stack<Context> contextStack, CompilationState state, out Context context) { if (_next == null) { context = contextStack.Last(); return true; } else { var rootedContextStack = new Stack<Context>(); rootedContextStack.Push(contextStack.Last()); return _next.TryEvaluate(rootedContextStack, state, out context); } }
internal override bool TryEvaluate(Stack<Context> contextStack, CompilationState state, out Context context) { if (!contextStack.Any() || contextStack.Count == 1) { state.AddTypeError("Error in MemberExpression: Empty ContextStack but PathUp Element ('../')!", HandlebarsTypeErrorKind.EmptyContextStack); context = null; return false; } contextStack.Pop(); return _next.TryEvaluate(contextStack, state, out context); }
/// <summary> /// Returns a list of strings of the elements of a context which needs to be checked. /// I.e. if the path in contextToCheck is "viewModel.Parent.Child" and the path in lastCheckedContext is /// "viewModel" it will return { "viewModel.Parent", "viewModel.Parent.Child" } /// Also unreachable code is detected /// </summary> /// <param name="lastCheckedContext"></param> /// <param name="contextToCheck"></param> /// <returns></returns> private List<string> GetQueryElements(Context lastCheckedContext, Context contextToCheck) {//Items -> ItemsTitle var resultList = new List<string>(); var lastCheckedElements = lastCheckedContext?.FullPath.Split('.') ?? new string[0]; var pathToCheckElements = contextToCheck.FullPath.Split('.'); List<string> relevantElements = new List<string>(); List<string> prefixElements = new List<string>(); if (lastCheckedElements.Any()) { int i = 0; for (i = 0; i < Math.Min(lastCheckedElements.Length, pathToCheckElements.Length); i++) { if (lastCheckedElements[i].Equals(pathToCheckElements[i])) prefixElements.Add(lastCheckedElements[i]); else break; } if (pathToCheckElements.Length > i) relevantElements.AddRange(pathToCheckElements.Skip(i)); } else relevantElements = pathToCheckElements.ToList(); string prefix = prefixElements.Any() ? string.Join(".", prefixElements) + ".": string.Empty; for (int i = 1; i <= relevantElements.Count; i++) {//then join them back together with the prefix resultList.Add(string.Concat(prefix, string.Join(".", relevantElements.Take(i).ToArray()))); } return resultList; }
internal void PromiseTruthyCheck(Context contextToCheck, IfType ifType = IfType.If) { contextToCheck.Truthy = ifType == IfType.If; TruthyStack.Push(contextToCheck); }