private DirectiveTriviaSyntax ParsePragmaDirective(SyntaxToken hash, SyntaxToken pragma, bool 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) { style = this.EatToken(); 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, ids.ToList(), end, isActive)); } else { style = this.EatToken(SyntaxKind.DisableKeyword, ErrorCode.WRN_IllegalPPWarning, reportError: isActive); var end = this.ParseEndOfDirective(ignoreErrors: true, afterPragma: true); return(SyntaxFactory.PragmaWarningDirectiveTrivia(hash, pragma, warning, style, default(SeparatedSyntaxList <ExpressionSyntax>), end, isActive)); } } else if (this.CurrentToken.Kind == SyntaxKind.ChecksumKeyword) { var checksum = this.EatToken(); var file = this.EatToken(SyntaxKind.StringLiteralToken, ErrorCode.WRN_IllegalPPChecksum, reportError: isActive); var guid = this.EatToken(SyntaxKind.StringLiteralToken, ErrorCode.WRN_IllegalPPChecksum, reportError: isActive && !file.IsMissing); if (isActive && !guid.IsMissing) { Guid tmp; if (!Guid.TryParse(guid.ValueText, out tmp)) { guid = this.AddError(guid, ErrorCode.WRN_IllegalPPChecksum); } } var bytes = this.EatToken(SyntaxKind.StringLiteralToken, ErrorCode.WRN_IllegalPPChecksum, reportError: isActive && !guid.IsMissing); if (isActive && !bytes.IsMissing) { if (bytes.ValueText.Length % 2 != 0) { bytes = this.AddError(bytes, ErrorCode.WRN_IllegalPPChecksum); } else { foreach (char c in bytes.ValueText) { if (!SyntaxFacts.IsHexDigit(c)) { bytes = this.AddError(bytes, ErrorCode.WRN_IllegalPPChecksum); break; } } } } hasError = file.ContainsDiagnostics | guid.ContainsDiagnostics | bytes.ContainsDiagnostics; var eod = this.ParseEndOfDirective(ignoreErrors: hasError, afterPragma: true); return(SyntaxFactory.PragmaChecksumDirectiveTrivia(hash, pragma, checksum, file, guid, bytes, eod, isActive)); } else { var warning = this.EatToken(SyntaxKind.WarningKeyword, ErrorCode.WRN_IllegalPragma, reportError: isActive); var style = this.EatToken(SyntaxKind.DisableKeyword, reportError: false); var eod = this.ParseEndOfDirective(ignoreErrors: true, afterPragma: true); return(SyntaxFactory.PragmaWarningDirectiveTrivia(hash, pragma, warning, style, default(SeparatedSyntaxList <ExpressionSyntax>), eod, isActive)); } }
private DirectiveTriviaSyntax ParsePragmaDirective(SyntaxToken hash, SyntaxToken pragma, bool 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) { style = this.EatToken(); var ids = new SeparatedSyntaxListBuilder <ExpressionSyntax>(10); while (this.CurrentToken.Kind != SyntaxKind.EndOfDirectiveToken) { SyntaxToken id; ExpressionSyntax idExpression; if (this.CurrentToken.Kind == SyntaxKind.NumericLiteralToken || this.CurrentToken.Kind == SyntaxKind.StringLiteralToken) { id = this.EatToken(); if (isActive) { if (id.Kind == SyntaxKind.NumericLiteralToken) { int compilerWarningNumber = (int)id.Value; if (ErrorFacts.GetSeverity((ErrorCode)compilerWarningNumber) != DiagnosticSeverity.Warning) { id = this.AddError(id, ErrorCode.WRN_BadWarningNumber, compilerWarningNumber); } } else { string value = (string)id.Value; var messageProvider = MessageProvider.Instance; if (value.StartsWith(messageProvider.CodePrefix)) { // For diagnostic IDs of the form "CS[0-9]*", verify the error code is that of a warning int compilerWarningNumber; if (int.TryParse(value.Substring(messageProvider.CodePrefix.Length), NumberStyles.None, CultureInfo.InvariantCulture, out compilerWarningNumber) && (messageProvider.GetIdForErrorCode(compilerWarningNumber) != value || ErrorFacts.GetSeverity((ErrorCode)compilerWarningNumber) != DiagnosticSeverity.Warning)) { id = this.AddError(id, ErrorCode.WRN_BadWarningNumber, value); } } } } var expressionKind = id.Kind == SyntaxKind.NumericLiteralToken ? SyntaxKind.NumericLiteralExpression : SyntaxKind.StringLiteralExpression; idExpression = SyntaxFactory.LiteralExpression(expressionKind, id); } else { id = this.EatToken(SyntaxKind.NumericLiteralToken, ErrorCode.WRN_StringOrNumericLiteralExpected, 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, ids.ToList(), end, isActive)); } else { style = this.EatToken(SyntaxKind.DisableKeyword, ErrorCode.WRN_IllegalPPWarning, reportError: isActive); var end = this.ParseEndOfDirective(ignoreErrors: true, afterPragma: true); return(SyntaxFactory.PragmaWarningDirectiveTrivia(hash, pragma, warning, style, default(SeparatedSyntaxList <ExpressionSyntax>), end, isActive)); } } else if (this.CurrentToken.Kind == SyntaxKind.ChecksumKeyword) { var checksum = this.EatToken(); var file = this.EatToken(SyntaxKind.StringLiteralToken, ErrorCode.WRN_IllegalPPChecksum, reportError: isActive); var guid = this.EatToken(SyntaxKind.StringLiteralToken, ErrorCode.WRN_IllegalPPChecksum, reportError: isActive && !file.IsMissing); if (isActive && !guid.IsMissing) { Guid tmp; if (!Guid.TryParse(guid.ValueText, out tmp)) { guid = this.AddError(guid, ErrorCode.WRN_IllegalPPChecksum); } } var bytes = this.EatToken(SyntaxKind.StringLiteralToken, ErrorCode.WRN_IllegalPPChecksum, reportError: isActive && !guid.IsMissing); if (isActive && !bytes.IsMissing) { if (bytes.ValueText.Length % 2 != 0) { bytes = this.AddError(bytes, ErrorCode.WRN_IllegalPPChecksum); } else { foreach (char c in bytes.ValueText) { if (!SyntaxFacts.IsHexDigit(c)) { bytes = this.AddError(bytes, ErrorCode.WRN_IllegalPPChecksum); break; } } } } hasError = file.ContainsDiagnostics | guid.ContainsDiagnostics | bytes.ContainsDiagnostics; var eod = this.ParseEndOfDirective(ignoreErrors: hasError, afterPragma: true); return(SyntaxFactory.PragmaChecksumDirectiveTrivia(hash, pragma, checksum, file, guid, bytes, eod, isActive)); } else { var warning = this.EatToken(SyntaxKind.WarningKeyword, ErrorCode.WRN_IllegalPragma, reportError: isActive); var style = this.EatToken(SyntaxKind.DisableKeyword, reportError: false); var eod = this.ParseEndOfDirective(ignoreErrors: true, afterPragma: true); return(SyntaxFactory.PragmaWarningDirectiveTrivia(hash, pragma, warning, style, default(SeparatedSyntaxList <ExpressionSyntax>), eod, isActive)); } }