예제 #1
0
        private static void CheckParameterModifiers(
            ParameterSyntax parameter, DiagnosticBag diagnostics)
        {
            var seenThis   = false;
            var seenRef    = false;
            var seenOut    = false;
            var seenParams = false;
            var seenIn     = false;

            foreach (var modifier in parameter.Modifiers)
            {
                switch (modifier.Kind())
                {
                case SyntaxKind.ThisKeyword:
                    if (seenThis)
                    {
                        diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ThisKeyword));
                    }
                    else if (seenOut)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ThisKeyword), SyntaxFacts.GetText(SyntaxKind.OutKeyword));
                    }
                    else if (seenParams)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParamModThis, modifier.GetLocation());
                    }
                    else
                    {
                        seenThis = true;
                    }
                    break;

                case SyntaxKind.RefKeyword:
                    if (seenRef)
                    {
                        diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.RefKeyword));
                    }
                    else if (seenParams)
                    {
                        diagnostics.Add(ErrorCode.ERR_ParamsCantBeWithModifier, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.RefKeyword));
                    }
                    else if (seenOut)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.RefKeyword), SyntaxFacts.GetText(SyntaxKind.OutKeyword));
                    }
                    else if (seenIn)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.RefKeyword), SyntaxFacts.GetText(SyntaxKind.InKeyword));
                    }
                    else
                    {
                        seenRef = true;
                    }
                    break;

                case SyntaxKind.OutKeyword:
                    if (seenOut)
                    {
                        diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword));
                    }
                    else if (seenThis)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword), SyntaxFacts.GetText(SyntaxKind.ThisKeyword));
                    }
                    else if (seenParams)
                    {
                        diagnostics.Add(ErrorCode.ERR_ParamsCantBeWithModifier, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword));
                    }
                    else if (seenRef)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword), SyntaxFacts.GetText(SyntaxKind.RefKeyword));
                    }
                    else if (seenIn)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword), SyntaxFacts.GetText(SyntaxKind.InKeyword));
                    }
                    else
                    {
                        seenOut = true;
                    }
                    break;

                case SyntaxKind.ParamsKeyword:
                    if (seenParams)
                    {
                        diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ParamsKeyword));
                    }
                    else if (seenThis)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParamModThis, modifier.GetLocation());
                    }
                    else if (seenRef)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ParamsKeyword), SyntaxFacts.GetText(SyntaxKind.RefKeyword));
                    }
                    else if (seenIn)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ParamsKeyword), SyntaxFacts.GetText(SyntaxKind.InKeyword));
                    }
                    else if (seenOut)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ParamsKeyword), SyntaxFacts.GetText(SyntaxKind.OutKeyword));
                    }
                    else
                    {
                        seenParams = true;
                    }
                    break;

                case SyntaxKind.InKeyword:
                    if (seenIn)
                    {
                        diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword));
                    }
                    else if (seenOut)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword), SyntaxFacts.GetText(SyntaxKind.OutKeyword));
                    }
                    else if (seenRef)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword), SyntaxFacts.GetText(SyntaxKind.RefKeyword));
                    }
                    else if (seenParams)
                    {
                        diagnostics.Add(ErrorCode.ERR_ParamsCantBeWithModifier, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword));
                    }
                    else
                    {
                        seenIn = true;
                    }
                    break;

                default:
                    throw ExceptionUtilities.UnexpectedValue(modifier.Kind());
                }
            }
        }
예제 #2
0
        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, SyntaxFacts.GetText(expected), SyntaxFacts.GetText(actual)));
            }
            else
            {
                return(new SyntaxDiagnosticInfo(offset, width, code));
            }
        }
 public static bool HasMatchingText(this SyntaxToken token, SyntaxKind kind)
 => token.ToString() == SyntaxFacts.GetText(kind);
예제 #4
0
        public void AnalyzeNode(SyntaxNodeAnalysisContext context)
        {
            var statement         = context.Node;
            var cancellationToken = context.CancellationToken;

            var optionSet = context.Options.GetDocumentOptionSetAsync(statement.SyntaxTree, cancellationToken).GetAwaiter().GetResult();

            if (optionSet == null)
            {
                return;
            }

            var option = optionSet.GetOption(CSharpCodeStyleOptions.PreferBraces);

            if (option.Value == PreferBracesPreference.None)
            {
                return;
            }

            var embeddedStatement = statement.GetEmbeddedStatement();

            switch (embeddedStatement.Kind())
            {
            case SyntaxKind.Block:
                // The embedded statement already has braces, which is always allowed.
                return;

            case SyntaxKind.IfStatement when statement.Kind() == SyntaxKind.ElseClause:
                // Constructs like the following are always allowed:
                //
                //   if (something)
                //   {
                //   }
                //   else if (somethingElse) // <-- 'if' nested in an 'else' clause
                //   {
                //   }
                return;

            case SyntaxKind.LockStatement:
            case SyntaxKind.UsingStatement:
            case SyntaxKind.FixedStatement:
                // If we have something like this:
                //
                //    using (...)
                //    using (...)
                //    {
                //    }
                //
                // The first statement needs no block as it formatted with the same indentation.
                if (statement.Kind() == embeddedStatement.Kind())
                {
                    return;
                }

                break;
            }

            if (option.Value == PreferBracesPreference.WhenMultiline &&
                !IsConsideredMultiLine(statement, embeddedStatement) &&
                !RequiresBracesToMatchContext(statement))
            {
                return;
            }

            if (ContainsInterleavedDirective(statement, embeddedStatement, cancellationToken))
            {
                return;
            }

            var firstToken = statement.GetFirstToken();

            context.ReportDiagnostic(DiagnosticHelper.Create(
                                         Descriptor,
                                         firstToken.GetLocation(),
                                         option.Notification.Severity,
                                         additionalLocations: null,
                                         properties: null,
                                         SyntaxFacts.GetText(firstToken.Kind())));
        }
예제 #5
0
 protected static SymbolDisplayPart Punctuation(SyntaxKind kind)
 {
     return(new SymbolDisplayPart(SymbolDisplayPartKind.Punctuation, null, SyntaxFacts.GetText(kind)));
 }
예제 #6
0
        public void Parser_BinaryExpression_HonorsPrecedences(SyntaxKind op1, SyntaxKind op2)
        {
            var op1Precedence = SyntaxFacts.GetBinaryOperatorPrecedence(op1);
            var op2Precedence = SyntaxFacts.GetBinaryOperatorPrecedence(op2);
            var op1Text       = SyntaxFacts.GetText(op1);
            var op2Text       = SyntaxFacts.GetText(op2);
            var text          = $"a {op1Text} b {op2Text} c";
            var expression    = SyntaxTree.Parse(text).Root;

            if (op1Precedence >= op2Precedence)
            {
                //     op2
                //    /   \
                //   op1   c
                //  /   \
                // a     b

                using (var e = new AssertingEnumerator(expression))
                {
                    e.AssertNode(SyntaxKind.BinaryExpression);
                    e.AssertNode(SyntaxKind.BinaryExpression);

                    e.AssertNode(SyntaxKind.NameExpression);
                    e.AssertToken(SyntaxKind.IdentifierToken, "a");

                    e.AssertToken(op1, op1Text);

                    e.AssertNode(SyntaxKind.NameExpression);
                    e.AssertToken(SyntaxKind.IdentifierToken, "b");

                    e.AssertToken(op2, op2Text);

                    e.AssertNode(SyntaxKind.NameExpression);
                    e.AssertToken(SyntaxKind.IdentifierToken, "c");
                }
            }
            else
            {
                //   op1
                //  /   \
                // a    op2
                //     /   \
                //    b     c

                using (var e = new AssertingEnumerator(expression))
                {
                    e.AssertNode(SyntaxKind.BinaryExpression);

                    e.AssertNode(SyntaxKind.NameExpression);
                    e.AssertToken(SyntaxKind.IdentifierToken, "a");

                    e.AssertToken(op1, op1Text);

                    e.AssertNode(SyntaxKind.BinaryExpression);

                    e.AssertNode(SyntaxKind.NameExpression);
                    e.AssertToken(SyntaxKind.IdentifierToken, "b");

                    e.AssertToken(op2, op2Text);

                    e.AssertNode(SyntaxKind.NameExpression);
                    e.AssertToken(SyntaxKind.IdentifierToken, "c");
                }
            }
        }
