Exemple #1
0
 /// <summary>
 /// Get type-prefixed literals with quoted values duration, binary and spatial types.
 /// </summary>
 /// <param name="tokenText">Token text</param>
 /// <returns>ExpressionTokenKind</returns>
 /// <example>geometry'POINT (79 84)'. 'geometry' is the tokenText </example>
 private ExpressionTokenKind GetBuiltInTypesLiteralPrefixWithQuotedValue(string tokenText)
 {
     if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixDuration, StringComparison.OrdinalIgnoreCase))
     {
         return(ExpressionTokenKind.DurationLiteral);
     }
     else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixBinary, StringComparison.OrdinalIgnoreCase))
     {
         return(ExpressionTokenKind.BinaryLiteral);
     }
     else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixGeography, StringComparison.OrdinalIgnoreCase))
     {
         return(ExpressionTokenKind.GeographyLiteral);
     }
     else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixGeometry, StringComparison.OrdinalIgnoreCase))
     {
         return(ExpressionTokenKind.GeometryLiteral);
     }
     else if (string.Equals(tokenText, ExpressionConstants.KeywordNull, StringComparison.OrdinalIgnoreCase))
     {
         // typed null literals are not supported.
         throw ParseError(ODataErrorStrings.ExpressionLexer_SyntaxError(this.textPos, this.Text));
     }
     else
     {
         // treat as quoted literal
         return(ExpressionTokenKind.QuotedLiteral);
     }
 }
Exemple #2
0
 /// <summary>Validates the current token is of the specified kind.</summary>
 /// <param name="t">Expected token kind.</param>
 internal void ValidateToken(ExpressionTokenKind t)
 {
     if (this.token.Kind != t)
     {
         throw ParseError(ODataErrorStrings.ExpressionLexer_SyntaxError(this.textPos, this.Text));
     }
 }
Exemple #3
0
        public void TypedNullFunctionParameterParsingShouldThrow()
        {
            ICollection <OperationSegmentParameter> parsedParameters;
            Action parse = () => TryParsOperationParameters("CanMoveToAddress", "address=null'Fully.Qualified.Namespace.Address'", null, out parsedParameters).Should().BeTrue();

            parse.ShouldThrow <ODataException>().WithMessage(ODataErrorStrings.ExpressionLexer_SyntaxError(12, "address=null'Fully.Qualified.Namespace.Address'"));
        }
Exemple #4
0
        public void FunctionParameterParserShouldThrowIfSecondParameterIsPositional()
        {
            ICollection <OperationSegmentParameter> parsedParameters;
            Action parse = () => TryParseFunctionParameters("fakeFunc", "a=1,2", null, out parsedParameters);

            parse.ShouldThrow <ODataException>().WithMessage(ODataErrorStrings.ExpressionLexer_SyntaxError(5, "a=1,2"));
        }
Exemple #5
0
        public void AnyAllSyntacticParsingShouldCheckSeperatorTokenIsColon()
        {
            // Repro for: Syntactic parsing for Any/All allows an arbitrary token between range variable and expression
            Action parse = () => this.testSubject.ParseFilter("Things/any(a,true)");

            parse.ShouldThrow <ODataException>().WithMessage(ErrorStrings.ExpressionLexer_SyntaxError("13", "Things/any(a,true)"));
        }
Exemple #6
0
        public void ShouldThrowWhenCurrentTokenIsNotExpressionKind()
        {
            ExpressionLexer lexer    = new ExpressionLexer("null", true, false);
            Action          validate = () => lexer.ValidateToken(ExpressionTokenKind.Question);

            validate.ShouldThrow <ODataException>().WithMessage(ODataErrorStrings.ExpressionLexer_SyntaxError(4, "null"));
        }
Exemple #7
0
        public void StarMustBeLastTokenInDottedIdentifier()
        {
            ExpressionLexer lexer = new ExpressionLexer("m.*.blah", true, false);
            Action          read  = () => lexer.ReadDottedIdentifier(true);

            read.ShouldThrow <ODataException>(ODataErrorStrings.ExpressionLexer_SyntaxError("2", "m.*.blah"));
        }
