Example #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)));
            }
        }
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var(document, textSpan, cancellationToken) = context;

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

            if (!MakeLocalFunctionStaticHelper.IsStaticLocalFunctionSupported(syntaxTree))
            {
                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.TryGetCaputuredSymbolsAndCheckApplicability(localFunction, semanticModel, out var captures))
            {
                context.RegisterRefactoring(new MyCodeAction(
                                                FeaturesResources.Make_local_function_static,
                                                c => MakeLocalFunctionStaticHelper.MakeLocalFunctionStaticAsync(document, localFunction, captures, c)));
            }
        }
 protected override void InitializeWorker(AnalysisContext context)
 => context.RegisterCompilationStartAction(context =>
 {
     if (MakeLocalFunctionStaticHelper.IsStaticLocalFunctionSupported(context.Compilation.LanguageVersion()))
     {
         context.RegisterSyntaxNodeAction(AnalyzeSyntax, SyntaxKind.LocalFunctionStatement);
     }
 });
        // 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);
                }
            }
        }
Example #5
0
        private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
        {
            var localFunction = (LocalFunctionStatementSyntax)context.Node;

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

            var syntaxTree = context.Node.SyntaxTree;

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

            var cancellationToken = context.CancellationToken;
            var option            = context.Options.GetOption(
                CSharpCodeStyleOptions.PreferStaticLocalFunction,
                syntaxTree,
                cancellationToken
                );

            if (!option.Value)
            {
                return;
            }

            var semanticModel = context.SemanticModel;

            if (
                MakeLocalFunctionStaticHelper.CanMakeLocalFunctionStaticBecauseNoCaptures(
                    localFunction,
                    semanticModel
                    )
                )
            {
                context.ReportDiagnostic(
                    DiagnosticHelper.Create(
                        Descriptor,
                        localFunction.Identifier.GetLocation(),
                        option.Notification.Severity,
                        additionalLocations: ImmutableArray.Create(localFunction.GetLocation()),
                        properties: null
                        )
                    );
            }
        }
        private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
        {
            var localFunction = (LocalFunctionStatementSyntax)context.Node;

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

            var syntaxTree = context.Node.SyntaxTree;

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

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

            if (optionSet == null)
            {
                return;
            }

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

            if (!option.Value)
            {
                return;
            }

            var semanticModel = context.SemanticModel;

            if (MakeLocalFunctionStaticHelper.TryGetCaputuredSymbols(localFunction, semanticModel, out var captures) && captures.Length == 0)
            {
                context.ReportDiagnostic(DiagnosticHelper.Create(
                                             Descriptor,
                                             localFunction.Identifier.GetLocation(),
                                             option.Notification.Severity,
                                             additionalLocations: ImmutableArray.Create(localFunction.GetLocation()),
                                             properties: null));
            }
        }