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)); } }
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 void ParseParameterModifiers(SyntaxListBuilder modifiers, bool allowThisKeyword, bool allowFieldModifiers) { var flags = ParamFlags.None; SyntaxModifier fieldMods = 0; bool seenNoDuplicates = true; bool seenNoAccessibilityDuplicates = true; while (true) { if (IsParameterModifier(this.CurrentToken.Kind, allowThisKeyword)) { var mod = this.EatToken(); if (mod.Kind == SyntaxKind.ThisKeyword) { if (mod.Kind == SyntaxKind.ThisKeyword) { mod = CheckFeatureAvailability(mod, MessageID.IDS_FeatureExtensionMethod); if ((flags & ParamFlags.This) != 0) { mod = this.AddError(mod, ErrorCode.ERR_DupParamMod, SyntaxKindFacts.GetText(SyntaxKind.ThisKeyword)); } else if ((flags & ParamFlags.Params) != 0) { mod = this.AddError(mod, ErrorCode.ERR_BadParamModThis); } else { flags |= ParamFlags.This; } } if (mod.Kind == SyntaxKind.FinalKeyword) { flags |= ParamFlags.Final; } //else if (mod.Kind == SyntaxKind.ParamsKeyword) //{ // if ((flags & ParamFlags.Params) != 0) // { // mod = this.AddError(mod, ErrorCode.ERR_DupParamMod, SyntaxKindFacts.GetText(SyntaxKind.ParamsKeyword)); // } // else if ((flags & ParamFlags.This) != 0) // { // mod = this.AddError(mod, ErrorCode.ERR_BadParamModThis); // } // else if ((flags & (ParamFlags.Ref | ParamFlags.Out | ParamFlags.This)) != 0) // { // mod = this.AddError(mod, ErrorCode.ERR_MultiParamMod); // } // else // { // flags |= ParamFlags.Params; // } //} } modifiers.Add(mod); continue; } if (allowFieldModifiers) { var newFieldMod = GetFieldModifier(this.CurrentToken); if (newFieldMod != SyntaxModifier.None) { var modTok = this.EatToken(); if (newFieldMod == SyntaxModifier.Static) { if ((fieldMods & SyntaxModifier.Static) == 0) { modTok = this.AddError(modTok, ErrorCode.ERR_StaticParamMod); } } else { ReportDuplicateModifiers(ref modTok, newFieldMod, fieldMods, ref seenNoDuplicates, ref seenNoAccessibilityDuplicates); } fieldMods |= newFieldMod; modifiers.Add(modTok); continue; } } break; } if (fieldMods != 0 && fieldMods != SyntaxModifier.Static && ((fieldMods & AccessModifiers) == 0)) { for (int i = 0; i < modifiers.Count; i++) { var mod = GetFieldModifier((SyntaxToken)modifiers[i]); if (mod != SyntaxModifier.None && mod != SyntaxModifier.Static) { Debug.Assert((fieldMods & AccessModifiers) == 0); if ((fieldMods & AccessModifiers) == 0) { modifiers[i] = this.AddError(modifiers[i], ErrorCode.ERR_ParamMissingAccessMod); } break; } } } }
private void ReportDuplicateModifiers(ref SyntaxToken modTok, SyntaxModifier newMod, SyntaxModifier mods, ref bool seenNoDuplicates, ref bool seenNoAccessibilityDuplicates) { if ((mods & newMod) != 0) { if (seenNoDuplicates) { modTok = this.AddError(modTok, ErrorCode.ERR_DuplicateModifier, SyntaxKindFacts.GetText(modTok.Kind)); seenNoDuplicates = false; } } else { if ((mods & AccessModifiers) != 0 && (newMod & AccessModifiers) != 0) { if (seenNoAccessibilityDuplicates) { modTok = this.AddError(modTok, ErrorCode.ERR_BadMemberProtection); } seenNoAccessibilityDuplicates = false; } } }
private ExpressionSyntax ParseSubExpression(uint precedence, bool allowDeclarationExpressionAtTheBeginning = true, bool contextRequiresVariable = false) { ExpressionSyntax leftOperand = null; uint newPrecedence = 0; SyntaxKind opKind = SyntaxKind.None; // all of these are tokens that start statements and are invalid // to start a expression with. if we see one, then we must have // something like: // // return // if (... // parse out a missing name node for the expression, and keep on going var tk = this.CurrentToken.Kind; if (IsInvalidSubExpression(tk)) { return(this.AddError(this.CreateMissingIdentifierName(), ErrorCode.ERR_InvalidExprTerm, SyntaxKindFacts.GetText(tk))); } // No left operand, so we need to parse one -- possibly preceded by a // unary operator. if (IsExpectedPrefixUnaryOperator(tk)) { opKind = SyntaxKindFacts.GetPrefixUnaryExpression(tk); newPrecedence = GetPrecedence(opKind); var opToken = this.EatToken(); var operand = this.ParseSubExpression(newPrecedence); leftOperand = _syntaxFactory.PrefixUnaryExpression(opKind, opToken, operand); } else { // Not a unary operator - get a primary expression. leftOperand = this.ParseTerm(precedence, allowDeclarationExpressionAtTheBeginning, contextRequiresVariable); } while (true) { // We either have a binary operator here, or we're finished. tk = this.CurrentToken.Kind; if (!IsExpectedBinaryOperator(tk)) { break; } opKind = SyntaxKindFacts.GetBinaryExpression(tk); newPrecedence = GetPrecedence(opKind); Debug.Assert(newPrecedence > 0); // All binary operators must have precedence > 0! // check for >> or >>= or >>> or >>>= bool doubleOp = false; bool doubleOpPlusOne = false; if (tk == SyntaxKind.GreaterThanToken && (this.PeekToken(1).Kind == SyntaxKind.GreaterThanToken) && (this.PeekToken(2).Kind == SyntaxKind.GreaterThanToken || this.PeekToken(2).Kind == SyntaxKind.GreaterThanEqualsToken)) { // check to see if they really are adjacent if (this.CurrentToken.GetTrailingTriviaWidth() == 0 && this.PeekToken(1).GetLeadingTriviaWidth() == 0 && this.PeekToken(1).GetTrailingTriviaWidth() == 0 && this.PeekToken(2).GetLeadingTriviaWidth() == 0 ) { opKind = SyntaxKindFacts.GetBinaryExpression(this.PeekToken(2).Kind == SyntaxKind.GreaterThanToken ? SyntaxKind.GreaterThanGreaterThanGreaterThanToken : SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken); newPrecedence = GetPrecedence(opKind); doubleOp = true; doubleOpPlusOne = true; } } else if (tk == SyntaxKind.GreaterThanToken && (this.PeekToken(1).Kind == SyntaxKind.GreaterThanToken || this.PeekToken(1).Kind == SyntaxKind.GreaterThanEqualsToken)) { // check to see if they really are adjacent if (this.CurrentToken.GetTrailingTriviaWidth() == 0 && this.PeekToken(1).GetLeadingTriviaWidth() == 0) { opKind = SyntaxKindFacts.GetBinaryExpression(this.PeekToken(1).Kind == SyntaxKind.GreaterThanToken ? SyntaxKind.GreaterThanGreaterThanToken : SyntaxKind.GreaterThanGreaterThanEqualsToken); newPrecedence = GetPrecedence(opKind); doubleOp = true; } } // Check the precedence to see if we should "take" this operator if (newPrecedence < precedence) { break; } // Same precedence, but not right-associative -- deal with this "later" if ((newPrecedence == precedence) && !IsRightAssociative(opKind)) { break; } // Precedence is okay, so we'll "take" this operator. var opToken = this.EatToken(); if (doubleOp) { // combine tokens into a single token var opToken2 = this.EatToken(); if (doubleOpPlusOne) { var opToken3 = this.EatToken(); var kind = opToken3.Kind == SyntaxKind.GreaterThanToken ? SyntaxKind.GreaterThanGreaterThanGreaterThanToken : SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken; opToken = SyntaxFactory.Token(opToken.GetLeadingTrivia(), kind, opToken3.GetTrailingTrivia()); } else { var kind = opToken2.Kind == SyntaxKind.GreaterThanToken ? SyntaxKind.GreaterThanGreaterThanToken : SyntaxKind.GreaterThanGreaterThanEqualsToken; opToken = SyntaxFactory.Token(opToken.GetLeadingTrivia(), kind, opToken2.GetTrailingTrivia()); } } if (opKind == SyntaxKind.InstanceOfExpression) { leftOperand = _syntaxFactory.BinaryExpression(opKind, leftOperand, opToken, this.ParseTypeCore(parentIsParameter: false, isInstanceOfOrAs: true, expectSizes: false, isArrayCreation: false)); } else { leftOperand = _syntaxFactory.BinaryExpression(opKind, leftOperand, opToken, this.ParseSubExpression(newPrecedence)); } } // From the language spec: // // conditional-expression: // null-coalescing-expression // null-coalescing-expression ? expression : expression // // Only take the ternary if we're at a precedence less than the null coelescing // expression. var nullCoalescingPrecedence = 2U; //GetPrecedence(SyntaxKind.CoalesceExpression); if (tk == SyntaxKind.QuestionToken && precedence < 2) { var questionToken = this.EatToken(); var colonLeft = this.ParseSubExpression(nullCoalescingPrecedence - 1); var colon = this.EatToken(SyntaxKind.ColonToken); var colonRight = this.ParseSubExpression(nullCoalescingPrecedence - 1); leftOperand = _syntaxFactory.ConditionalExpression(leftOperand, questionToken, colonLeft, colon, colonRight); } return(leftOperand); }
private ExpressionSyntax ParseTerm(uint precedence, bool allowDeclarationExpression, bool contextRequiresVariable) { ExpressionSyntax expr = null; var tk = this.CurrentToken.Kind; if (SyntaxKindFacts.IsPredefinedType(tk) && allowDeclarationExpression && this.PeekToken(1).Kind == SyntaxKind.DotToken && this.PeekToken(2).Kind == SyntaxKind.ClassKeyword) { expr = ParseClassLiteralExpression(); } else { switch (tk) { case SyntaxKind.DefaultKeyword: expr = this.ParseDefaultExpression(); break; case SyntaxKind.ColonColonToken: // misplaced :: // TODO: this should not be a compound name.. (disallow dots) expr = this.ParseQualifiedName(NameOptions.InExpression); break; case SyntaxKind.IdentifierToken: if (this.IsTrueIdentifier()) { if (this.IsPossibleLambdaExpression(precedence)) { expr = this.ParseLambdaExpression(); } else if (allowDeclarationExpression && IsPossibleDeclarationExpression(contextRequiresVariable)) { expr = ParseDeclarationExpression(); } else if (IsPossibleIdentifierDotSuffix(SyntaxKind.ClassKeyword)) { expr = ParseClassLiteralExpression(); } else if (IsPossibleIdentifierDotSuffix(SyntaxKind.ThisKeyword)) { expr = ParseJavaQualifiedThisExpression(); } else if (IsPossibleIdentifierDotSuffix(SyntaxKind.SuperKeyword)) { expr = ParseJavaQualifiedSuperExpression(); } else if (IsPossibleIdentifierDotSuffix(SyntaxKind.NewKeyword)) { expr = this.ParseNewExpression(); } else { expr = this.ParseSimpleName(NameOptions.InExpression); } } else { expr = this.CreateMissingIdentifierName(); expr = this.AddError(expr, ErrorCode.ERR_InvalidExprTerm, this.CurrentToken.Text); } break; case SyntaxKind.ThisKeyword: expr = _syntaxFactory.ThisExpression(this.EatToken()); break; case SyntaxKind.SuperKeyword: expr = _syntaxFactory.BaseExpression(this.EatToken()); break; case SyntaxKind.ArgListKeyword: case SyntaxKind.FalseKeyword: case SyntaxKind.TrueKeyword: case SyntaxKind.NullKeyword: case SyntaxKind.NumericLiteralToken: case SyntaxKind.StringLiteralToken: case SyntaxKind.CharacterLiteralToken: expr = _syntaxFactory.LiteralExpression(SyntaxKindFacts.GetLiteralExpression(tk), this.EatToken()); break; case SyntaxKind.OpenParenToken: expr = this.ParseCastOrParenExpressionOrLambda(precedence, contextRequiresVariable: contextRequiresVariable); break; case SyntaxKind.NewKeyword: expr = this.ParseNewExpression(); break; case SyntaxKind.OpenBraceToken: expr = this.ParseArrayInitializer(); break; case SyntaxKind.AtToken: expr = this.ParseAnnotationCreationExpression(); break; default: // check for intrinsic type followed by '.' if (IsPredefinedType(tk)) { if (allowDeclarationExpression && IsPossibleDeclarationExpression(contextRequiresVariable)) { expr = ParseDeclarationExpression(); } else { expr = _syntaxFactory.PredefinedType(this.EatToken()); if (this.CurrentToken.Kind != SyntaxKind.DotToken || tk == SyntaxKind.VoidKeyword) { expr = this.AddError(expr, ErrorCode.ERR_InvalidExprTerm, SyntaxKindFacts.GetText(tk)); } } } else { expr = this.CreateMissingIdentifierName(); if (tk == SyntaxKind.EndOfFileToken) { expr = this.AddError(expr, ErrorCode.ERR_ExpressionExpected); } else { expr = this.AddError(expr, ErrorCode.ERR_InvalidExprTerm, SyntaxKindFacts.GetText(tk)); } } break; } } return(this.ParsePostFixExpression(expr)); }