public static void ComputeRefactoring(RefactoringContext context, VariableDeclaratorSyntax variableDeclarator)
        {
            if (variableDeclarator.Initializer != null)
            {
                return;
            }

            if (!variableDeclarator.IsParentKind(SyntaxKind.VariableDeclaration))
            {
                return;
            }

            if (!(variableDeclarator.Parent.Parent is FieldDeclarationSyntax fieldDeclaration))
            {
                return;
            }

            if (fieldDeclaration.Modifiers.ContainsAny(SyntaxKind.StaticKeyword, SyntaxKind.ConstKeyword))
            {
                return;
            }

            if (!(fieldDeclaration.Parent is TypeDeclarationSyntax typeDeclaration))
            {
                return;
            }

            if (!typeDeclaration.IsKind(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration))
            {
                return;
            }

            if (!typeDeclaration
                .Members
                .Any(f => f.Kind() == SyntaxKind.ConstructorDeclaration && !((ConstructorDeclarationSyntax)f).Modifiers.Contains(SyntaxKind.StaticKeyword)))
            {
                return;
            }

            context.RegisterRefactoring(
                "Initialize field from constructor",
                cancellationToken => RefactorAsync(context.Document, variableDeclarator, typeDeclaration, cancellationToken));
        }
예제 #2
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.ChangeTypeOfLocalVariable))
            {
                return;
            }

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

            VariableDeclaratorSyntax variableDeclarator = root
                                                          .FindNode(context.Span, getInnermostNodeForTie: true)?
                                                          .FirstAncestorOrSelf <VariableDeclaratorSyntax>();

            Debug.Assert(variableDeclarator != null, $"{nameof(variableDeclarator)} is null");

            if (variableDeclarator == null)
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.CannotAssignMethodGroupToImplicitlyTypedVariable:
                case CompilerDiagnosticIdentifiers.NoOverloadMatchesDelegate:
                case CompilerDiagnosticIdentifiers.MethodHasWrongReturnType:
                {
                    if (!variableDeclarator.IsParentKind(SyntaxKind.VariableDeclaration))
                    {
                        break;
                    }

                    var variableDeclaration = (VariableDeclarationSyntax)variableDeclarator.Parent;

                    ExpressionSyntax value = variableDeclarator.Initializer?.Value;

                    if (value == null)
                    {
                        break;
                    }

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

                    SymbolInfo symbolInfo = semanticModel.GetSymbolInfo(value, context.CancellationToken);

                    if (symbolInfo.Symbol != null)
                    {
                        ComputeCodeFix(context, diagnostic, variableDeclarator, symbolInfo.Symbol, semanticModel);
                    }
                    else
                    {
                        foreach (ISymbol candidateSymbol in symbolInfo.CandidateSymbols)
                        {
                            ComputeCodeFix(context, diagnostic, variableDeclarator, candidateSymbol, semanticModel);
                        }
                    }

                    break;
                }
                }
            }
        }