예제 #7
0
 private void BuildVisibility(CodeFileTokensBuilder builder, ISymbol symbol)
 {
     builder.Keyword(SyntaxFacts.GetText(ToEffectiveAccessibility(symbol.DeclaredAccessibility)));
 }
        public static bool IsInNameofCall(this ExpressionSyntax expression)
        {
            var argumentList     = (expression.Parent as ArgumentSyntax)?.Parent as ArgumentListSyntax;
            var nameofCall       = argumentList?.Parent as InvocationExpressionSyntax;
            var nameofIdentifier = (nameofCall?.Expression as IdentifierNameSyntax)?.Identifier;

            return(nameofIdentifier.HasValue &&
                   (nameofIdentifier.Value.IsKind(SyntaxKind.NameOfKeyword) || (nameofIdentifier.Value.ToString() == SyntaxFacts.GetText(SyntaxKind.NameOfKeyword))));
        }
 protected override string GetOperatorText(SyntaxKind binaryExprKind)
 => binaryExprKind == SyntaxKind.LogicalAndExpression
         ? SyntaxFacts.GetText(SyntaxKind.AmpersandAmpersandToken)
         : SyntaxFacts.GetText(SyntaxKind.BarBarToken);
예제 #10
0
        private SyntaxFactoryWriter Write(SyntaxToken token)
        {
            if (token.Kind() == SyntaxKind.None)
            {
                this.writer.Append("default");
                return(this);
            }

            switch (token.Kind())
            {
            case SyntaxKind.BadToken:
                return(this.AppendLine("SyntaxFactory.BadToken(")
                       .PushIndent()
                       .WriteArgument("leading", token.LeadingTrivia)
                       .WriteArgument("text", token.Text)
                       .WriteArgument("trailing", token.TrailingTrivia, closeArgumentList: true)
                       .PopIndent());

            case SyntaxKind.IdentifierToken:
                if (token.IsContextualKeyword())
                {
                    return(this.AppendLine("SyntaxFactory.Identifier(")
                           .PushIndent()
                           .WriteArgument("leading", token.LeadingTrivia)
                           .WriteArgument("contextualKind", token.Kind())
                           .WriteArgument("text", token.Text)
                           .WriteArgument("valueText", token.ValueText)
                           .WriteArgument("trailing", token.TrailingTrivia, closeArgumentList: true)
                           .PopIndent());
                }

                return(this.AppendLine("SyntaxFactory.Identifier(")
                       .PushIndent()
                       .WriteArgument("leading", token.LeadingTrivia)
                       .WriteArgument("text", token.Text)
                       .WriteArgument("trailing", token.TrailingTrivia, closeArgumentList: true)
                       .PopIndent());

            case SyntaxKind.NumericLiteralToken:
                if (!token.HasLeadingTrivia &&
                    !token.HasTrailingTrivia)
                {
                    return(this.AppendLine("SyntaxFactory.Literal(")
                           .PushIndent()
                           .WriteArgument("text", token.Text)
                           .WriteArgumentValue("value", token.ValueText, closeArgumentList: true)
                           .PopIndent());
                }

                return(this.AppendLine("SyntaxFactory.Literal(")
                       .PushIndent()
                       .WriteArgument("leading", token.LeadingTrivia)
                       .WriteArgument("text", token.Text)
                       .WriteArgumentValue("value", token.ValueText)
                       .WriteArgument("trailing", token.TrailingTrivia, closeArgumentList: true)
                       .PopIndent());

            case SyntaxKind.CharacterLiteralToken:
            case SyntaxKind.StringLiteralToken:
                if (!token.HasLeadingTrivia &&
                    !token.HasTrailingTrivia)
                {
                    return(this.AppendLine("SyntaxFactory.Literal(")
                           .PushIndent()
                           .WriteArgument("text", token.Text)
                           .WriteArgument("value", token.ValueText, closeArgumentList: true)
                           .PopIndent());
                }

                return(this.AppendLine("SyntaxFactory.Literal(")
                       .PushIndent()
                       .WriteArgument("leading", token.LeadingTrivia)
                       .WriteArgument("text", token.Text)
                       .WriteArgument("value", token.ValueText)
                       .WriteArgument("trailing", token.TrailingTrivia, closeArgumentList: true)
                       .PopIndent());

            case SyntaxKind.XmlTextLiteralToken:
                if (token.HasLeadingTrivia ||
                    token.HasTrailingTrivia)
                {
                    return(this.AppendLine("SyntaxFactory.XmlTextLiteral(")
                           .PushIndent()
                           .WriteArgument("leading", token.LeadingTrivia)
                           .WriteArgument("text", token.Text)
                           .WriteArgument("value", token.ValueText)
                           .WriteArgument("trailing", token.TrailingTrivia, closeArgumentList: true)
                           .PopIndent());
                }

                if (new System.Xml.Linq.XText(token.ValueText).ToString() == token.Text)
                {
                    this.writer.Append("SyntaxFactory.XmlTextLiteral(")
                    .AppendQuotedEscaped(token.Text)
                    .Append(")");
                    return(this);
                }

                return(this.AppendLine("SyntaxFactory.XmlTextLiteral(")
                       .PushIndent()
                       .WriteArgument("text", token.Text)
                       .WriteArgument("value", token.ValueText, closeArgumentList: true)
                       .PopIndent());

            case SyntaxKind.XmlEntityLiteralToken:
                return(this.AppendLine("SyntaxFactory.XmlEntity(")
                       .PushIndent()
                       .WriteArgument("leading", token.LeadingTrivia)
                       .WriteArgument("text", token.Text)
                       .WriteArgument("value", token.ValueText)
                       .WriteArgument("trailing", token.TrailingTrivia, closeArgumentList: true)
                       .PopIndent());

            case SyntaxKind.XmlTextLiteralNewLineToken:
                if (token.Text.Length == 1)
                {
                    return(this.AppendLine("SyntaxFactory.XmlTextNewLine(")
                           .PushIndent()
                           .WriteArgument("leading", token.LeadingTrivia)
                           .WriteArgument("text", "\n")
                           .WriteArgument("value", "\n")
                           .WriteArgument("trailing", token.TrailingTrivia, closeArgumentList: true)
                           .PopIndent());
                }

                return(this.AppendLine("SyntaxFactory.XmlTextNewLine(")
                       .PushIndent()
                       .WriteArgument("leading", token.LeadingTrivia)
                       .WriteArgument("text", "\r\n")
                       .WriteArgument("value", "\r\n")
                       .WriteArgument("trailing", token.TrailingTrivia, closeArgumentList: true)
                       .PopIndent());

            default:
                if (SyntaxFacts.GetText(token.Kind()) == token.Text)
                {
                    if (token.HasLeadingTrivia || token.HasTrailingTrivia)
                    {
                        return(this.AppendLine("SyntaxFactory.Token(")
                               .PushIndent()
                               .WriteArgument("leading", token.LeadingTrivia)
                               .WriteArgument("kind", token.Kind())
                               .WriteArgument("trailing", token.TrailingTrivia, closeArgumentList: true)
                               .PopIndent());
                    }

                    return(this.Append($"SyntaxFactory.Token(SyntaxKind.{token.Kind()})"));
                }

                return(this.AppendLine("SyntaxFactory.Token(")
                       .PushIndent()
                       .WriteArgument("leading", token.LeadingTrivia)
                       .WriteArgument("kind", token.Kind())
                       .WriteArgument("text", token.Text)
                       .WriteArgument("valueText", token.ValueText)
                       .WriteArgument("trailing", token.TrailingTrivia, closeArgumentList: true)
                       .PopIndent());
            }
        }
