示例#1
0
        public Expression Parse(IParser parser)
        {
            var segments = new List <ExpressionSegment>();

            while (!parser.Is('`'))
            {
                if (parser.Is('$'))
                {
                    parser.Expect('$');
                    parser.Skip();
                    parser.Expect('{');
                    parser.Skip();
                    parser.SkipWhitespace();
                    var segment = new ExpressionSegment(ExpressionSegmentType.Interpolated, parser.ReadUntil('}'));
                    segments.Add(segment);
                    parser.SkipWhitespace();
                    parser.Expect('}');
                    parser.Skip();
                }
                else
                {
                    segments.Add(new ExpressionSegment(ExpressionSegmentType.Literal, parser.ReadUntil('$', '`')));
                }
            }

            return(new Expression(segments));
        }
        private void AggregateMethodCalls(Func<AssertionComponent, string, int, ExpressionSegment> getSegment, Action<ExpressionSegment> useSegment)
        {
            SourceAddress assertionsAddress = calls.First().SourceAddress;

            string[] sourceLines;
            if (!Utils.TryReadAllLines(assertionsAddress, out sourceLines))
                return;

            string expressionSource = sourceLines.Skip(assertionsAddress.LineIndex).Join(Environment.NewLine);

            ExpressionSegment segment = new ExpressionSegment { IndexOfNextSegment = assertionsAddress.ExpressionIndex };
            foreach (AssertionComponent method in MethodCalls)
            {
                segment = getSegment(method, expressionSource, segment.IndexOfNextSegment);
                useSegment(segment);
            }
        }
        IEnumerable <ExpressionSegment> ToParts(string expr)
        {
            if (string.IsNullOrEmpty(expr))
            {
                yield break;
            }

            int    len = expr.Length;
            char   ch;
            int    offset = 0;
            int    count  = 0;
            bool   isKw;
            string keyword  = null;
            bool   isWord   = false;
            bool   isDigit  = false;
            int    index    = 0;
            bool   isString = false;

            ExpressionSegment prev = null;
            ExpressionSegment current;

            for (int i = 0; i < len; i++)
            {
                ch   = expr[i];
                isKw = false;

                if (offset == i)
                {
                    if (isSpaceChar(ch))
                    {
                        offset = i + 1;
                        count  = 0;
                        continue;
                    }
                    isString = false;
                    isWord   = false;
                    isDigit  = false;
                    if (ch == '"')
                    {
                        isString = true;
                        count    = 0;
                        continue;
                    }
                    else if (IsStartChar(ch))
                    {
                        isWord = true;
                    }
                    else
                    {
                        if (IsDigit(ch))
                        {
                            isDigit = true;
                        }
                    }
                    count = 1;
                    if (!isWord && !isDigit)
                    {
                        if (kws.ContainsKey(ch.ToString()))
                        {
                            bool isOper = true;
                            //if (ch == '(' || ch == ')')
                            //    isOper = false;
                            if (i < len - 1 && kws.ContainsKey(ch.ToString() + expr[i + 1]))
                            {
                                current = new ExpressionSegment()
                                {
                                    Index     = index++,
                                    Expr      = ch.ToString() + expr[i + 1],
                                    Offset    = offset,
                                    Length    = 2,
                                    IsKeyword = true,
                                    IsOper    = isOper,
                                    Prev      = prev
                                };
                                yield return(current);

                                prev = current;
                                i++;
                                offset = i + 1;
                            }
                            else
                            {
                                current = new ExpressionSegment()
                                {
                                    Index     = index++,
                                    Expr      = ch.ToString(),
                                    Offset    = offset,
                                    Length    = 1,
                                    IsKeyword = true,
                                    IsOper    = isOper,
                                    Prev      = prev
                                };
                                yield return(current);

                                prev   = current;
                                offset = i + 1;
                            }
                        }
                    }
                    continue;
                }
                else
                {
                    if (isString)
                    {
                        if (ch != '"')
                        {
                            count++;
                            continue;
                        }
                        current = new ExpressionSegment()
                        {
                            Index    = index++,
                            Expr     = expr.Substring(offset + 1, count),
                            IsString = true,
                            Offset   = offset,
                            Length   = count + 2,
                            Prev     = prev,
                        };
                        yield return(current);

                        prev     = current;
                        offset   = i + 1;
                        isString = false;
                        continue;
                    }
                    else if (isDigit)
                    {
                        if (IsDigit(ch))
                        {
                            count++;
                            continue;
                        }
                    }
                    else if (isWord)
                    {
                        if (IsMemberChar(ch))
                        {
                            count++;
                            continue;
                        }
                    }
                    else
                    {
                        if (!IsStartChar(ch) && !IsDigit(ch) && ch != '"')
                        {
                            count++;
                            continue;
                        }
                    }
                }

                if (count > 0)
                {
                    current = new ExpressionSegment()
                    {
                        Index  = index++,
                        Expr   = expr.Substring(offset, count),
                        Offset = offset,
                        Length = count,
                        Prev   = prev,
                    };
                    if (isDigit)
                    {
                        current.IsDigit = true;
                    }
                    else
                    {
                        current.IsOper = kws.ContainsKey(current.Expr);
                    }

                    yield return(current);

                    prev = current;
                }
                i--;
                offset = i + 1;
                count  = 0;
            }

            if (len > offset)
            {
                current = new ExpressionSegment()
                {
                    Index  = index++,
                    Expr   = expr.Substring(offset, len - offset),
                    Offset = offset,
                    Length = len - offset,
                    Prev   = prev
                };
                if (isDigit)
                {
                    current.IsDigit = true;
                }
                else
                {
                    current.IsOper = kws.ContainsKey(current.Expr);
                }
                yield return(current);

                prev = current;
            }
        }