예제 #1
0
        static List <Token> ValidateAndTokenize(string expression, out ExpressionType expressionType)
        {
            expressionType = ExpressionEvaluator.PeekExpressionType(expression);

            if (expressionType == ExpressionType.Literal)
            {
                return(new List <Token>());
            }

            List <Token> tokens       = new List <Token>();
            string       workingInput = expression;
            int          tokenEndIndex;

            if (expressionType == ExpressionType.Composite)
            {
                if (expression[expression.Length - 1] != '}')
                {
                    throw new InvalidDataContractException(SRClient.ExpressionMissingClosingParenthesesNoToken(expression));
                }

                workingInput = expression.Substring(1, expression.Length - 2).TrimEnd();
            }

            while (true)
            {
                Token token = new Token();
                workingInput = workingInput.TrimStart();

                if (workingInput.Length < 3)
                {
                    throw new InvalidDataContractException(SRClient.ExpressionInvalidToken(expression, workingInput));
                }

                switch (workingInput[0])
                {
                case '.':
                    token.Type    = TokenType.Dot;
                    tokenEndIndex = ExpressionEvaluator.ExtractToken(expression, workingInput, token);
                    break;

                case '%':
                    token.Type    = TokenType.Percentage;
                    tokenEndIndex = ExpressionEvaluator.ExtractToken(expression, workingInput, token);
                    break;

                case '\'':
                    token.Type    = TokenType.SingleLiteral;
                    tokenEndIndex = ExpressionEvaluator.ExtractLiteral(expression, workingInput, token);
                    break;

                case '"':
                    token.Type    = TokenType.DoubleLiteral;
                    tokenEndIndex = ExpressionEvaluator.ExtractLiteral(expression, workingInput, token);
                    break;

                case '#':
                    token.Type    = TokenType.Hash;
                    tokenEndIndex = ExpressionEvaluator.ExtractToken(expression, workingInput, token);
                    break;

                case '$':
                    if (workingInput.ToLowerInvariant().StartsWith(BodyExpression, StringComparison.OrdinalIgnoreCase))
                    {
                        tokenEndIndex = BodyExpression.Length - 1;
                        token.Type    = TokenType.Body;
                    }
                    else
                    {
                        token.Type    = TokenType.Dollar;
                        tokenEndIndex = ExpressionEvaluator.ExtractToken(expression, workingInput, token);
                    }

                    break;

                default:
                    throw new InvalidDataContractException(SRClient.ExpressionInvalidTokenType(expression, workingInput));
                }

                if (token.Type != TokenType.SingleLiteral &&
                    token.Type != TokenType.DoubleLiteral &&
                    token.Type != TokenType.Body &&
                    !string.Equals(token.Property, ExpressionEvaluator.BodyExpression, StringComparison.OrdinalIgnoreCase))
                {
                    if (!ExpressionEvaluator.PropertyNameRegEx.IsMatch(token.Property))
                    {
                        throw new InvalidDataContractException(SRClient.PropertyNameIsBad(token.Property));
                    }

                    if (token.Property.Length > ExpressionEvaluator.MaxLengthOfPropertyName)
                    {
                        throw new InvalidDataContractException(SRClient.PropertyTooLong(token.Property.Length, ExpressionEvaluator.MaxLengthOfPropertyName));
                    }
                }

                tokens.Add(token);

                if (workingInput.Length == tokenEndIndex + 1)
                {
                    break;
                }

                workingInput = workingInput.Substring(tokenEndIndex + 1).TrimStart();

                if (workingInput[0] != '+')
                {
                    throw new InvalidDataContractException(SRClient.ExpressionInvalidCompositionOperator(expression, workingInput));
                }

                workingInput = workingInput.Substring(1);
            }

            if (tokens.Count > 1 && tokens.Find((token) => token.Type == TokenType.Hash) != null)
            {
                throw new InvalidDataContractException(SRClient.ExpressionHashInComposite);
            }

            return(tokens);
        }