예제 #11
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsAnyEnabled(
                    CodeFixIdentifiers.AddOutModifierToArgument,
                    CodeFixIdentifiers.RemoveRefModifier,
                    CodeFixIdentifiers.CreateSingletonArray,
                    CodeFixIdentifiers.AddArgumentList,
                    CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue))
            {
                return;
            }

            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out ArgumentSyntax argument))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.ArgumentMustBePassedWithRefOrOutKeyword:
                {
                    if (!Settings.IsEnabled(CodeFixIdentifiers.AddOutModifierToArgument))
                    {
                        return;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    IParameterSymbol parameter = semanticModel.DetermineParameter(argument, allowCandidate: true, cancellationToken: context.CancellationToken);

                    if (parameter == null)
                    {
                        return;
                    }

                    SyntaxToken refOrOutKeyword = default;

                    if (parameter.RefKind == RefKind.Out)
                    {
                        refOrOutKeyword = Token(SyntaxKind.OutKeyword);
                    }
                    else if (parameter.RefKind == RefKind.Ref)
                    {
                        refOrOutKeyword = Token(SyntaxKind.RefKeyword);
                    }
                    else
                    {
                        return;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        $"Add '{SyntaxFacts.GetText(refOrOutKeyword.Kind())}' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(refOrOutKeyword)
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case CompilerDiagnosticIdentifiers.ArgumentShouldNotBePassedWithRefOrOutKeyword:
                {
                    if (!Settings.IsEnabled(CodeFixIdentifiers.RemoveRefModifier))
                    {
                        return;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Remove 'ref' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(default(SyntaxToken))
                                                         .PrependToLeadingTrivia(argument.RefOrOutKeyword.GetAllTrivia())
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotConvertArgumentType:
                {
                    if (Settings.IsEnabled(CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue))
                    {
                        ExpressionSyntax expression = argument.Expression;

                        if (expression.Kind() == SyntaxKind.NullLiteralExpression &&
                            argument.Parent is ArgumentListSyntax argumentList)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            ImmutableArray <IParameterSymbol> parameterSymbols = FindParameters(argumentList, semanticModel, context.CancellationToken);

                            if (!parameterSymbols.IsDefault)
                            {
                                int index = argumentList.Arguments.IndexOf(argument);

                                IParameterSymbol parameterSymbol = parameterSymbols[index];

                                ITypeSymbol typeSymbol = parameterSymbol.Type;

                                if (typeSymbol.IsValueType)
                                {
                                    CodeFixRegistrator.ReplaceNullWithDefaultValue(
                                        context,
                                        diagnostic,
                                        expression,
                                        typeSymbol,
                                        CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue);
                                }
                            }
                        }
                    }

                    if (Settings.IsEnabled(CodeFixIdentifiers.AddArgumentList))
                    {
                        ExpressionSyntax expression = argument.Expression;

                        if (expression.IsKind(
                                SyntaxKind.IdentifierName,
                                SyntaxKind.GenericName,
                                SyntaxKind.SimpleMemberAccessExpression))
                        {
                            InvocationExpressionSyntax invocationExpression = InvocationExpression(
                                expression.WithoutTrailingTrivia(),
                                ArgumentList().WithTrailingTrivia(expression.GetTrailingTrivia()));

                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            if (semanticModel.GetSpeculativeMethodSymbol(expression.SpanStart, invocationExpression) != null)
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Add argument list",
                                    cancellationToken =>
                                    {
                                        ArgumentSyntax newNode = argument.WithExpression(invocationExpression);

                                        return(context.Document.ReplaceNodeAsync(argument, newNode, cancellationToken));
                                    },
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.AddArgumentList));

                                context.RegisterCodeFix(codeAction, diagnostic);
                                break;
                            }
                        }
                    }

                    if (Settings.IsEnabled(CodeFixIdentifiers.CreateSingletonArray))
                    {
                        ExpressionSyntax expression = argument.Expression;

                        if (expression?.IsMissing == false)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression);

                            if (typeSymbol?.IsErrorType() == false)
                            {
                                foreach (ITypeSymbol typeSymbol2 in DetermineParameterTypeHelper.DetermineParameterTypes(argument, semanticModel, context.CancellationToken))
                                {
                                    if (!typeSymbol.Equals(typeSymbol2) &&
                                        typeSymbol2 is IArrayTypeSymbol arrayType &&
                                        semanticModel.IsImplicitConversion(expression, arrayType.ElementType))
                                    {
                                        CodeAction codeAction = CodeAction.Create(
                                            "Create singleton array",
                                            cancellationToken => CreateSingletonArrayRefactoring.RefactorAsync(context.Document, expression, arrayType.ElementType, semanticModel, cancellationToken),
                                            GetEquivalenceKey(diagnostic, CodeFixIdentifiers.CreateSingletonArray));

                                        context.RegisterCodeFix(codeAction, diagnostic);
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    break;
                }
                }
            }
        }
        public void AnalyzeNode(SyntaxNodeAnalysisContext context)
        {
            var node = context.Node;

            if (node.IsKind(SyntaxKind.IfStatement))
            {
                var ifStatement = (IfStatementSyntax)node;
                if (AnalyzeIfStatement(ifStatement))
                {
                    context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
                                                               ifStatement.IfKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.IfKeyword)));
                }
            }

            if (node.IsKind(SyntaxKind.ElseClause))
            {
                var elseClause = (ElseClauseSyntax)node;
                if (AnalyzeElseClause(elseClause))
                {
                    context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
                                                               elseClause.ElseKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ElseKeyword)));
                }
            }

            if (node.IsKind(SyntaxKind.ForStatement))
            {
                var forStatement = (ForStatementSyntax)node;
                if (AnalyzeForStatement(forStatement))
                {
                    context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
                                                               forStatement.ForKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ForKeyword)));
                }
            }

            if (node.IsKind(SyntaxKind.ForEachStatement) || node.IsKind(SyntaxKind.ForEachComponentStatement))
            {
                var forEachStatement = (CommonForEachStatementSyntax)node;
                if (AnalyzeForEachStatement(forEachStatement))
                {
                    context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
                                                               forEachStatement.ForEachKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ForEachKeyword)));
                }
            }

            if (node.IsKind(SyntaxKind.WhileStatement))
            {
                var whileStatement = (WhileStatementSyntax)node;
                if (AnalyzeWhileStatement(whileStatement))
                {
                    context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
                                                               whileStatement.WhileKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.WhileKeyword)));
                }
            }

            if (node.IsKind(SyntaxKind.DoStatement))
            {
                var doStatement = (DoStatementSyntax)node;
                if (AnalyzeDoStatement(doStatement))
                {
                    context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
                                                               doStatement.DoKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.DoKeyword)));
                }
            }

            if (node.IsKind(SyntaxKind.UsingStatement))
            {
                var usingStatement = (UsingStatementSyntax)context.Node;
                if (AnalyzeUsingStatement(usingStatement))
                {
                    context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
                                                               usingStatement.UsingKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.UsingKeyword)));
                }
            }

            if (node.IsKind(SyntaxKind.LockStatement))
            {
                var lockStatement = (LockStatementSyntax)context.Node;
                if (AnalyzeLockStatement(lockStatement))
                {
                    context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
                                                               lockStatement.LockKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.LockKeyword)));
                }
            }
        }
예제 #13
0
 public static void WritePunctuation(this TextWriter writer, SyntaxKind kind)
 {
     writer.WritePunctuation(SyntaxFacts.GetText(kind));
 }
예제 #14
0
 public static void WriteKeyword(this TextWriter writer, SyntaxKind kind)
 {
     writer.WriteKeyword(SyntaxFacts.GetText(kind));
 }
        public void TestBinaryOperators(SyntaxKind expressionKind, SyntaxKind tokenKind)
        {
            UsingExpression($"new(Int32,Int32){SyntaxFacts.GetText(tokenKind),2}", DefaultParseOptions,
                            // (1,18): error CS1733: Expected expression
                            // new(Int32,Int32) +
                            Diagnostic(ErrorCode.ERR_ExpressionExpected, "").WithLocation(1, 19));

            N(expressionKind);
            {
                N(SyntaxKind.ImplicitObjectCreationExpression);
                {
                    N(SyntaxKind.NewKeyword);
                    N(SyntaxKind.ArgumentList);
                    {
                        N(SyntaxKind.OpenParenToken);
                        N(SyntaxKind.Argument);
                        {
                            N(SyntaxKind.IdentifierName);
                            {
                                N(SyntaxKind.IdentifierToken, "Int32");
                            }
                        }
                        N(SyntaxKind.CommaToken);
                        N(SyntaxKind.Argument);
                        {
                            N(SyntaxKind.IdentifierName);
                            {
                                N(SyntaxKind.IdentifierToken, "Int32");
                            }
                        }
                        N(SyntaxKind.CloseParenToken);
                    }
                }
                N(tokenKind);
                M(SyntaxKind.IdentifierName);
                {
                    M(SyntaxKind.IdentifierToken);
                }
            }
            EOF();

            UsingExpression($"new(Int32,Int32){SyntaxFacts.GetText(tokenKind),2}e", DefaultParseOptions);

            N(expressionKind);
            {
                N(SyntaxKind.ImplicitObjectCreationExpression);
                {
                    N(SyntaxKind.NewKeyword);
                    N(SyntaxKind.ArgumentList);
                    {
                        N(SyntaxKind.OpenParenToken);
                        N(SyntaxKind.Argument);
                        {
                            N(SyntaxKind.IdentifierName);
                            {
                                N(SyntaxKind.IdentifierToken, "Int32");
                            }
                        }
                        N(SyntaxKind.CommaToken);
                        N(SyntaxKind.Argument);
                        {
                            N(SyntaxKind.IdentifierName);
                            {
                                N(SyntaxKind.IdentifierToken, "Int32");
                            }
                        }
                        N(SyntaxKind.CloseParenToken);
                    }
                }
                N(tokenKind);
                N(SyntaxKind.IdentifierName, "e");
                {
                    N(SyntaxKind.IdentifierToken);
                }
            }
            EOF();
        }