Exemple #8
0
        public void ShouldThrowWhenGivenStarInDontAcceptStarMode()
        {
            ExpressionLexer lexer = new ExpressionLexer("m.*", true, false);
            Action          read  = () => lexer.ReadDottedIdentifier(false);

            read.ShouldThrow <ODataException>(ODataErrorStrings.ExpressionLexer_SyntaxError("2", "m.*"));
        }
Exemple #9
0
        public void ShouldThrowWhenNotGivenIdentifierToken()
        {
            ExpressionLexer lexer = new ExpressionLexer("2.43", false, false);
            Action          read  = () => lexer.ReadDottedIdentifier(false);

            read.ShouldThrow <ODataException>().WithMessage(ODataErrorStrings.ExpressionLexer_SyntaxError("0", "2.43"));
        }
Exemple #10
0
        public void FunctionParameterParserShouldFailIfAnExtraClosingParenthesisIsFoundInPath()
        {
            ICollection <FunctionParameterToken> splitParameters;
            ODataUriParserConfiguration          configuration = new ODataUriParserConfiguration(HardCodedTestModel.TestModel)
            {
                ParameterAliasValueAccessor = null
            };
            Action parse = () => FunctionParameterParser.TrySplitOperationParameters(/*"fakeFunc", */ "a=1)", configuration, out splitParameters);

            parse.ShouldThrow <ODataException>().WithMessage(ODataErrorStrings.ExpressionLexer_SyntaxError(4, "a=1)"));
        }
Exemple #11
0
        /// <summary>
        /// Starting from an identifier, reads a sequence of dots and
        /// identifiers, and returns the text for it, with whitespace
        /// stripped.
        /// </summary>
        /// <param name="acceptStar">do we allow a star in this identifier</param>
        /// <returns>The dotted identifier starting at the current identifier.</returns>
        internal string ReadDottedIdentifier(bool acceptStar)
        {
            this.ValidateToken(ExpressionTokenKind.Identifier);
            StringBuilder builder = null;
            string        result  = this.CurrentToken.Text;

            this.NextToken();
            while (this.CurrentToken.Kind == ExpressionTokenKind.Dot)
            {
                this.NextToken();
                if (this.CurrentToken.Kind != ExpressionTokenKind.Identifier &&
                    this.CurrentToken.Kind != ExpressionTokenKind.QuotedLiteral)
                {
                    if (this.CurrentToken.Kind == ExpressionTokenKind.Star)
                    {
                        // if we accept a star and this is the last token in the identifier, then we're ok... otherwise we throw.
                        if (!acceptStar || (this.PeekNextToken().Kind != ExpressionTokenKind.End && this.PeekNextToken().Kind != ExpressionTokenKind.Comma))
                        {
                            throw ParseError(ODataErrorStrings.ExpressionLexer_SyntaxError(this.textPos, this.Text));
                        }
                    }
                    else
                    {
                        throw ParseError(ODataErrorStrings.ExpressionLexer_SyntaxError(this.textPos, this.Text));
                    }
                }

                if (builder == null)
                {
                    builder = new StringBuilder(result, result.Length + 1 + this.CurrentToken.Text.Length);
                }

                builder.Append('.');
                builder.Append(this.CurrentToken.Text);
                this.NextToken();
            }

            if (builder != null)
            {
                result = builder.ToString();
            }

            return(result);
        }
        public void ContainerQualifiedWildcardNotAllowedInExpand()
        {
            Action parseWithContainerQualfiedWildcard = () => this.ParseExpandTerm("container.qualified.*");

            parseWithContainerQualfiedWildcard.ShouldThrow <ODataException>(ODataErrorStrings.ExpressionLexer_SyntaxError("10", "container.qualified.*"));
        }
