/// <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); } }
/// <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)); } }
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'")); }
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")); }
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)")); }
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")); }
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")); }
public void ShouldThrowWhenGivenStarInDontAcceptStarMode() { ExpressionLexer lexer = new ExpressionLexer("m.*", true, false); Action read = () => lexer.ReadDottedIdentifier(false); read.ShouldThrow <ODataException>(ODataErrorStrings.ExpressionLexer_SyntaxError("2", "m.*")); }
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")); }
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)")); }
/// <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.*")); }
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); }
/// <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); }
public void ExpressionLexerShouldFailAtSymbolIsLastCharacter() { Action lex = () => new ExpressionLexer("@", moveToFirstToken: true, useSemicolonDelimeter: false, parsingFunctionParameters: true); lex.ShouldThrow <ODataException>().WithMessage(ODataErrorStrings.ExpressionLexer_SyntaxError(1, "@")); }