예제 #16
0
        internal static string ConvertSingleModifierToSyntaxText(DeclarationModifiers modifier)
        {
            switch (modifier)
            {
            case DeclarationModifiers.Abstract:
                return(SyntaxFacts.GetText(SyntaxKind.AbstractKeyword));

            case DeclarationModifiers.Sealed:
                return(SyntaxFacts.GetText(SyntaxKind.SealedKeyword));

            case DeclarationModifiers.Static:
                return(SyntaxFacts.GetText(SyntaxKind.StaticKeyword));

            case DeclarationModifiers.New:
                return(SyntaxFacts.GetText(SyntaxKind.NewKeyword));

            case DeclarationModifiers.Public:
                return(SyntaxFacts.GetText(SyntaxKind.PublicKeyword));

            case DeclarationModifiers.Protected:
                return(SyntaxFacts.GetText(SyntaxKind.ProtectedKeyword));

            case DeclarationModifiers.Internal:
                return(SyntaxFacts.GetText(SyntaxKind.InternalKeyword));

            case DeclarationModifiers.ProtectedInternal:
                return(SyntaxFacts.GetText(SyntaxKind.ProtectedKeyword) + " " + SyntaxFacts.GetText(SyntaxKind.InternalKeyword));

            case DeclarationModifiers.Private:
                return(SyntaxFacts.GetText(SyntaxKind.PrivateKeyword));

            case DeclarationModifiers.PrivateProtected:
                return(SyntaxFacts.GetText(SyntaxKind.PrivateKeyword) + " " + SyntaxFacts.GetText(SyntaxKind.ProtectedKeyword));

            case DeclarationModifiers.ReadOnly:
                return(SyntaxFacts.GetText(SyntaxKind.ReadOnlyKeyword));

            case DeclarationModifiers.Const:
                return(SyntaxFacts.GetText(SyntaxKind.ConstKeyword));

            case DeclarationModifiers.Volatile:
                return(SyntaxFacts.GetText(SyntaxKind.VolatileKeyword));

            case DeclarationModifiers.Extern:
                return(SyntaxFacts.GetText(SyntaxKind.ExternKeyword));

            case DeclarationModifiers.Partial:
                return(SyntaxFacts.GetText(SyntaxKind.PartialKeyword));

            case DeclarationModifiers.Unsafe:
                return(SyntaxFacts.GetText(SyntaxKind.UnsafeKeyword));

            case DeclarationModifiers.Fixed:
                return(SyntaxFacts.GetText(SyntaxKind.FixedKeyword));

            case DeclarationModifiers.Virtual:
                return(SyntaxFacts.GetText(SyntaxKind.VirtualKeyword));

            case DeclarationModifiers.Override:
                return(SyntaxFacts.GetText(SyntaxKind.OverrideKeyword));

            case DeclarationModifiers.Async:
                return(SyntaxFacts.GetText(SyntaxKind.AsyncKeyword));

            case DeclarationModifiers.Ref:
                return(SyntaxFacts.GetText(SyntaxKind.RefKeyword));

            default:
                throw ExceptionUtilities.UnexpectedValue(modifier);
            }
        }
예제 #17
0
        private static void CheckParameterModifiers(
            ParameterSyntax parameter, DiagnosticBag diagnostics)
        {
            var seenThis   = false;
            var seenRef    = false;
            var seenOut    = false;
            var seenParams = false;

            foreach (var modifier in parameter.Modifiers)
            {
                switch (modifier.Kind())
                {
                case SyntaxKind.ThisKeyword:
                    if (seenThis)
                    {
                        diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ThisKeyword));
                    }
                    else if (seenOut)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadOutWithThis, modifier.GetLocation());
                    }
                    else if (seenRef)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadRefWithThis, modifier.GetLocation());
                    }
                    else if (seenParams)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParamModThis, modifier.GetLocation());
                    }
                    else
                    {
                        seenThis = true;
                    }
                    break;

                case SyntaxKind.RefKeyword:
                    if (seenRef)
                    {
                        diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.RefKeyword));
                    }
                    else if (seenThis)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadRefWithThis, modifier.GetLocation());
                    }
                    else if (seenParams)
                    {
                        diagnostics.Add(ErrorCode.ERR_ParamsCantBeRefOut, modifier.GetLocation());
                    }
                    else if (seenOut)
                    {
                        diagnostics.Add(ErrorCode.ERR_MultiParamMod, modifier.GetLocation());
                    }
                    else
                    {
                        seenRef = true;
                    }
                    break;

                case SyntaxKind.OutKeyword:
                    if (seenOut)
                    {
                        diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword));
                    }
                    else if (seenThis)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadOutWithThis, modifier.GetLocation());
                    }
                    else if (seenParams)
                    {
                        diagnostics.Add(ErrorCode.ERR_ParamsCantBeRefOut, modifier.GetLocation());
                    }
                    else if (seenRef)
                    {
                        diagnostics.Add(ErrorCode.ERR_MultiParamMod, modifier.GetLocation());
                    }
                    else
                    {
                        seenOut = true;
                    }
                    break;

                case SyntaxKind.ParamsKeyword:
                    if (seenParams)
                    {
                        diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ParamsKeyword));
                    }
                    else if (seenThis)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParamModThis, modifier.GetLocation());
                    }
                    else if (seenRef || seenOut || seenThis)
                    {
                        diagnostics.Add(ErrorCode.ERR_MultiParamMod, modifier.GetLocation());
                    }
                    else
                    {
                        seenParams = true;
                    }
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }
        }
예제 #18
0
 public static string ToFriendlyString(this Accessibility accessibility) => SyntaxFacts.GetText(accessibility);
 protected override void AddAwaitableUsageText(IMethodSymbol method, SemanticModel semanticModel, int position)
 {
     AddToGroup(SymbolDescriptionGroups.AwaitableUsageText,
                method.ToAwaitableParts(SyntaxFacts.GetText(SyntaxKind.AwaitKeyword), "x", semanticModel, position));
 }
예제 #20
0
 private static bool IsKindOrHasMatchingText(SyntaxToken token, SyntaxKind kind) =>
 token.Kind() == kind || token.ToString() == SyntaxFacts.GetText(kind);
        internal sealed override TypeSymbol GetFieldType(ConsList <FieldSymbol> fieldsBeingBound)
        {
            Debug.Assert(fieldsBeingBound != null);

            if ((object)lazyType != null)
            {
                return(lazyType);
            }

            var declarator  = VariableDeclaratorNode;
            var fieldSyntax = GetFieldDeclaration(declarator);
            var typeSyntax  = fieldSyntax.Declaration.Type;

            var compilation = this.DeclaringCompilation;

            var        diagnostics = DiagnosticBag.GetInstance();
            TypeSymbol type;

            // When we have multiple declarators, we report the type diagnostics on only the first.
            DiagnosticBag diagnosticsForFirstDeclarator = DiagnosticBag.GetInstance();

            Symbol associatedPropertyOrEvent = this.AssociatedSymbol;

            if ((object)associatedPropertyOrEvent != null && associatedPropertyOrEvent.Kind == SymbolKind.Event)
            {
                EventSymbol @event = (EventSymbol)associatedPropertyOrEvent;
                if (@event.IsWindowsRuntimeEvent)
                {
                    NamedTypeSymbol tokenTableType = this.DeclaringCompilation.GetWellKnownType(WellKnownType.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationTokenTable_T);
                    Binder.ReportUseSiteDiagnostics(tokenTableType, diagnosticsForFirstDeclarator, this.ErrorLocation);

                    // CONSIDER: Do we want to guard against the possibility that someone has created their own EventRegistrationTokenTable<T>
                    // type that has additional generic constraints?
                    type = tokenTableType.Construct(@event.Type);
                }
                else
                {
                    type = @event.Type;
                }
            }
            else
            {
                var binderFactory = compilation.GetBinderFactory(SyntaxTree);
                var binder        = binderFactory.GetBinder(typeSyntax);

                binder = binder.WithContainingMemberOrLambda(this);
                if (!ContainingType.IsScriptClass)
                {
                    type = binder.BindType(typeSyntax, diagnosticsForFirstDeclarator);
                    if (IsFixed)
                    {
                        type = new PointerTypeSymbol(type);
                    }
                }
                else
                {
                    bool isVar;
                    type = binder.BindType(typeSyntax, diagnostics, out isVar);

                    Debug.Assert((object)type != null || isVar);

                    if (isVar)
                    {
                        if (this.IsConst)
                        {
                            diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_ImplicitlyTypedVariableCannotBeConst, typeSyntax.Location);
                        }

                        if (fieldsBeingBound.ContainsReference(this))
                        {
                            diagnostics.Add(ErrorCode.ERR_RecursivelyTypedVariable, this.ErrorLocation, this);
                            type = null;
                        }
                        else if (fieldSyntax.Declaration.Variables.Count > 1)
                        {
                            diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_ImplicitlyTypedVariableMultipleDeclarator, typeSyntax.Location);
                        }
                        else
                        {
                            fieldsBeingBound = new ConsList <FieldSymbol>(this, fieldsBeingBound);

                            var initializerBinder = new ImplicitlyTypedFieldBinder(binder, fieldsBeingBound);
                            var initializerOpt    = initializerBinder.BindInferredVariableInitializer(diagnostics, declarator.Initializer, declarator);

                            if (initializerOpt != null)
                            {
                                if ((object)initializerOpt.Type != null && !initializerOpt.Type.IsErrorType())
                                {
                                    type = initializerOpt.Type;
                                }

                                this.lazyFieldTypeInferred = 1;
                            }
                        }

                        if ((object)type == null)
                        {
                            type = binder.CreateErrorType("var");
                        }
                    }
                }

                if (IsFixed)
                {
                    if (ContainingType.TypeKind != TypeKind.Struct)
                    {
                        diagnostics.Add(ErrorCode.ERR_FixedNotInStruct, ErrorLocation);
                    }

                    if (IsStatic)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadMemberFlag, ErrorLocation, SyntaxFacts.GetText(SyntaxKind.StaticKeyword));
                    }

                    if (IsVolatile)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadMemberFlag, ErrorLocation, SyntaxFacts.GetText(SyntaxKind.VolatileKeyword));
                    }

                    var elementType = ((PointerTypeSymbol)type).PointedAtType;
                    int elementSize = elementType.FixedBufferElementSizeInBytes();
                    if (elementSize == 0)
                    {
                        var loc = typeSyntax.Location;
                        diagnostics.Add(ErrorCode.ERR_IllegalFixedType, loc);
                    }

                    if (!binder.InUnsafeRegion)
                    {
                        diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_UnsafeNeeded, declarator.Location);
                    }
                }
            }

            // update the lazyType only if it contains value last seen by the current thread:
            if ((object)Interlocked.CompareExchange(ref lazyType, type, null) == null)
            {
                TypeChecks(type, fieldSyntax, declarator, diagnostics);

                // CONSIDER: SourceEventFieldSymbol would like to suppress these diagnostics.
                compilation.SemanticDiagnostics.AddRange(diagnostics);

                bool isFirstDeclarator = fieldSyntax.Declaration.Variables[0] == declarator;
                if (isFirstDeclarator)
                {
                    compilation.SemanticDiagnostics.AddRange(diagnosticsForFirstDeclarator);
                }

                state.NotePartComplete(CompletionPart.Type);
            }

            diagnostics.Free();
            diagnosticsForFirstDeclarator.Free();
            return(lazyType);
        }