Exemple #13
0
        protected virtual ExpressionToken NextTokenImplementation(out Exception error)
        {
            error = null;

            if (this.ignoreWhitespace)
            {
                this.ParseWhitespace();
            }

            ExpressionTokenKind t;
            int tokenPos = this.textPos;

            switch (this.ch)
            {
            case '(':
                this.NextChar();
                t = ExpressionTokenKind.OpenParen;
                break;

            case ')':
                this.NextChar();
                t = ExpressionTokenKind.CloseParen;
                break;

            case ',':
                this.NextChar();
                t = ExpressionTokenKind.Comma;
                break;

            case '-':
                bool hasNext = this.textPos + 1 < this.TextLen;
                if (hasNext && Char.IsDigit(this.Text[this.textPos + 1]))
                {
                    // don't separate '-' and its following digits : -2147483648 is valid int.MinValue, but 2147483648 is long.
                    t = this.ParseFromDigit();
                    if (ExpressionLexerUtils.IsNumeric(t))
                    {
                        break;
                    }

                    // If it looked like a numeric but wasn't (because it was a binary 0x... value for example),
                    // we'll rewind and fall through to a simple '-' token.
                    this.SetTextPos(tokenPos);
                }
                else if (hasNext && this.Text[tokenPos + 1] == ExpressionConstants.InfinityLiteral[0])
                {
                    this.NextChar();
                    this.ParseIdentifier();
                    string currentIdentifier = this.Text.Substring(tokenPos + 1, this.textPos - tokenPos - 1);

                    if (ExpressionLexerUtils.IsInfinityLiteralDouble(currentIdentifier))
                    {
                        t = ExpressionTokenKind.DoubleLiteral;
                        break;
                    }
                    else if (ExpressionLexerUtils.IsInfinityLiteralSingle(currentIdentifier))
                    {
                        t = ExpressionTokenKind.SingleLiteral;
                        break;
                    }

                    // If it looked like '-INF' but wasn't we'll rewind and fall through to a simple '-' token.
                    this.SetTextPos(tokenPos);
                }

                this.NextChar();
                t = ExpressionTokenKind.Minus;
                break;

            case '=':
                this.NextChar();
                t = ExpressionTokenKind.Equal;
                break;

            case '/':
                this.NextChar();
                t = ExpressionTokenKind.Slash;
                break;

            case '?':
                this.NextChar();
                t = ExpressionTokenKind.Question;
                break;

            case '.':
                this.NextChar();
                t = ExpressionTokenKind.Dot;
                break;

            case '\'':
                char quote = this.ch.Value;
                do
                {
                    this.AdvanceToNextOccuranceOf(quote);

                    if (this.textPos == this.TextLen)
                    {
                        error = ParseError(ODataErrorStrings.ExpressionLexer_UnterminatedStringLiteral(this.textPos, this.Text));
                    }

                    this.NextChar();
                }while (this.ch.HasValue && (this.ch.Value == quote));
                t = ExpressionTokenKind.StringLiteral;
                break;

            case '*':
                this.NextChar();
                t = ExpressionTokenKind.Star;
                break;

            case ':':
                this.NextChar();
                t = ExpressionTokenKind.Colon;
                break;

            case '{':
                this.NextChar();
                this.AdvanceThroughBalancedExpression('{', '}');
                t = ExpressionTokenKind.BracketedExpression;
                break;

            case '[':
                this.NextChar();
                this.AdvanceThroughBalancedExpression('[', ']');
                t = ExpressionTokenKind.BracketedExpression;
                break;

            default:
                if (this.IsValidWhiteSpace)
                {
                    Debug.Assert(!this.ignoreWhitespace, "should not hit ws while ignoring it");
                    this.ParseWhitespace();
                    t = ExpressionTokenKind.Unknown;
                    break;
                }

                if (this.IsValidStartingCharForIdentifier)
                {
                    this.ParseIdentifier();

                    // Guids will have '-' in them
                    // guidValue = 8HEXDIG "-" 4HEXDIG "-" 4HEXDIG "-" 4HEXDIG "-" 12HEXDIG
                    if (this.ch == '-' &&
                        this.TryParseGuid(tokenPos))
                    {
                        t = ExpressionTokenKind.GuidLiteral;
                        break;
                    }

                    t = ExpressionTokenKind.Identifier;
                    break;
                }

                if (this.IsValidDigit)
                {
                    t = this.ParseFromDigit();
                    break;
                }

                if (this.textPos == this.TextLen)
                {
                    t = ExpressionTokenKind.End;
                    break;
                }

                if (this.useSemicolonDelimeter && this.ch == ';')
                {
                    this.NextChar();
                    t = ExpressionTokenKind.SemiColon;
                    break;
                }

                if (this.parsingFunctionParameters && this.ch == '@')
                {
                    this.NextChar();

                    if (this.textPos == this.TextLen)
                    {
                        error = ParseError(ODataErrorStrings.ExpressionLexer_SyntaxError(this.textPos, this.Text));
                        t     = ExpressionTokenKind.Unknown;
                        break;
                    }

                    if (!this.IsValidStartingCharForIdentifier)
                    {
                        error = ParseError(ODataErrorStrings.ExpressionLexer_InvalidCharacter(this.ch, this.textPos, this.Text));
                        t     = ExpressionTokenKind.Unknown;
                        break;
                    }

                    this.ParseIdentifier();
                    t = ExpressionTokenKind.ParameterAlias;
                    break;
                }

                error = ParseError(ODataErrorStrings.ExpressionLexer_InvalidCharacter(this.ch, this.textPos, this.Text));
                t     = ExpressionTokenKind.Unknown;
                break;
            }

            this.token.Kind     = t;
            this.token.Text     = this.Text.Substring(tokenPos, this.textPos - tokenPos);
            this.token.Position = tokenPos;

            this.HandleTypePrefixedLiterals();

            return(this.token);
        }
