Example #1
0
        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);
            }
        }
Example #5
0
        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());
        }
Example #6
0
        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] == '.':