예제 #22
0
        private static void CheckParameterModifiers(
            ParameterSyntax parameter, DiagnosticBag diagnostics)
        {
            var seenThis   = false;
            var seenRef    = false;
            var seenOut    = false;
            var seenParams = false;
            var seenIn     = false;

            // If we don't have an extended type syntax, we don't have modifiers
            var extendedSypeSyntax = parameter.Type as ExtendedTypeSyntax;

            if (extendedSypeSyntax == null)
            {
                return;
            }

            foreach (var modifier in extendedSypeSyntax.Modifiers)
            {
                switch (modifier.Kind())
                {
                case SyntaxKind.ThisKeyword:
                    if (seenThis)
                    {
                        diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ThisKeyword));
                    }
                    else if (seenOut)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ThisKeyword), SyntaxFacts.GetText(SyntaxKind.OutKeyword));
                    }
                    else if (seenParams)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParamModThis, modifier.GetLocation());
                    }
                    else
                    {
                        seenThis = true;
                    }
                    break;

                case SyntaxKind.RefKeyword:
                    if (seenRef)
                    {
                        diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.RefKeyword));
                    }
                    else if (seenParams)
                    {
                        diagnostics.Add(ErrorCode.ERR_ParamsCantBeWithModifier, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.RefKeyword));
                    }
                    else if (seenOut)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.RefKeyword), SyntaxFacts.GetText(SyntaxKind.OutKeyword));
                    }
                    else if (seenIn)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.RefKeyword), SyntaxFacts.GetText(SyntaxKind.InKeyword));
                    }
                    else
                    {
                        seenRef = true;
                    }
                    break;

                case SyntaxKind.OutKeyword:
                    if (seenOut)
                    {
                        diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword));
                    }
                    else if (seenThis)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword), SyntaxFacts.GetText(SyntaxKind.ThisKeyword));
                    }
                    else if (seenParams)
                    {
                        diagnostics.Add(ErrorCode.ERR_ParamsCantBeWithModifier, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword));
                    }
                    else if (seenRef)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword), SyntaxFacts.GetText(SyntaxKind.RefKeyword));
                    }
                    else if (seenIn)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword), SyntaxFacts.GetText(SyntaxKind.InKeyword));
                    }
                    else
                    {
                        seenOut = true;
                    }
                    break;

                case SyntaxKind.ParamsKeyword:
                    if (seenParams)
                    {
                        diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ParamsKeyword));
                    }
                    else if (seenThis)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParamModThis, modifier.GetLocation());
                    }
                    else if (seenRef)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ParamsKeyword), SyntaxFacts.GetText(SyntaxKind.RefKeyword));
                    }
                    else if (seenIn)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ParamsKeyword), SyntaxFacts.GetText(SyntaxKind.InKeyword));
                    }
                    else if (seenOut)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ParamsKeyword), SyntaxFacts.GetText(SyntaxKind.OutKeyword));
                    }
                    else
                    {
                        seenParams = true;
                    }
                    break;

                case SyntaxKind.InKeyword:
                    if (seenIn)
                    {
                        diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword));
                    }
                    else if (seenOut)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword), SyntaxFacts.GetText(SyntaxKind.OutKeyword));
                    }
                    else if (seenRef)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword), SyntaxFacts.GetText(SyntaxKind.RefKeyword));
                    }
                    else if (seenParams)
                    {
                        diagnostics.Add(ErrorCode.ERR_ParamsCantBeWithModifier, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword));
                    }
                    else
                    {
                        seenIn = true;
                    }
                    break;

                case SyntaxKind.TransientKeyword:
                case SyntaxKind.ReadOnlyKeyword:
                    break;

                default:
                    throw ExceptionUtilities.UnexpectedValue(modifier.Kind());
                }
            }
        }
예제 #23
0
 protected static SymbolDisplayPart Keyword(SyntaxKind kind)
 {
     return(new SymbolDisplayPart(SymbolDisplayPartKind.Keyword, null, SyntaxFacts.GetText(kind)));
 }
