private DirectiveTriviaSyntax ParsePragmaDirective(SyntaxToken hash, SyntaxToken pragma, bool isActive) { if (isActive) { pragma = CheckFeatureAvailability(pragma, MessageID.IDS_FeaturePragma); } bool hasError = false; if (this.CurrentToken.ContextualKind == SyntaxKind.WarningKeyword) { var warning = this.EatContextualToken(SyntaxKind.WarningKeyword); SyntaxToken style; if (this.CurrentToken.Kind == SyntaxKind.DisableKeyword || this.CurrentToken.Kind == SyntaxKind.RestoreKeyword || this.CurrentToken.Kind == SyntaxKind.EnableKeyword || this.CurrentToken.Kind == SyntaxKind.SafeOnlyKeyword) { style = this.EatToken(); if (isActive && (style.Kind == SyntaxKind.EnableKeyword || style.Kind == SyntaxKind.SafeOnlyKeyword)) { style = CheckFeatureAvailability(style, MessageID.IDS_FeaturePragmaWarningEnableOrSafeOnly, forceWarning: true); } if (this.CurrentToken.ContextualKind == SyntaxKind.NullableKeyword) { SyntaxToken nullable = this.EatContextualToken(SyntaxKind.NullableKeyword); var end = this.ParseEndOfDirective(hasError || !isActive, afterPragma: true); return(SyntaxFactory.PragmaWarningDirectiveTrivia(hash, pragma, warning, style, nullableKeyword: nullable, default(SeparatedSyntaxList <ExpressionSyntax>), end, isActive)); } else if (style.Kind == SyntaxKind.SafeOnlyKeyword) { SyntaxToken nullable = this.EatToken(SyntaxKind.NullableKeyword, ErrorCode.WRN_IllegalPPWarningSafeOnly, reportError: isActive); var end = this.ParseEndOfDirective(ignoreErrors: true, afterPragma: true); return(SyntaxFactory.PragmaWarningDirectiveTrivia(hash, pragma, warning, style, nullableKeyword: nullable, default(SeparatedSyntaxList <ExpressionSyntax>), end, isActive)); } else { var ids = new SeparatedSyntaxListBuilder <ExpressionSyntax>(10); while (this.CurrentToken.Kind != SyntaxKind.EndOfDirectiveToken) { SyntaxToken id; ExpressionSyntax idExpression; if (this.CurrentToken.Kind == SyntaxKind.NumericLiteralToken) { // Previous versions of the compiler used to report a warning (CS1691) // whenever an unrecognized warning code was supplied in a #pragma directive // (or via /nowarn /warnaserror flags on the command line). // Going forward, we won't generate any warning in such cases. This will make // maintenance of backwards compatibility easier (we no longer need to worry // about breaking existing projects / command lines if we deprecate / remove // an old warning code). id = this.EatToken(); idExpression = SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, id); } else if (this.CurrentToken.Kind == SyntaxKind.IdentifierToken) { // Lexing / parsing of identifiers inside #pragma warning directives is identical // to that inside #define directives except that very long identifiers inside #define // are truncated to 128 characters to maintain backwards compatibility with previous // versions of the compiler. (See TruncateIdentifier() below.) // Since support for identifiers inside #pragma warning directives is new, // we don't have any backwards compatibility constraints. So we can preserve the // identifier exactly as it appears in source. id = this.EatToken(); idExpression = SyntaxFactory.IdentifierName(id); } else { id = this.EatToken(SyntaxKind.NumericLiteralToken, ErrorCode.WRN_IdentifierOrNumericLiteralExpected, reportError: isActive); idExpression = SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, id); } hasError = hasError || id.ContainsDiagnostics; ids.Add(idExpression); if (this.CurrentToken.Kind != SyntaxKind.CommaToken) { break; } ids.AddSeparator(this.EatToken()); } var end = this.ParseEndOfDirective(hasError || !isActive, afterPragma: true); return(SyntaxFactory.PragmaWarningDirectiveTrivia(hash, pragma, warning, style, nullableKeyword: default, ids.ToList(), end, isActive));