Exemplo n.º 1
0
        private static Diagnostic?AnalyzeSyntax(
            SemanticModel semanticModel, CodeStyleOption2 <ExpressionBodyPreference> option,
            LambdaExpressionSyntax declaration, CancellationToken cancellationToken)
        {
            if (UseExpressionBodyForLambdaHelpers.CanOfferUseExpressionBody(option.Value, declaration, declaration.GetLanguageVersion()))
            {
                var location = GetDiagnosticLocation(declaration);

                var additionalLocations = ImmutableArray.Create(declaration.GetLocation());
                var properties          = ImmutableDictionary <string, string?> .Empty;
                return(DiagnosticHelper.Create(
                           s_useExpressionBodyForLambda,
                           location, option.Notification.Severity, additionalLocations, properties));
            }

            if (UseExpressionBodyForLambdaHelpers.CanOfferUseBlockBody(semanticModel, option.Value, declaration, cancellationToken))
            {
                // They have an expression body.  Create a diagnostic to convert it to a block
                // if they don't want expression bodies for this member.
                var location = GetDiagnosticLocation(declaration);

                var properties          = ImmutableDictionary <string, string?> .Empty;
                var additionalLocations = ImmutableArray.Create(declaration.GetLocation());
                return(DiagnosticHelper.Create(
                           s_useBlockBodyForLambda,
                           location, option.Notification.Severity, additionalLocations, properties));
            }

            return(null);
        }
Exemplo n.º 2
0
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document          = context.Document;
            var cancellationToken = context.CancellationToken;

            var optionProvider = await document.GetAnalyzerOptionsProviderAsync(cancellationToken).ConfigureAwait(false);

            var optionValue = UseExpressionBodyForLambdaHelpers.GetCodeStyleOption(optionProvider);

            var severity = UseExpressionBodyForLambdaHelpers.GetOptionSeverity(optionValue);

            switch (severity)
            {
            case ReportDiagnostic.Suppress:
            case ReportDiagnostic.Hidden:
                // if the severity is Hidden that's equivalent to 'refactoring only', so we want
                // to try to compute the refactoring here.
                //
                // If the severity is 'suppress', that means the user doesn't want the actual
                // analyzer to run here.  However, we can still check to see if we could offer
                // the feature here as a refactoring.
                await ComputeRefactoringsAsync(context, optionValue.Value, analyzerActive : false).ConfigureAwait(false);

                return;

            case ReportDiagnostic.Error:
            case ReportDiagnostic.Warn:
            case ReportDiagnostic.Info:
                // User has this option set at a level where we want it checked by the
                // DiagnosticAnalyser and not the CodeRefactoringProvider.  However, we still
                // want to check if we want to offer the *reverse* refactoring here in this
                // single location.
                //
                // For example, say this is the "use expression body" feature.  If the user says
                // they always prefer expression-bodies (with warning level), then we want the
                // analyzer to always be checking for that.  However, we still want to offer the
                // refactoring to flip their code to use a block body here, just in case that
                // was something they wanted to do as a one off (i.e. before adding new
                // statements.
                //
                // TODO(cyrusn): Should we only do this for warn/info?  Argument could be made
                // that we shouldn't even offer to refactor in the reverse direction if it will
                // just cause an error.  That said, maybe this is just an intermediary step, and
                // we shouldn't really be blocking the user from making it.
                await ComputeRefactoringsAsync(context, optionValue.Value, analyzerActive : true).ConfigureAwait(false);

                return;
            }
        }
Exemplo n.º 3
0
        private static void AnalyzeIfEnabled(SyntaxNodeAnalysisContext context)
        {
            var analyzerOptions = context.Options;
            var syntaxTree      = context.SemanticModel.SyntaxTree;
            var optionValue     = UseExpressionBodyForLambdaHelpers.GetCodeStyleOption(analyzerOptions.GetAnalyzerOptions(syntaxTree));
            var severity        = UseExpressionBodyForLambdaHelpers.GetOptionSeverity(optionValue);

            switch (severity)
            {
            case ReportDiagnostic.Error:
            case ReportDiagnostic.Warn:
            case ReportDiagnostic.Info:
                break;

            default:
                // don't analyze if it's any other value.
                return;
            }

            AnalyzeSyntax(context, optionValue);
        }
Exemplo n.º 4
0
        private static async Task <ImmutableArray <CodeAction> > ComputeRefactoringsAsync(
            Document document, TextSpan span, ExpressionBodyPreference option, CancellationToken cancellationToken)
        {
            var lambdaNode = await document.TryGetRelevantNodeAsync <LambdaExpressionSyntax>(span, cancellationToken).ConfigureAwait(false);

            if (lambdaNode == null)
            {
                return(ImmutableArray <CodeAction> .Empty);
            }

            var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            using var resultDisposer = ArrayBuilder <CodeAction> .GetInstance(out var result);

            if (UseExpressionBodyForLambdaHelpers.CanOfferUseExpressionBody(option, lambdaNode, root.GetLanguageVersion()))
            {
                var title = UseExpressionBodyForLambdaHelpers.UseExpressionBodyTitle.ToString();
                result.Add(CodeAction.Create(
                               title,
                               c => UpdateDocumentAsync(
                                   document, root, lambdaNode, c),
                               title));
            }

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

            if (UseExpressionBodyForLambdaHelpers.CanOfferUseBlockBody(semanticModel, option, lambdaNode, cancellationToken))
            {
                var title = UseExpressionBodyForLambdaHelpers.UseBlockBodyTitle.ToString();
                result.Add(CodeAction.Create(
                               title,
                               c => UpdateDocumentAsync(
                                   document, root, lambdaNode, c),
                               title));
            }

            return(result.ToImmutable());
        }