예제 #24
0
        private void CheckModifiers(Location location, DiagnosticBag diagnostics)
        {
            const DeclarationModifiers partialMethodInvalidModifierMask = (DeclarationModifiers.AccessibilityMask & ~DeclarationModifiers.Private) |
                                                                          DeclarationModifiers.Virtual |
                                                                          DeclarationModifiers.Abstract |
                                                                          DeclarationModifiers.Override |
                                                                          DeclarationModifiers.New |
                                                                          DeclarationModifiers.Sealed |
                                                                          DeclarationModifiers.Extern;

            if (IsPartial && !ReturnsVoid)
            {
                diagnostics.Add(ErrorCode.ERR_PartialMethodMustReturnVoid, location);
            }
            else if (IsPartial && !ContainingType.IsInterface && (DeclarationModifiers & partialMethodInvalidModifierMask) != 0)
            {
                diagnostics.Add(ErrorCode.ERR_PartialMethodInvalidModifier, location);
            }
            else if (this.DeclaredAccessibility == Accessibility.Private && (IsVirtual || IsAbstract || IsOverride))
            {
                diagnostics.Add(ErrorCode.ERR_VirtualPrivate, location, this);
            }
            else if (IsStatic && (IsOverride || IsVirtual || IsAbstract))
            {
                // A static member '{0}' cannot be marked as override, virtual, or abstract
                diagnostics.Add(ErrorCode.ERR_StaticNotVirtual, location, this);
            }
            else if (IsOverride && (IsNew || IsVirtual))
            {
                // A member '{0}' marked as override cannot be marked as new or virtual
                diagnostics.Add(ErrorCode.ERR_OverrideNotNew, location, this);
            }
            else if (IsSealed && !IsOverride)
            {
                // '{0}' cannot be sealed because it is not an override
                diagnostics.Add(ErrorCode.ERR_SealedNonOverride, location, this);
            }
            else if (!ContainingType.IsInterfaceType() && _lazyReturnType.IsStatic)
            {
                // '{0}': static types cannot be used as return types
                diagnostics.Add(ErrorCode.ERR_ReturnTypeIsStaticClass, location, _lazyReturnType);
            }
            else if (IsAbstract && IsExtern)
            {
                diagnostics.Add(ErrorCode.ERR_AbstractAndExtern, location, this);
            }
            else if (IsAbstract && IsSealed)
            {
                diagnostics.Add(ErrorCode.ERR_AbstractAndSealed, location, this);
            }
            else if (IsAbstract && IsVirtual)
            {
                diagnostics.Add(ErrorCode.ERR_AbstractNotVirtual, location, this);
            }
            else if (IsAbstract && ContainingType.TypeKind == TypeKind.Struct)
            {
                // The modifier '{0}' is not valid for this item
                diagnostics.Add(ErrorCode.ERR_BadMemberFlag, location, SyntaxFacts.GetText(SyntaxKind.AbstractKeyword));
            }
            else if (IsVirtual && ContainingType.TypeKind == TypeKind.Struct)
            {
                // The modifier '{0}' is not valid for this item
                diagnostics.Add(ErrorCode.ERR_BadMemberFlag, location, SyntaxFacts.GetText(SyntaxKind.VirtualKeyword));
            }
            else if (IsAbstract && !ContainingType.IsAbstract && (ContainingType.TypeKind == TypeKind.Class || ContainingType.TypeKind == TypeKind.Submission))
            {
                // '{0}' is abstract but it is contained in non-abstract class '{1}'
                diagnostics.Add(ErrorCode.ERR_AbstractInConcreteClass, location, this, ContainingType);
            }
            else if (IsVirtual && ContainingType.IsSealed)
            {
                // '{0}' is a new virtual member in sealed class '{1}'
                diagnostics.Add(ErrorCode.ERR_NewVirtualInSealed, location, this, ContainingType);
            }
            else if (bodySyntaxReferenceOpt == null && IsAsync)
            {
                diagnostics.Add(ErrorCode.ERR_BadAsyncLacksBody, location);
            }
            else if (bodySyntaxReferenceOpt == null && !IsExtern && !IsAbstract && !IsPartial && !IsExpressionBodied)
            {
                diagnostics.Add(ErrorCode.ERR_ConcreteMissingBody, location, this);
            }
            else if (ContainingType.IsSealed && this.DeclaredAccessibility.HasProtected() && !this.IsOverride)
            {
                diagnostics.Add(AccessCheck.GetProtectedMemberInSealedTypeError(ContainingType), location, this);
            }
            else if (ContainingType.IsStatic && !IsStatic)
            {
                diagnostics.Add(ErrorCode.ERR_InstanceMemberInStaticClass, location, Name);
            }
            else if (_lazyIsVararg && (IsGenericMethod || ContainingType.IsGenericType || _lazyParameters.Length > 0 && _lazyParameters[_lazyParameters.Length - 1].IsParams))
            {
                diagnostics.Add(ErrorCode.ERR_BadVarargs, location);
            }
            else if (_lazyIsVararg && IsAsync)
            {
                diagnostics.Add(ErrorCode.ERR_VarargsAsync, location);
            }
        }
        private void CheckModifiers(bool isExplicitInterfaceImplementation, bool isVararg, bool hasBody, Location location, DiagnosticBag diagnostics)
        {
            bool isExplicitInterfaceImplementationInInterface = isExplicitInterfaceImplementation && ContainingType.IsInterface;

            if (IsPartial && HasExplicitAccessModifier)
            {
                Binder.CheckFeatureAvailability(SyntaxNode, MessageID.IDS_FeatureExtendedPartialMethods, diagnostics, location);
            }

            if (IsPartial && IsAbstract)
            {
                diagnostics.Add(ErrorCode.ERR_PartialMethodInvalidModifier, location);
            }
            else if (IsPartial && !HasExplicitAccessModifier && !ReturnsVoid)
            {
                diagnostics.Add(ErrorCode.ERR_PartialMethodWithNonVoidReturnMustHaveAccessMods, location, this);
            }
            else if (IsPartial && !HasExplicitAccessModifier && HasExtendedPartialModifier)
            {
                diagnostics.Add(ErrorCode.ERR_PartialMethodWithExtendedModMustHaveAccessMods, location, this);
            }
            else if (IsPartial && !HasExplicitAccessModifier && Parameters.Any(p => p.RefKind == RefKind.Out))
            {
                diagnostics.Add(ErrorCode.ERR_PartialMethodWithOutParamMustHaveAccessMods, location, this);
            }
            else if (this.DeclaredAccessibility == Accessibility.Private && (IsVirtual || (IsAbstract && !isExplicitInterfaceImplementationInInterface) || IsOverride))
            {
                diagnostics.Add(ErrorCode.ERR_VirtualPrivate, location, this);
            }
            else if (IsStatic && (IsOverride || IsVirtual || IsAbstract))
            {
                // A static member '{0}' cannot be marked as override, virtual, or abstract
                diagnostics.Add(ErrorCode.ERR_StaticNotVirtual, location, this);
            }
            else if (IsOverride && (IsNew || IsVirtual))
            {
                // A member '{0}' marked as override cannot be marked as new or virtual
                diagnostics.Add(ErrorCode.ERR_OverrideNotNew, location, this);
            }
            else if (IsSealed && !IsOverride && !(isExplicitInterfaceImplementationInInterface && IsAbstract))
            {
                // '{0}' cannot be sealed because it is not an override
                diagnostics.Add(ErrorCode.ERR_SealedNonOverride, location, this);
            }
            else if (IsSealed && ContainingType.TypeKind == TypeKind.Struct)
            {
                // The modifier '{0}' is not valid for this item
                diagnostics.Add(ErrorCode.ERR_BadMemberFlag, location, SyntaxFacts.GetText(SyntaxKind.SealedKeyword));
            }
            else if (_lazyReturnType.IsStatic)
            {
                // '{0}': static types cannot be used as return types
                diagnostics.Add(ErrorFacts.GetStaticClassReturnCode(ContainingType.IsInterfaceType()), location, _lazyReturnType.Type);
            }
            else if (IsAbstract && IsExtern)
            {
                diagnostics.Add(ErrorCode.ERR_AbstractAndExtern, location, this);
            }
            else if (IsAbstract && IsSealed && !isExplicitInterfaceImplementationInInterface)
            {
                diagnostics.Add(ErrorCode.ERR_AbstractAndSealed, location, this);
            }
            else if (IsAbstract && IsVirtual)
            {
                diagnostics.Add(ErrorCode.ERR_AbstractNotVirtual, location, this.Kind.Localize(), this);
            }
            else if (IsAbstract && ContainingType.TypeKind == TypeKind.Struct)
            {
                // The modifier '{0}' is not valid for this item
                diagnostics.Add(ErrorCode.ERR_BadMemberFlag, location, SyntaxFacts.GetText(SyntaxKind.AbstractKeyword));
            }
            else if (IsVirtual && ContainingType.TypeKind == TypeKind.Struct)
            {
                // The modifier '{0}' is not valid for this item
                diagnostics.Add(ErrorCode.ERR_BadMemberFlag, location, SyntaxFacts.GetText(SyntaxKind.VirtualKeyword));
            }
            else if (IsStatic && IsDeclaredReadOnly)
            {
                // Static member '{0}' cannot be marked 'readonly'.
                diagnostics.Add(ErrorCode.ERR_StaticMemberCantBeReadOnly, location, this);
            }
            else if (IsAbstract && !ContainingType.IsAbstract && (ContainingType.TypeKind == TypeKind.Class || ContainingType.TypeKind == TypeKind.Submission))
            {
                // '{0}' is abstract but it is contained in non-abstract type '{1}'
                diagnostics.Add(ErrorCode.ERR_AbstractInConcreteClass, location, this, ContainingType);
            }
            else if (IsVirtual && ContainingType.IsSealed)
            {
                // '{0}' is a new virtual member in sealed type '{1}'
                diagnostics.Add(ErrorCode.ERR_NewVirtualInSealed, location, this, ContainingType);
            }
            else if (!hasBody && IsAsync)
            {
                diagnostics.Add(ErrorCode.ERR_BadAsyncLacksBody, location);
            }
            else if (!hasBody && !IsExtern && !IsAbstract && !IsPartial && !IsExpressionBodied)
            {
                diagnostics.Add(ErrorCode.ERR_ConcreteMissingBody, location, this);
            }
            else if (ContainingType.IsSealed && this.DeclaredAccessibility.HasProtected() && !this.IsOverride)
            {
                diagnostics.Add(AccessCheck.GetProtectedMemberInSealedTypeError(ContainingType), location, this);
            }
            else if (ContainingType.IsStatic && !IsStatic)
            {
                diagnostics.Add(ErrorCode.ERR_InstanceMemberInStaticClass, location, Name);
            }
            else if (isVararg && (IsGenericMethod || ContainingType.IsGenericType || _lazyParameters.Length > 0 && _lazyParameters[_lazyParameters.Length - 1].IsParams))
            {
                diagnostics.Add(ErrorCode.ERR_BadVarargs, location);
            }
            else if (isVararg && IsAsync)
            {
                diagnostics.Add(ErrorCode.ERR_VarargsAsync, location);
            }
        }
