Exemple #1
0
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var(document, textSpan, cancellationToken) = context;

            var syntaxTree = (await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false)) !;

            if (!MakeLocalFunctionStaticHelper.IsStaticLocalFunctionSupported(((CSharpParseOptions)syntaxTree.Options).LanguageVersion))
            {
                return;
            }

            var localFunction = await context.TryGetRelevantNodeAsync <LocalFunctionStatementSyntax>().ConfigureAwait(false);

            if (localFunction == null)
            {
                return;
            }

            if (localFunction.Modifiers.Any(SyntaxKind.StaticKeyword))
            {
                return;
            }

            var semanticModel = (await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false)) !;

            if (MakeLocalFunctionStaticHelper.CanMakeLocalFunctionStaticByRefactoringCaptures(localFunction, semanticModel, out var captures))
            {
                context.RegisterRefactoring(new MyCodeAction(
                                                c => MakeLocalFunctionStaticCodeFixHelper.MakeLocalFunctionStaticAsync(document, localFunction, captures, c)));
            }
        }
        // The purpose of this wrapper is to share some common logic between FixOne and FixAll.
        // The main reason we chose this approach over the typical "FixOne calls FixAll" approach is
        // to avoid duplicate code.
        private static async Task WrapFixAsync(
            Document document,
            ImmutableArray <Diagnostic> diagnostics,
            Func <Document, LocalFunctionStatementSyntax, ImmutableArray <ISymbol>, Task> fixer,
            CancellationToken cancellationToken
            )
        {
            var root = (
                await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false)
                ) !;

            // Even when the language version doesn't support staic local function, the compiler will still
            // generate this error. So we need to check to make sure we don't provide incorrect fix.
            if (!MakeLocalFunctionStaticHelper.IsStaticLocalFunctionSupported(root.SyntaxTree))
            {
                return;
            }

            // Find all unique local functions that contain the error.
            var localFunctions = diagnostics
                                 .Select(
                d =>
                root.FindNode(d.Location.SourceSpan)
                .AncestorsAndSelf()
                .OfType <LocalFunctionStatementSyntax>()
                .FirstOrDefault()
                )
                                 .WhereNotNull()
                                 .Distinct()
                                 .ToImmutableArrayOrEmpty();

            if (localFunctions.Length == 0)
            {
                return;
            }

            var semanticModel = (
                await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false)
                ) !;

            foreach (var localFunction in localFunctions)
            {
                if (
                    MakeLocalFunctionStaticHelper.CanMakeLocalFunctionStaticByRefactoringCaptures(
                        localFunction,
                        semanticModel,
                        out var captures
                        )
                    )
                {
                    await fixer(document, localFunction, captures).ConfigureAwait(false);
                }
            }
        }