private bool IsPossibleExpression() { var tk = this.CurrentToken.Kind; switch (tk) { case SyntaxKind.DefaultKeyword: case SyntaxKind.ArgListKeyword: case SyntaxKind.SuperKeyword: case SyntaxKind.FalseKeyword: case SyntaxKind.ThisKeyword: case SyntaxKind.TrueKeyword: case SyntaxKind.NullKeyword: case SyntaxKind.OpenParenToken: case SyntaxKind.NumericLiteralToken: case SyntaxKind.StringLiteralToken: case SyntaxKind.CharacterLiteralToken: case SyntaxKind.NewKeyword: case SyntaxKind.ColonColonToken: // bad aliased name case SyntaxKind.AtToken: case SyntaxKind.OpenBraceToken: return(true); case SyntaxKind.IdentifierToken: // Specifically allow the from contextual keyword, because it can always be the start of an // expression (whether it is used as an identifier or a keyword). return(this.IsTrueIdentifier()); default: return(IsExpectedPrefixUnaryOperator(tk) || (IsPredefinedType(tk) && tk != SyntaxKind.VoidKeyword) || SyntaxKindFacts.IsAnyUnaryExpression(tk) || SyntaxKindFacts.IsBinaryExpression(tk)); } }
internal static SyntaxToken Create(SyntaxKind kind, CSharpSyntaxNode leading, CSharpSyntaxNode trailing) { if (kind > LastTokenWithWellKnownText) { if (!SyntaxKindFacts.IsAnyToken(kind)) { throw new ArgumentException(string.Format(CSharpResources.ThisMethodCanOnlyBeUsedToCreateTokens, kind), "kind"); } return(CreateMissing(kind, leading, trailing)); } if (leading == null) { if (trailing == null) { return(TokensWithNoTrivia[(int)kind].Value); } else if (trailing == SyntaxFactory.Space) { return(TokensWithSingleTrailingSpace[(int)kind].Value); } else if (trailing == SyntaxFactory.CarriageReturnLineFeed) { return(TokensWithSingleTrailingCRLF[(int)kind].Value); } } if (leading == SyntaxFactory.ElasticZeroSpace && trailing == SyntaxFactory.ElasticZeroSpace) { return(TokensWithElasticTrivia[(int)kind].Value); } return(new SyntaxTokenWithTrivia(kind, leading, trailing)); }
private static CanConsumeResult SelectCanConsumeNext(ParsingContext xoContext, Boolean xbIsPreconsumption = false) { SyntaxKind oKind = xoContext.List.Peek().ExpectedType; // Only add core statements after the column list Boolean bIsCoreStatement = ((int)oKind >= (int)SyntaxKind.FromKeyword && (int)oKind <= (int)SyntaxKind.HavingKeyword); // If a column list hasn't been initialised yet if (xoContext.CurrentNode.Count == 0 && // And we have something that can be consumed by a column list (SyntaxKindFacts.IsIdentifierOrExpression(oKind) || oKind == SyntaxKind.StarToken || oKind == SyntaxKind.BarBarToken)) { return(CheckIfConsumptionIsAllowed(xoContext)); } // Else we have a column list and we just found a core keyword else if (xoContext.CurrentNode.Count >= 1 && bIsCoreStatement) { return(CheckIfConsumptionIsAllowed(xoContext)); } // Else a terminating condition else if (SyntaxKindFacts.IsTerminatingNode(oKind)) { // We want to remove the terminated node and quit xoContext.List.Pop(); return(CanConsumeResult.Complete); } // Clearly we have something we can't consume here else { return(DefaultCanConsumeNext(xoContext)); } }
/// <summary> /// Used by WHERE and ON /// </summary> /// <param name="xoContext.CurrentNode"></param> /// <param name="xoContext.List"></param> /// <returns></returns> private static CanConsumeResult ExpressionCanConsumeNext(ParsingContext xoContext, Boolean xbIsPreconsumption = false) { SyntaxKind eKind = xoContext.List.Peek().ExpectedType; if ( SyntaxKindFacts.IsIdentifierOrExpression(eKind) || // Identifiers and Expressions are allowed here SyntaxKindFacts.IsAdjunctConditionalOperator(eKind) || // AND OR SyntaxKindFacts.IsConditionalOperator(eKind) || // = >= IN SyntaxKindFacts.IsUnaryOperator(eKind) || // NOT SyntaxKindFacts.IsFunction(eKind) || SyntaxKindFacts.IsArithmaticOperator(eKind)) { return(CheckIfConsumptionIsAllowed(xoContext)); } CanConsumeResult eResult = DefaultCanConsumeNext(xoContext); // Post execution check if (eResult == CanConsumeResult.Complete && xoContext.CurrentNode.Count != 1) { ResolutionGenerator.HandleIncompleteNode(xoContext); } return(eResult); }
/// <summary> /// This only really happens with conjunctive operators (ie. +, -, AND, OR..) /// </summary> /// <param name="xoContext.CurrentNode"></param> /// <param name="xoContext.List"></param> public static void HandlePreconsumptionError(ParsingContext xoContext) { // Its good to know whats next SyntaxKind eNextTokenKind = SyntaxKind.UnknownNode; // If we have an arithmatic operator, we know we need the types to match if (SyntaxKindFacts.IsArithmaticOperator(xoContext.CurrentNode.ExpectedType) || SyntaxKindFacts.IsConditionalOperator(xoContext.CurrentNode.ExpectedType)) { // if (SyntaxKindFacts.IsLiteral(xoContext.List.Peek().ExpectedType)) { // Set the return kind eNextTokenKind = xoContext.List.Peek().ExpectedType; } } // Conjunctive or Adjunct will not matter what types we have else if (SyntaxKindFacts.IsAdjunctConditionalOperator(xoContext.CurrentNode.ExpectedType)) { // MUST BE BOOLEAN eNextTokenKind = SyntaxKind.BooleanToken; } // Default to unknown Filler xoContext.CurrentNode.Add( new FillerNode( eNextTokenKind, "Missing (" + SyntaxKindUtilities.GetStringFromKind(eNextTokenKind) + ")")); }
private static CanConsumeResult JoinCanConsumeNext(ParsingContext xoContext, Boolean xbIsPreconsumption = false) { SyntaxKind eKind = xoContext.List.Peek().ExpectedType; if (SyntaxKindFacts.IsIdentifier(eKind) || eKind == SyntaxKind.OpenParenthesisToken || eKind == SyntaxKind.OnKeyword || (xbIsPreconsumption && SyntaxKindFacts.IsJoinKeyword(eKind)) // Allow preconsumption to use JOIN keywods ) { return(CheckIfConsumptionIsAllowed(xoContext)); } // If we got another keyword (that we cant process) else if ( SyntaxKindFacts.IsTerminatingNode(eKind) || SyntaxKindFacts.IsKeyword(eKind) || eKind == SyntaxKind.CloseParenthesisToken) { // Post execution check if (xoContext.CurrentNode.Count != 3) { ResolutionGenerator.HandleIncompleteNode(xoContext); } return(CanConsumeResult.Complete); } CanConsumeResult eResult = DefaultCanConsumeNext(xoContext); return(DefaultCanConsumeNext(xoContext)); }
private static ErrorCode GetExpectedTokenErrorCode(SyntaxKind expected, SyntaxKind actual) { switch (expected) { case SyntaxKind.IdentifierToken: if (SyntaxKindFacts.IsReservedKeyword(actual)) { return(ErrorCode.ERR_IdentifierExpectedKW); // A keyword -- use special message. } else { return(ErrorCode.ERR_IdentifierExpected); } case SyntaxKind.SemicolonToken: return(ErrorCode.ERR_SemicolonExpected); // case TokenKind::Colon: iError = ERR_ColonExpected; break; // case TokenKind::OpenParen: iError = ERR_LparenExpected; break; case SyntaxKind.CloseParenToken: return(ErrorCode.ERR_CloseParenExpected); case SyntaxKind.OpenBraceToken: return(ErrorCode.ERR_LbraceExpected); case SyntaxKind.CloseBraceToken: return(ErrorCode.ERR_RbraceExpected); // case TokenKind::CloseSquare: iError = ERR_CloseSquareExpected; break; default: return(ErrorCode.ERR_SyntaxError); } }
private ExpressionSyntax ParsePostFixExpression(ExpressionSyntax expr) { Debug.Assert(expr != null); while (true) { SyntaxKind tk = this.CurrentToken.Kind; switch (tk) { case SyntaxKind.OpenParenToken: expr = _syntaxFactory.InvocationExpression(expr, this.ParseParenthesizedArgumentList()); break; case SyntaxKind.OpenBracketToken: expr = _syntaxFactory.ElementAccessExpression(expr, this.ParseBracketedArgumentList()); break; case SyntaxKind.PlusPlusToken: case SyntaxKind.MinusMinusToken: expr = _syntaxFactory.PostfixUnaryExpression(SyntaxKindFacts.GetPostfixUnaryExpression(tk), expr, this.EatToken()); break; case SyntaxKind.ColonColonToken: if (this.PeekToken(1).Kind == SyntaxKind.IdentifierToken) { // replace :: with missing dot and annotate with skipped text "::" and error var ccToken = this.EatToken(); ccToken = this.AddError(ccToken, ErrorCode.ERR_UnexpectedAliasedName); var dotToken = this.ConvertToMissingWithTrailingTrivia(ccToken, SyntaxKind.DotToken); expr = _syntaxFactory.MemberAccessExpression( expr, dotToken, this.ParseSimpleName(NameOptions.InExpression)); } else { // just some random trailing :: ? expr = AddTrailingSkippedSyntax(expr, this.EatTokenWithPrejudice(SyntaxKind.DotToken)); } break; //case SyntaxKind.MinusGreaterThanToken: // expr = _syntaxFactory.MemberAccessExpression(SyntaxKind.PointerMemberAccessExpression, // expr, // this.EatToken(), // this.ParseSimpleName(NameOptions.InExpression)); // break; case SyntaxKind.DotToken: expr = _syntaxFactory.MemberAccessExpression( expr, this.EatToken(SyntaxKind.DotToken), this.ParseSimpleName(NameOptions.InExpression)); break; default: return(expr); } } }
private bool IsPossibleLocalDeclarationStatement(bool allowAnyExpression) { // This method decides whether to parse a statement as a declaration or as an expression statement. // In the old compiler it would simple call IsLocalDeclaration. var tk = this.CurrentToken.Kind; if ((SyntaxKindFacts.IsPredefinedType(tk) && this.PeekToken(1).Kind != SyntaxKind.DotToken) || IsDeclarationModifier(tk)) { return(true); } bool?typedIdentifier = IsPossibleTypedIdentifierStart(this.CurrentToken, this.PeekToken(1), allowThisKeyword: false); if (typedIdentifier != null) { return(typedIdentifier.Value); } var resetPoint = this.GetResetPoint(); try { ScanTypeFlags st = this.ScanType(); // We could always return true for st == AliasQualName in addition to MustBeType on the first line, however, we want it to return false in the case where // CurrentToken.Kind != SyntaxKind.Identifier so that error cases, like: A::N(), are not parsed as variable declarations and instead are parsed as A.N() where we can give // a better error message saying "did you meant to use a '.'?" if (st == ScanTypeFlags.MustBeType && this.CurrentToken.Kind != SyntaxKind.DotToken) { return(true); } if (st == ScanTypeFlags.NotType || this.CurrentToken.Kind != SyntaxKind.IdentifierToken) { return(false); } // T? and T* might start an expression, we need to parse further to disambiguate: if (allowAnyExpression) { if (st == ScanTypeFlags.PointerOrMultiplication) { return(false); } else if (st == ScanTypeFlags.NullableType) { return(IsPossibleDeclarationStatementFollowingNullableType()); } } return(true); } finally { this.Reset(ref resetPoint); this.Release(ref resetPoint); } }
private static Boolean EligibleColumnSymbol(SyntaxKind xeKind) { return (SyntaxKindFacts.IsIdentifierOrExpression(xeKind) || SyntaxKindFacts.IsFunction(xeKind) || xeKind == SyntaxKind.StarToken || xeKind == SyntaxKind.BarBarToken || SyntaxKindFacts.IsArithmaticOperator(xeKind)); }
private TypeSyntax ParseClassType() { var type = this.ParseType(false); if (!SyntaxKindFacts.IsName(type.Kind)) { type = this.AddError(type, ErrorCode.ERR_ClassTypeExpected); } return(type); }
public override string ToString() { if (SyntaxKindFacts.IsIdentifier(Parent.ExpectedType)) { return(base.ToString()); } else { return(base.ToString() + Alias); } }
protected SyntaxToken EatToken(SyntaxKind kind, ErrorCode code, bool reportError = true) { Debug.Assert(SyntaxKindFacts.IsAnyToken(kind)); if (this.CurrentToken.Kind != kind) { return(CreateMissingToken(kind, code, reportError)); } else { return(this.EatToken()); } }
private static bool BinaryTokenNeedsSeparator(SyntaxKind kind) { switch (kind) { case SyntaxKind.DotToken: case SyntaxKind.MinusGreaterThanToken: return(false); default: return(SyntaxKindFacts.GetBinaryExpression(kind) != SyntaxKind.None); } }
internal static SyntaxToken Token(CSharpSyntaxNode leading, SyntaxKind kind, string text, string valueText, CSharpSyntaxNode trailing) { Debug.Assert(SyntaxKindFacts.IsAnyToken(kind)); Debug.Assert(kind != SyntaxKind.IdentifierToken); Debug.Assert(kind != SyntaxKind.CharacterLiteralToken); Debug.Assert(kind != SyntaxKind.NumericLiteralToken); string defaultText = SyntaxKindFacts.GetText(kind); return(kind >= SyntaxToken.FirstTokenWithWellKnownText && kind <= SyntaxToken.LastTokenWithWellKnownText && text == defaultText && valueText == defaultText ? Token(leading, kind, trailing) : SyntaxToken.WithValue(kind, leading, text, valueText, trailing)); }
private static CanConsumeResult FromCanConsumeNext(ParsingContext xoContext, Boolean xbIsPreconsumption = false) { SyntaxKind eKind = xoContext.List.Peek().ExpectedType; if (SyntaxKindFacts.IsIdentifier(eKind) || eKind == SyntaxKind.OpenParenthesisToken || SyntaxKindFacts.IsJoinKeyword(eKind)) { return(CheckIfConsumptionIsAllowed(xoContext)); } return(DefaultCanConsumeNext(xoContext)); }
protected SyntaxToken EatTokenWithPrejudice(SyntaxKind kind) { var token = this.CurrentToken; Debug.Assert(SyntaxKindFacts.IsAnyToken(kind)); if (token.Kind != kind) { token = WithAdditionalDiagnostics(token, this.GetExpectedTokenError(kind, token.Kind)); } this.MoveToNextToken(); return(token); }
protected virtual SyntaxDiagnosticInfo GetExpectedTokenError(SyntaxKind expected, SyntaxKind actual, int offset, int width) { var code = GetExpectedTokenErrorCode(expected, actual); if (code == ErrorCode.ERR_SyntaxError || code == ErrorCode.ERR_IdentifierExpectedKW) { return(new SyntaxDiagnosticInfo(offset, width, code, SyntaxKindFacts.GetText(expected), SyntaxKindFacts.GetText(actual))); } else { return(new SyntaxDiagnosticInfo(offset, width, code)); } }
/// <summary> /// Generates a Column Symbol (Used everywhere else) /// </summary> /// <param name="xoCurrentToken"></param> /// <param name="xoList"></param> /// <returns></returns> private static SyntaxNode FactoryCreateColumn(ParsingContext xoContext, Boolean xbIsAliasNeeded = false) { ISyntax xoCurrentToken = xoContext.List.Peek(); // A Symbol consists of multiple parts Symbol oTable; Symbol oColumn; // If this is a literal Column if (SyntaxKindFacts.IsLiteral(xoCurrentToken.ExpectedType)) { oColumn = new Symbol(xoContext.List.Pop(), NodeStrategyFactory.NULL_STRATEGY); // Assign the alias if (xbIsAliasNeeded) { oColumn.Alias = SyntaxNodeFactory.ScanAheadForAlias(xoContext.List); } return(oColumn); } // Trailing item is . (table.column) if (xoContext.List.Peek(1).ExpectedType == SyntaxKind.DotToken) { oTable = new Symbol(xoCurrentToken, NodeStrategyFactory.NULL_STRATEGY); oColumn = new Symbol(xoContext.List.Peek(2)); // Grab the Column oTable.Add(oColumn); xoContext.List.Pop(3); // Skip over the next 2 } // Standalone Column else { oTable = new Symbol(new SyntaxToken(SyntaxKind.IdentifierTableSymbol, String.Empty)); oColumn = new Symbol(xoCurrentToken, NodeStrategyFactory.NULL_STRATEGY); // Grab the Column oTable.Add(oColumn); xoContext.List.Pop(); // Skip over the next 1 } // Assign the alias if (xbIsAliasNeeded) { oColumn.Alias = SyntaxNodeFactory.ScanAheadForAlias(xoContext.List); } oColumn.ExpectedType = SyntaxKind.IdentifierColumnSymbol; oTable.ExpectedType = SyntaxKind.IdentifierTableSymbol; // Return the top level node return(oTable); }
private static CanConsumeResult BinaryExpressionCanConsumeNext(ParsingContext xoContext, Boolean xbIsPreconsumption = false) { // Intermediate var SyntaxKind eKind = xoContext.List.Peek().ExpectedType; // If we have something we are actually allowed to consume if ((xbIsPreconsumption && SyntaxKindFacts.IsAdjunctConditionalOperator(eKind)) || // Allow AND/OR in preconsump SyntaxKindFacts.IsIdentifierOrExpression(eKind) || // Identifiers and Expressions are allowed here SyntaxKindFacts.IsConditionalOperator(eKind) || // = >= IN SyntaxKindFacts.IsUnaryOperator(eKind) || // NOT SyntaxKindFacts.IsArithmaticOperator(eKind)) { CanConsumeResult eResult = CheckIfConsumptionIsAllowed(xoContext); switch (eResult) { // Possible erroroneous case CanConsumeResult.Unknown: // Definitely finished case CanConsumeResult.Complete: // Perform final checks break; // Break immediately case CanConsumeResult.Skip: case CanConsumeResult.Consume: return(eResult); } } // Closing condition if (xoContext.CurrentNode.IsFull() || SyntaxKindFacts.IsTerminatingNode(eKind) || SyntaxKindFacts.IsKeyword(eKind) || eKind == SyntaxKind.CloseParenthesisToken) { // Post execution check if (xoContext.CurrentNode.Count != 2) { ResolutionGenerator.HandleIncompleteNode(xoContext); } return(CanConsumeResult.Complete); } // return(DefaultCanConsumeNext(xoContext)); }
protected SyntaxToken EatContextualToken(SyntaxKind kind, bool reportError = true) { Debug.Assert(SyntaxKindFacts.IsAnyToken(kind)); var contextualKind = this.CurrentToken.ContextualKind; if (contextualKind != kind) { return(CreateMissingToken(kind, contextualKind, reportError)); } else { return(ConvertToKeyword(this.EatToken())); } }
//this method is called very frequently //we should keep it simple so that it can be inlined. protected SyntaxToken EatToken(SyntaxKind kind) { Debug.Assert(SyntaxKindFacts.IsAnyToken(kind)); var ct = this.CurrentToken; if (ct.Kind == kind) { MoveToNextToken(); return(ct); } //slow part of EatToken(SyntaxKind kind) return(CreateMissingToken(kind, this.CurrentToken.Kind, reportError: true)); }
private static Boolean SelectIsValid(ParsingContext xoContext) { // Break early if (xoContext.CurrentNode == null || xoContext.CurrentNode.Count == 0) { return(false); } // Check Children are valid SyntaxNode oColumnList = xoContext.CurrentNode.FindFirst(SyntaxKind.ColumnListNode); // 0. Cant have an empty column list if (oColumnList == null || oColumnList.Count == 0) { // FAIL return(false); } // 1. If we found an identifier if (oColumnList.Exists( (oNode) => SyntaxKindFacts.IsIdentifier(oNode.ExpectedType) )) { // Does the select node have a from? if (xoContext.CurrentNode.FindFirst(SyntaxKind.FromKeyword) == null) { // FAIL return(false); } } // 2. if we find an aggregate function if (oColumnList.Exists((oNode) => SyntaxKindFacts.IsAggregateFunction(oNode.ExpectedType) )) { // Do we have a Group By and is it correct? if (xoContext.CurrentNode.FindFirst(SyntaxKind.GroupByKeyword) == null) { // fail return(false); } } // default to true return(true); }
// ?? TODO: Move to partial class #region Node Specific Methods #region COMMON /// <summary> /// Generic Table Symbol Creation from an Identifier /// </summary> /// <param name="xoContext.CurrentNode"></param> /// <param name="xoContext.List"></param> /// <returns></returns> private static SyntaxNode TableSymbolConvertToken(ParsingContext xoContext, Boolean xbIsPreconsumption = false) { SyntaxKind eKind = xoContext.List.Peek().ExpectedType; // If we need to perform a context sensitive conversion if (SyntaxKindFacts.IsIdentifier(eKind) || eKind == SyntaxKind.OpenParenthesisToken) { return(SyntaxNodeFactory.FactoryCreateTable(xoContext)); } else { // Everything else return(DefaultTryConsumeNext(xoContext)); } }
/// <summary> /// Returns true if the next node is something this node can interpret /// and returns false if it cannot do anything with the next node /// </summary> /// <param name="xoContext.List"></param> /// <returns></returns> private static CanConsumeResult DefaultCanConsumeNext(ParsingContext xoContext, Boolean xbIsPreconsumption = false) { SyntaxKind eKind = xoContext.List.Peek().ExpectedType; // If we have a Open parenthesis starting node // And we just found a closing Token if (eKind == SyntaxKind.CloseParenthesisToken) { // We have an open paren node, remove the token and close if (NodeIsOpenParenthesis(xoContext.CurrentNode)) { xoContext.List.Pop(); // Helps us get back to the appropriate Node return(CanConsumeResult.Complete); } else { // Scan up to see if there is an open parenthesis. SyntaxNode oOpenParenParent = xoContext.CurrentNode.FindFirstParent( NodeIsOpenParenthesis); if (oOpenParenParent != null) { // Helps us get back to the appropriate Node return(CanConsumeResult.Complete); } else { // Invalid Closing parenthesis here xoContext.CurrentNode.Add(new SkippedNode(xoContext.List.Pop())); // Add as excluded node // keep processing return(CanConsumeResult.Skip); } } } // Terminate if we find an eof of any sort or we are full else if (SyntaxKindFacts.IsTerminatingNode(eKind) || xoContext.CurrentNode.IsFull()) { return(CanConsumeResult.Complete); } else { // Unknown, Missing? return(CanConsumeResult.Unknown); } }
private static CanConsumeResult ConcatCanConsume(ParsingContext xoContext, Boolean xbIsPreconsumption = false) { // Intermediate var SyntaxKind oKind = xoContext.List.Peek().ExpectedType; // Consume immediately if (xoContext.CurrentNode.Count <= 1) { if (SyntaxKindFacts.IsIdentifierOrExpression(oKind)) { return(CanConsumeResult.Consume); } else { ResolutionGenerator.HandleIncompleteNode(xoContext); return(CanConsumeResult.Complete); } } // Get BARBAR, consume next else if (oKind == SyntaxKind.BarBarToken) { // Drop the bar bar and consume the next item xoContext.List.Pop(); if (SyntaxKindFacts.IsIdentifierOrExpression(xoContext.List.Peek().ExpectedType)) { return(CanConsumeResult.Consume); } else { ResolutionGenerator.HandleIncompleteNode(xoContext); return(CanConsumeResult.Complete); } } // Else close this object else { // Post consumption check if (xoContext.CurrentNode.Count <= 1) { ResolutionGenerator.HandleIncompleteNode(xoContext); } return(CanConsumeResult.Complete); } }
private TypeSyntax ParseDeclarationType(bool isConstraint, bool parentIsParameter) { var type = this.ParseType(parentIsParameter); if (type.Kind != SyntaxKind.PredefinedType && !SyntaxKindFacts.IsName(type.Kind)) { if (isConstraint) { type = this.AddError(type, ErrorCode.ERR_BadConstraintType); } else { type = this.AddError(type, ErrorCode.ERR_BadBaseType); } } return(type); }
protected SyntaxToken EatToken(SyntaxKind kind, bool reportError) { if (reportError) { return(EatToken(kind)); } Debug.Assert(SyntaxKindFacts.IsAnyToken(kind)); if (this.CurrentToken.Kind != kind) { // should we eat the current ParseToken's leading trivia? return(SyntaxFactory.MissingToken(kind)); } else { return(this.EatToken()); } }
/// <summary> /// Finish up as soon as we come across a Close Parenthesis /// </summary> /// <param name="xoContext.List"></param> /// <returns></returns> private static CanConsumeResult FunctionCanConsumeNext(ParsingContext xoContext, Boolean xbIsPreconsumption = false) { SyntaxKind eKind = xoContext.List.Peek().ExpectedType; // If we get a closing parenthesis in a function if (eKind == SyntaxKind.CloseParenthesisToken) { // Drop it and complete the Function xoContext.List.Pop(); return(CanConsumeResult.Complete); } else if (SyntaxKindFacts.IsIdentifierOrExpression(eKind) || eKind == SyntaxKind.StarToken) { return(CheckIfConsumptionIsAllowed(xoContext)); } return(DefaultCanConsumeNext(xoContext)); }
private static CanConsumeResult ElseCanConsume(ParsingContext xoContext, Boolean xbIsPreconsumption = false) { SyntaxKind eNextKind = xoContext.List.Peek().ExpectedType; // Any Expression/Identifier if (SyntaxKindFacts.IsIdentifierOrExpression(eNextKind) || // Identifiers and Expressions are allowed here SyntaxKindFacts.IsAdjunctConditionalOperator(eNextKind) || // AND OR SyntaxKindFacts.IsConditionalOperator(eNextKind) || // = >= IN SyntaxKindFacts.IsUnaryOperator(eNextKind) || // NOT SyntaxKindFacts.IsFunction(eNextKind) || SyntaxKindFacts.IsArithmaticOperator(eNextKind)) { return(CanConsumeResult.Consume); } else { return(CanConsumeResult.Complete); } }