예제 #26
0
    private void GenerateInteropMethodImplementations(GeneratorExecutionContext context, CallbacksData data)
    {
        var symbol = data.NativeTypeSymbol;

        INamespaceSymbol namespaceSymbol = symbol.ContainingNamespace;
        string           classNs         = namespaceSymbol != null && !namespaceSymbol.IsGlobalNamespace ?
                                           namespaceSymbol.FullQualifiedName() :
                                           string.Empty;
        bool hasNamespace = classNs.Length != 0;
        bool isInnerClass = symbol.ContainingType != null;

        var source                = new StringBuilder();
        var methodSource          = new StringBuilder();
        var methodCallArguments   = new StringBuilder();
        var methodSourceAfterCall = new StringBuilder();

        source.Append(
            @"using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Godot.Bridge;
using Godot.NativeInterop;

#pragma warning disable CA1707 // Disable warning: Identifiers should not contain underscores

");

        if (hasNamespace)
        {
            source.Append("namespace ");
            source.Append(classNs);
            source.Append("\n{\n");
        }

        if (isInnerClass)
        {
            var containingType = symbol.ContainingType;

            while (containingType != null)
            {
                source.Append("partial ");
                source.Append(containingType.GetDeclarationKeyword());
                source.Append(" ");
                source.Append(containingType.NameWithTypeParameters());
                source.Append("\n{\n");

                containingType = containingType.ContainingType;
            }
        }

        source.Append("[System.Runtime.CompilerServices.SkipLocalsInit]\n");
        source.Append($"unsafe partial class {symbol.Name}\n");
        source.Append("{\n");
        source.Append($"    private static {data.FuncStructSymbol.FullQualifiedName()} _unmanagedCallbacks;\n\n");

        foreach (var callback in data.Methods)
        {
            methodSource.Clear();
            methodCallArguments.Clear();
            methodSourceAfterCall.Clear();

            source.Append("    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]\n");
            source.Append($"    {SyntaxFacts.GetText(callback.DeclaredAccessibility)} ");

            if (callback.IsStatic)
            {
                source.Append("static ");
            }

            source.Append("partial ");
            source.Append(callback.ReturnType.FullQualifiedName());
            source.Append(' ');
            source.Append(callback.Name);
            source.Append('(');

            for (int i = 0; i < callback.Parameters.Length; i++)
            {
                var parameter = callback.Parameters[i];

                source.Append(parameter.ToDisplayString());
                source.Append(' ');
                source.Append(parameter.Name);

                if (parameter.RefKind == RefKind.Out)
                {
                    // Only assign default if the parameter won't be passed by-ref or copied later.
                    if (IsGodotInteropStruct(parameter.Type))
                    {
                        methodSource.Append($"        {parameter.Name} = default;\n");
                    }
                }

                if (IsByRefParameter(parameter))
                {
                    if (IsGodotInteropStruct(parameter.Type))
                    {
                        methodSource.Append("        ");
                        AppendCustomUnsafeAsPointer(methodSource, parameter, out string varName);
                        methodCallArguments.Append(varName);
                    }
                    else if (parameter.Type.IsValueType)
                    {
                        methodSource.Append("        ");
                        AppendCopyToStackAndGetPointer(methodSource, parameter, out string varName);
                        methodCallArguments.Append($"&{varName}");

                        if (parameter.RefKind is RefKind.Out or RefKind.Ref)
                        {
                            methodSourceAfterCall.Append($"        {parameter.Name} = {varName};\n");
                        }
                    }
                    else
                    {
                        // If it's a by-ref param and we can't get the pointer
                        // just pass it by-ref and let it be pinned.
                        AppendRefKind(methodCallArguments, parameter.RefKind)
                        .Append(' ')
                        .Append(parameter.Name);
                    }
                }
                else
                {
                    methodCallArguments.Append(parameter.Name);
                }

                if (i < callback.Parameters.Length - 1)
                {
                    source.Append(", ");
                    methodCallArguments.Append(", ");
                }
            }

            source.Append(")\n");
            source.Append("    {\n");

            source.Append(methodSource);
            source.Append("        ");

            if (!callback.ReturnsVoid)
            {
                if (methodSourceAfterCall.Length != 0)
                {
                    source.Append($"{callback.ReturnType.FullQualifiedName()} ret = ");
                }
                else
                {
                    source.Append("return ");
                }
            }

            source.Append($"_unmanagedCallbacks.{callback.Name}(");
            source.Append(methodCallArguments);
            source.Append(");\n");

            if (methodSourceAfterCall.Length != 0)
            {
                source.Append(methodSourceAfterCall);

                if (!callback.ReturnsVoid)
                {
                    source.Append("        return ret;\n");
                }
            }

            source.Append("    }\n\n");
        }

        source.Append("}\n");

        if (isInnerClass)
        {
            var containingType = symbol.ContainingType;

            while (containingType != null)
            {
                source.Append("}\n"); // outer class

                containingType = containingType.ContainingType;
            }
        }

        if (hasNamespace)
        {
            source.Append("\n}");
        }

        source.Append("\n\n#pragma warning restore CA1707\n");

        context.AddSource($"{data.NativeTypeSymbol.FullQualifiedName().SanitizeQualifiedNameForUniqueHint()}.generated",
                          SourceText.From(source.ToString(), Encoding.UTF8));
    }
예제 #27
0
        protected void CheckModifiersAndType(DiagnosticBag diagnostics)
        {
            Location location = this.Locations[0];
            HashSet <DiagnosticInfo> useSiteDiagnostics = null;

            if (this.DeclaredAccessibility == Accessibility.Private && (IsVirtual || IsAbstract || IsOverride))
            {
                diagnostics.Add(ErrorCode.ERR_VirtualPrivate, location, this);
            }
            else if (IsStatic && (IsOverride || IsVirtual || IsAbstract))
            {
                // A static member '{0}' cannot be marked as override, virtual, or abstract
                diagnostics.Add(ErrorCode.ERR_StaticNotVirtual, location, this);
            }
            else if (IsOverride && (IsNew || IsVirtual))
            {
                // A member '{0}' marked as override cannot be marked as new or virtual
                diagnostics.Add(ErrorCode.ERR_OverrideNotNew, location, this);
            }
            else if (IsSealed && !IsOverride)
            {
                // '{0}' cannot be sealed because it is not an override
                diagnostics.Add(ErrorCode.ERR_SealedNonOverride, location, this);
            }
            else if (IsAbstract && ContainingType.TypeKind == TypeKind.Struct)
            {
                // The modifier '{0}' is not valid for this item
                diagnostics.Add(ErrorCode.ERR_BadMemberFlag, location, SyntaxFacts.GetText(SyntaxKind.AbstractKeyword));
            }
            else if (IsVirtual && ContainingType.TypeKind == TypeKind.Struct)
            {
                // The modifier '{0}' is not valid for this item
                diagnostics.Add(ErrorCode.ERR_BadMemberFlag, location, SyntaxFacts.GetText(SyntaxKind.VirtualKeyword));
            }
            else if (IsAbstract && IsExtern)
            {
                diagnostics.Add(ErrorCode.ERR_AbstractAndExtern, location, this);
            }
            else if (IsAbstract && IsSealed)
            {
                diagnostics.Add(ErrorCode.ERR_AbstractAndSealed, location, this);
            }
            else if (IsAbstract && IsVirtual)
            {
                diagnostics.Add(ErrorCode.ERR_AbstractNotVirtual, location, this);
            }
            else if (ContainingType.IsSealed && this.DeclaredAccessibility.HasProtected() && !this.IsOverride)
            {
                diagnostics.Add(AccessCheck.GetProtectedMemberInSealedTypeError(ContainingType), location, this);
            }
            else if (ContainingType.IsStatic && !IsStatic)
            {
                diagnostics.Add(ErrorCode.ERR_InstanceMemberInStaticClass, location, Name);
            }
            else if (this.Type.SpecialType == SpecialType.System_Void)
            {
                // Diagnostic reported by parser.
            }
            else if (!this.IsNoMoreVisibleThan(this.Type, ref useSiteDiagnostics))
            {
                // Dev10 reports different errors for field-like events (ERR_BadVisFieldType) and custom events (ERR_BadVisPropertyType).
                // Both seem odd, so add a new one.

                diagnostics.Add(ErrorCode.ERR_BadVisEventType, location, this, this.Type);
            }
            else if (!this.Type.IsDelegateType() && !this.Type.IsErrorType())
            {
                // Suppressed for error types.
                diagnostics.Add(ErrorCode.ERR_EventNotDelegate, location, this);
            }
            else if (IsAbstract && !ContainingType.IsAbstract && (ContainingType.TypeKind == TypeKind.Class || ContainingType.TypeKind == TypeKind.Submission))
            {
                // '{0}' is abstract but it is contained in non-abstract class '{1}'
                diagnostics.Add(ErrorCode.ERR_AbstractInConcreteClass, location, this, ContainingType);
            }
            else if (IsVirtual && ContainingType.IsSealed)
            {
                // '{0}' is a new virtual member in sealed class '{1}'
                diagnostics.Add(ErrorCode.ERR_NewVirtualInSealed, location, this, ContainingType);
            }

            diagnostics.Add(location, useSiteDiagnostics);
        }
예제 #28
0
 public static string GetTitle(Accessibility accessibility)
 {
     return($"Change accessibility to '{SyntaxFacts.GetText(accessibility)}'");
 }
예제 #29
0
        internal static DeclarationModifiers MakeModifiers(NamedTypeSymbol containingType, SyntaxToken firstIdentifier, SyntaxTokenList modifiers, DiagnosticBag diagnostics, out bool modifierErrors)
        {
            // @t-mawind
            //   Instances do not have fields, so, unlike methods, we do not
            //   force their default access to public.
            DeclarationModifiers defaultAccess =
                (containingType.IsInterface) ? DeclarationModifiers.Public : DeclarationModifiers.Private;

            DeclarationModifiers allowedModifiers =
                DeclarationModifiers.AccessibilityMask |
                DeclarationModifiers.Const |
                DeclarationModifiers.New |
                DeclarationModifiers.ReadOnly |
                DeclarationModifiers.Static |
                DeclarationModifiers.Volatile |
                DeclarationModifiers.Fixed |
                DeclarationModifiers.Unsafe |
                DeclarationModifiers.Abstract; // filtered out later

            var errorLocation           = new SourceLocation(firstIdentifier);
            DeclarationModifiers result = ModifierUtils.MakeAndCheckNontypeMemberModifiers(
                modifiers, defaultAccess, allowedModifiers, errorLocation, diagnostics, out modifierErrors);

            if ((result & DeclarationModifiers.Abstract) != 0)
            {
                diagnostics.Add(ErrorCode.ERR_AbstractField, errorLocation);
                result &= ~DeclarationModifiers.Abstract;
            }

            if ((result & DeclarationModifiers.Fixed) != 0)
            {
                if ((result & DeclarationModifiers.Static) != 0)
                {
                    // The modifier 'static' is not valid for this item
                    diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.StaticKeyword));
                }

                if ((result & DeclarationModifiers.ReadOnly) != 0)
                {
                    // The modifier 'readonly' is not valid for this item
                    diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.ReadOnlyKeyword));
                }

                if ((result & DeclarationModifiers.Const) != 0)
                {
                    // The modifier 'const' is not valid for this item
                    diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.ConstKeyword));
                }

                if ((result & DeclarationModifiers.Volatile) != 0)
                {
                    // The modifier 'volatile' is not valid for this item
                    diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.VolatileKeyword));
                }

                result &= ~(DeclarationModifiers.Static | DeclarationModifiers.ReadOnly | DeclarationModifiers.Const | DeclarationModifiers.Volatile);
                Debug.Assert((result & ~(DeclarationModifiers.AccessibilityMask | DeclarationModifiers.Fixed | DeclarationModifiers.Unsafe | DeclarationModifiers.New)) == 0);
            }


            if ((result & DeclarationModifiers.Const) != 0)
            {
                if ((result & DeclarationModifiers.Static) != 0)
                {
                    // The constant '{0}' cannot be marked static
                    diagnostics.Add(ErrorCode.ERR_StaticConstant, errorLocation, firstIdentifier.ValueText);
                }

                if ((result & DeclarationModifiers.ReadOnly) != 0)
                {
                    // The modifier 'readonly' is not valid for this item
                    diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.ReadOnlyKeyword));
                }

                if ((result & DeclarationModifiers.Volatile) != 0)
                {
                    // The modifier 'volatile' is not valid for this item
                    diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.VolatileKeyword));
                }

                if ((result & DeclarationModifiers.Unsafe) != 0)
                {
                    // The modifier 'unsafe' is not valid for this item
                    diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.UnsafeKeyword));
                }

                result |= DeclarationModifiers.Static; // "constants are considered static members"
            }
            else
            {
                // NOTE: always cascading on a const, so suppress.
                // NOTE: we're being a bit sneaky here - we're using the containingType rather than this symbol
                // to determine whether or not unsafe is allowed.  Since this symbol and the containing type are
                // in the same compilation, it won't make a difference.  We do, however, have to pass the error
                // location explicitly.
                containingType.CheckUnsafeModifier(result, errorLocation, diagnostics);
            }

            return(result);
        }