Exemple #14
0
        /// <summary>Handles lexemes that are formed by an identifier followed by a quoted string.</summary>
        /// <remarks>This method modified the token field as necessary.</remarks>
        private void HandleTypePrefixedLiterals()
        {
            ExpressionTokenKind id = this.token.Kind;

            if (id != ExpressionTokenKind.Identifier)
            {
                return;
            }

            bool quoteFollows = this.ch == '\'';

            if (!quoteFollows)
            {
                return;
            }

            string tokenText = this.token.Text;

            if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixDuration, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.DurationLiteral;
            }
            else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixBinary, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.BinaryLiteral;
            }
            else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixGeography, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.GeographyLiteral;
            }
            else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixGeometry, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.GeometryLiteral;
            }
            else if (string.Equals(tokenText, ExpressionConstants.KeywordNull, StringComparison.OrdinalIgnoreCase))
            {
                // typed null literals are not supported.
                throw ParseError(ODataErrorStrings.ExpressionLexer_SyntaxError(this.textPos, this.Text));
            }
            else
            {
                // treat as quoted literal
                id = ExpressionTokenKind.QuotedLiteral;
            }

            int tokenPos = this.token.Position;

            do
            {
                this.NextChar();
            }while (this.ch.HasValue && this.ch != '\'');

            if (this.ch == null)
            {
                throw ParseError(ODataErrorStrings.ExpressionLexer_UnterminatedLiteral(this.textPos, this.Text));
            }

            this.NextChar();
            this.token.Kind = id;
            this.token.Text = this.Text.Substring(tokenPos, this.textPos - tokenPos);
        }
Exemple #15
0
        public void ExpressionLexerShouldFailAtSymbolIsLastCharacter()
        {
            Action lex = () => new ExpressionLexer("@", moveToFirstToken: true, useSemicolonDelimeter: false, parsingFunctionParameters: true);

            lex.ShouldThrow <ODataException>().WithMessage(ODataErrorStrings.ExpressionLexer_SyntaxError(1, "@"));
        }