public static PathInfo Parse(string path) { if (path == "null") { return(Empty); } var originalPath = path; var pathType = GetPathType(path); var pathSubstring = new Substring(path); var isValidHelperLiteral = true; var isVariable = pathType == PathType.Variable; var isInversion = pathType == PathType.Inversion; var isBlockHelper = pathType == PathType.BlockHelper; if (isVariable || isBlockHelper || isInversion) { isValidHelperLiteral = isBlockHelper || isInversion; pathSubstring = new Substring(pathSubstring, 1); } var segments = new List <PathSegment>(); var pathParts = Substring.Split(pathSubstring, '/'); var extendedEnumerator = ExtendedEnumerator <Substring> .Create(pathParts); while (extendedEnumerator.MoveNext()) { var segment = extendedEnumerator.Current.Value; if (segment.Length == 2 && segment[0] == '.' && segment[1] == '.') { isValidHelperLiteral = false; segments.Add(new PathSegment(segment, ArrayEx.Empty <ChainSegment>())); continue; } if (segment.Length == 1 && segment[0] == '.') { isValidHelperLiteral = false; segments.Add(new PathSegment(segment, ArrayEx.Empty <ChainSegment>())); continue; } var chainSegments = GetPathChain(segment); if (chainSegments.Length > 1) { isValidHelperLiteral = false; } segments.Add(new PathSegment(segment, chainSegments)); } if (isValidHelperLiteral && segments.Count > 1) { isValidHelperLiteral = false; } return(new PathInfo(pathType, originalPath, isValidHelperLiteral, segments.ToArray())); }
private static void IterateObject( BindingContext context, EncodedTextWriter writer, ObjectDescriptor descriptor, ChainSegment[] blockParamsVariables, object target, IEnumerable properties, Type targetType, TemplateDelegate template, TemplateDelegate ifEmpty) { using var innerContext = context.CreateFrame(); var iterator = new ObjectIteratorValues(innerContext); var blockParams = new BlockParamsValues(innerContext, blockParamsVariables); blockParams.CreateProperty(0, out var _0); blockParams.CreateProperty(1, out var _1); var accessor = new MemberAccessor(target, descriptor); var enumerable = new ExtendedEnumerator <object>(properties.GetEnumerator()); var enumerated = false; object iteratorValue; ChainSegment iteratorKey; while (enumerable.MoveNext()) { enumerated = true; var enumerableValue = enumerable.Current; iteratorKey = ChainSegment.Create(enumerableValue.Value); iterator.Key = iteratorKey; iterator.Index = enumerableValue.Index; if (enumerableValue.Index == 1) { iterator.First = BoxedValues.False; } if (enumerableValue.IsLast) { iterator.Last = BoxedValues.True; } iteratorValue = accessor[iteratorKey]; iterator.Value = iteratorValue; innerContext.Value = iteratorValue; blockParams[_0] = iteratorValue; blockParams[_1] = iteratorKey; template(writer, innerContext); } if (!enumerated) { innerContext.Value = context.Value; ifEmpty(writer, innerContext); } }
public IExtendedEnumerator <Token> Filter(List <Token> input) { IExtendedEnumerator <Token> tokens = new ExtendedEnumerator <Token>(input); foreach (ITokenFilter filter in this.filters) { tokens = filter.Filter(tokens); } return(tokens); }
private static void IterateEnumerable( BindingContext context, EncodedTextWriter writer, ChainSegment[] blockParamsVariables, IEnumerable target, TemplateDelegate template, TemplateDelegate ifEmpty) { using var innerContext = context.CreateFrame(); var iterator = new IteratorValues(innerContext); var blockParams = new BlockParamsValues(innerContext, blockParamsVariables); blockParams.CreateProperty(0, out var _0); blockParams.CreateProperty(1, out var _1); var enumerator = new ExtendedEnumerator <object>(target.GetEnumerator()); var enumerated = false; object boxedIndex; object iteratorValue; while (enumerator.MoveNext()) { enumerated = true; var enumerableValue = enumerator.Current; if (enumerableValue.Index == 1) { iterator.First = BoxedValues.False; } if (enumerableValue.IsLast) { iterator.Last = BoxedValues.True; } boxedIndex = enumerableValue.Index; iteratorValue = enumerableValue.Value; iterator.Value = iteratorValue; iterator.Index = boxedIndex; blockParams[_0] = iteratorValue; blockParams[_1] = boxedIndex; innerContext.Value = iteratorValue; template(writer, innerContext); } if (!enumerated) { innerContext.Value = context.Value; ifEmpty(writer, innerContext); } }
private static ChainSegment[] GetPathChain(Substring segmentString) { var insideEscapeBlock = false; var pathChainParts = Substring.Split(segmentString, '.', StringSplitOptions.RemoveEmptyEntries); var extendedEnumerator = ExtendedEnumerator <Substring> .Create(pathChainParts); if (!extendedEnumerator.Any && segmentString == ".") { return new[] { ChainSegment.This } } ; var chainSegments = new List <ChainSegment>(); while (extendedEnumerator.MoveNext()) { var next = extendedEnumerator.Current.Value; if (insideEscapeBlock) { if (next.EndsWith(']')) { insideEscapeBlock = false; } chainSegments[chainSegments.Count - 1] = ChainSegment.Create($"{chainSegments[chainSegments.Count - 1]}.{next.ToString()}"); continue; } if (next.StartsWith('[')) { insideEscapeBlock = true; } if (next.EndsWith(']')) { insideEscapeBlock = false; } chainSegments.Add(ChainSegment.Create(next.ToString())); } return(chainSegments.ToArray()); }
public static PathInfo Parse(string path) { if (path == "null") { return(Empty); } var originalPath = path; var pathType = GetPathType(path); var pathSubstring = new Substring(path); var isValidHelperLiteral = true; var isVariable = pathType == PathType.Variable; var isInversion = pathType == PathType.Inversion; var isBlockHelper = pathType == PathType.BlockHelper; if (isVariable || isBlockHelper || isInversion) { isValidHelperLiteral = isBlockHelper || isInversion; pathSubstring = new Substring(pathSubstring, 1); } var segments = new List <PathSegment>(); var pathParts = Substring.Split(pathSubstring, '/'); var extendedEnumerator = ExtendedEnumerator <Substring> .Create(pathParts); using var container = StringBuilderPool.Shared.Use(); var buffer = container.Value; while (extendedEnumerator.MoveNext()) { var segment = extendedEnumerator.Current.Value; if (buffer.Length != 0) { buffer.Append('/'); buffer.Append(in segment); if (Substring.LastIndexOf(segment, ']', out var index) && !Substring.LastIndexOf(segment, '[', index, out _)) { var chainSegment = GetPathChain(buffer.ToString()); if (chainSegment.Length > 1) { isValidHelperLiteral = false; } segments.Add(new PathSegment(segment, chainSegment)); buffer.Length = 0; continue; } } if (Substring.LastIndexOf(segment, '[', out var startIndex) && !Substring.LastIndexOf(segment, ']', startIndex, out _)) { buffer.Append(in segment); continue; } switch (segment.Length) { case 2 when segment[0] == '.' && segment[1] == '.':