예제 #30
0
        public void AnalyzeNode(SyntaxNodeAnalysisContext context)
        {
            var syntaxTree        = context.Node.SyntaxTree;
            var cancellationToken = context.CancellationToken;
            var node = context.Node;

            var optionSet = context.Options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult();

            if (optionSet == null)
            {
                return;
            }

            var option = optionSet.GetOption(CSharpCodeStyleOptions.PreferBraces);

            if (!option.Value)
            {
                return;
            }

            var descriptor = GetDescriptorWithSeverity(option.Notification.Value);

            if (node.IsKind(SyntaxKind.IfStatement))
            {
                var ifStatement = (IfStatementSyntax)node;
                if (AnalyzeIfStatement(ifStatement))
                {
                    context.ReportDiagnostic(Diagnostic.Create(descriptor,
                                                               ifStatement.IfKeyword.GetLocation(),
                                                               SyntaxFacts.GetText(SyntaxKind.IfKeyword)));
                }
            }

            if (node.IsKind(SyntaxKind.ElseClause))
            {
                var elseClause = (ElseClauseSyntax)node;
                if (AnalyzeElseClause(elseClause))
                {
                    context.ReportDiagnostic(Diagnostic.Create(descriptor,
                                                               elseClause.ElseKeyword.GetLocation(),
                                                               SyntaxFacts.GetText(SyntaxKind.ElseKeyword)));
                }
            }

            if (node.IsKind(SyntaxKind.ForStatement))
            {
                var forStatement = (ForStatementSyntax)node;
                if (AnalyzeForStatement(forStatement))
                {
                    context.ReportDiagnostic(Diagnostic.Create(descriptor,
                                                               forStatement.ForKeyword.GetLocation(),
                                                               SyntaxFacts.GetText(SyntaxKind.ForKeyword)));
                }
            }

            if (node.IsKind(SyntaxKind.ForEachStatement) || node.IsKind(SyntaxKind.ForEachVariableStatement))
            {
                var forEachStatement = (CommonForEachStatementSyntax)node;
                if (AnalyzeForEachStatement(forEachStatement))
                {
                    context.ReportDiagnostic(Diagnostic.Create(descriptor,
                                                               forEachStatement.ForEachKeyword.GetLocation(),
                                                               SyntaxFacts.GetText(SyntaxKind.ForEachKeyword)));
                }
            }

            if (node.IsKind(SyntaxKind.WhileStatement))
            {
                var whileStatement = (WhileStatementSyntax)node;
                if (AnalyzeWhileStatement(whileStatement))
                {
                    context.ReportDiagnostic(Diagnostic.Create(descriptor,
                                                               whileStatement.WhileKeyword.GetLocation(),
                                                               SyntaxFacts.GetText(SyntaxKind.WhileKeyword)));
                }
            }

            if (node.IsKind(SyntaxKind.DoStatement))
            {
                var doStatement = (DoStatementSyntax)node;
                if (AnalyzeDoStatement(doStatement))
                {
                    context.ReportDiagnostic(Diagnostic.Create(descriptor,
                                                               doStatement.DoKeyword.GetLocation(),
                                                               SyntaxFacts.GetText(SyntaxKind.DoKeyword)));
                }
            }

            if (node.IsKind(SyntaxKind.UsingStatement))
            {
                var usingStatement = (UsingStatementSyntax)context.Node;
                if (AnalyzeUsingStatement(usingStatement))
                {
                    context.ReportDiagnostic(Diagnostic.Create(descriptor,
                                                               usingStatement.UsingKeyword.GetLocation(),
                                                               SyntaxFacts.GetText(SyntaxKind.UsingKeyword)));
                }
            }

            if (node.IsKind(SyntaxKind.LockStatement))
            {
                var lockStatement = (LockStatementSyntax)context.Node;
                if (AnalyzeLockStatement(lockStatement))
                {
                    context.ReportDiagnostic(Diagnostic.Create(descriptor,
                                                               lockStatement.LockKeyword.GetLocation(),
                                                               SyntaxFacts.GetText(SyntaxKind.LockKeyword)));
                }
            }
        }