Beispiel #1
0
        private SyntaxToken ParseEndOfDirective(bool ignoreErrors, bool afterPragma = false, bool afterLineNumber = false)
        {
            var skippedTokens = new SyntaxListBuilder(10);

            // Consume all extraneous tokens as leading SkippedTokens trivia.
            if (this.CurrentToken.Kind != SyntaxKind.EndOfDirectiveToken &&
                this.CurrentToken.Kind != SyntaxKind.EndOfFileToken)
            {
                skippedTokens = new SyntaxListBuilder(10);

                if (!ignoreErrors)
                {
                    var errorCode = ErrorCode.ERR_EndOfPPLineExpected;
                    if (afterPragma)
                    {
                        errorCode = ErrorCode.WRN_EndOfPPLineExpected;
                    }
                    else if (afterLineNumber)
                    {
                        errorCode = ErrorCode.ERR_MissingPPFile;
                    }

                    skippedTokens.Add(this.AddError(this.EatToken(), errorCode));
                }

                while (this.CurrentToken.Kind != SyntaxKind.EndOfDirectiveToken &&
                       this.CurrentToken.Kind != SyntaxKind.EndOfFileToken)
                {
                    skippedTokens.Add(this.EatToken());
                }
            }

            // attach text from extraneous tokens as trivia to EndOfDirective token
            SyntaxToken endOfDirective = this.CurrentToken.Kind == SyntaxKind.EndOfDirectiveToken
                                                                                 ? this.EatToken()
                                                                                 : SyntaxFactory.Token(SyntaxKind.EndOfDirectiveToken);

            if (skippedTokens.Count > 0)
            {
                //endOfDirective = endOfDirective.TokenWithLeadingTrivia(
                //	SyntaxFactory.SkippedTokensTrivia(skippedTokens.ToList()));
            }

            return(endOfDirective);
        }
Beispiel #2
0
 public SeparatedSyntaxListBuilder <TNode> Add(TNode node)
 {
     _builder.Add(node);
     return(this);
 }
Beispiel #3
0
        private DirectiveTriviaSyntax ParsePragmaDirective(SyntaxToken hash, SyntaxToken pragma, bool isActive)
        {
            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 (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, nullable, default(SyntaxList <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, nullable, default(SyntaxList <ExpressionSyntax>), end, isActive));
                    }
                    else
                    {
                        var ids = new SyntaxListBuilder(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.Add(this.EatToken());
                        }

                        var end = this.ParseEndOfDirective(hasError || !isActive, afterPragma: true);
                        return(SyntaxFactory.PragmaWarningDirectiveTrivia(hash, pragma, warning, style, null, 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, null, default(SyntaxList <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.GetValueText(), 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.GetValueText().Length % 2 != 0)
                    {
                        bytes = this.AddError(bytes, ErrorCode.WRN_IllegalPPChecksum);
                    }
                    else
                    {
                        foreach (char c in bytes.GetValueText())
                        {
                            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, null, default(SyntaxList <ExpressionSyntax>), eod, isActive));
            }
        }