public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var(document, _, cancellationToken) = context;
            var declaration = await context.TryGetRelevantNodeAsync <TLocalDeclaration>().ConfigureAwait(false);

            if (declaration == null)
            {
                return;
            }

            var syntaxFacts = document.GetRequiredLanguageService <ISyntaxFactsService>();
            var variables   = syntaxFacts.GetVariablesOfLocalDeclarationStatement(declaration);

            if (variables.Count != 1)
            {
                return;
            }

            var service = document.GetRequiredLanguageService <IMoveDeclarationNearReferenceService>();

            if (!await service.CanMoveDeclarationNearReferenceAsync(document, declaration, cancellationToken).ConfigureAwait(false))
            {
                return;
            }

            context.RegisterRefactoring(
                CodeAction.CreateWithPriority(
                    CodeActionPriority.Low,
                    FeaturesResources.Move_declaration_near_reference,
                    c => MoveDeclarationNearReferenceAsync(document, declaration, c),
                    nameof(FeaturesResources.Move_declaration_near_reference)),
                declaration.Span);
        }
 public override Task RegisterCodeFixesAsync(CodeFixContext context)
 {
     context.RegisterCodeFix(
         CodeAction.CreateWithPriority(
             CodeActionPriority.Low,
             CSharpAnalyzersResources.Use_pattern_matching,
             GetDocumentUpdater(context),
             nameof(CSharpAnalyzersResources.Use_pattern_matching)),
         context.Diagnostics);
     return(Task.CompletedTask);
 }
Пример #3
0
        private async Task CheckItemsAsync(
            CodeFixContext context, SyntaxToken nameToken, bool isGeneric,
            CompletionList completionList, WordSimilarityChecker similarityChecker)
        {
            var document          = context.Document;
            var cancellationToken = context.CancellationToken;

            var onlyConsiderGenerics = isGeneric;
            var results = new MultiDictionary <double, string>();

            foreach (var item in completionList.ItemsList)
            {
                if (onlyConsiderGenerics && !IsGeneric(item))
                {
                    continue;
                }

                var candidateText = item.FilterText;
                if (!similarityChecker.AreSimilar(candidateText, out var matchCost))
                {
                    continue;
                }

                var insertionText = await GetInsertionTextAsync(document, item, cancellationToken : cancellationToken).ConfigureAwait(false);

                results.Add(matchCost, insertionText);
            }

            var nameText    = nameToken.ValueText;
            var codeActions = results.OrderBy(kvp => kvp.Key)
                              .SelectMany(kvp => kvp.Value.Order())
                              .Where(t => t != nameText)
                              .Take(3)
                              .Select(n => CreateCodeAction(nameToken, nameText, n, document))
                              .ToImmutableArrayOrEmpty <CodeAction>();

            if (codeActions.Length > 1)
            {
                // Wrap the spell checking actions into a single top level suggestion
                // so as to not clutter the list.
                context.RegisterCodeFix(
                    CodeAction.CreateWithPriority(
                        CodeActionPriority.Low,
                        string.Format(FeaturesResources.Fix_typo_0, nameText),
                        codeActions,
                        isInlinable: true),
                    context.Diagnostics);
            }
            else
            {
                context.RegisterFixes(codeActions, context.Diagnostics);
            }
        }
        public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var literalExpression = await context.TryGetRelevantNodeAsync <TStringExpressionSyntax>().ConfigureAwait(false);

            if (literalExpression == null || !IsAppropriateLiteralKind(literalExpression))
            {
                return;
            }

            var(document, _, cancellationToken) = context;

            var charService = document.GetRequiredLanguageService <IVirtualCharLanguageService>();

            using var _ = ArrayBuilder <SyntaxToken> .GetInstance(out var subStringTokens);

            // First, ensure that we understand all text parts of the interpolation.
            AddSubStringTokens(literalExpression, subStringTokens);
            foreach (var subToken in subStringTokens)
            {
                var chars = charService.TryConvertToVirtualChars(subToken);
                if (chars.IsDefault)
                {
                    return;
                }
            }

            // Note: This is a generally useful feature on strings.  But it's not likely to be something
            // people want to use a lot.  Make low priority so it doesn't interfere with more
            // commonly useful refactorings.

            if (IsVerbatim(literalExpression))
            {
                // always offer to convert from verbatim string to normal string.
                context.RegisterRefactoring(CodeAction.CreateWithPriority(
                                                CodeActionPriority.Low,
                                                CSharpFeaturesResources.Convert_to_regular_string,
                                                c => ConvertToRegularStringAsync(document, literalExpression, c),
                                                nameof(CSharpFeaturesResources.Convert_to_regular_string)));
            }
            else if (ContainsSimpleEscape(charService, subStringTokens))
            {
                // Offer to convert to a verbatim string if the normal string contains simple
                // escapes that can be directly embedded in the verbatim string.
                context.RegisterRefactoring(CodeAction.CreateWithPriority(
                                                CodeActionPriority.Low,
                                                CSharpFeaturesResources.Convert_to_verbatim_string,
                                                c => ConvertToVerbatimStringAsync(document, literalExpression, c),
                                                nameof(CSharpFeaturesResources.Convert_to_verbatim_string)));
            }
        }
Пример #5
0
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var(document, span, cancellationToken) = context;
            if (!span.IsEmpty)
            {
                return;
            }

            if (!IsApplication(document.Project.CompilationOptions !))
            {
                return;
            }

            var position = span.Start;
            var root     = (CompilationUnitSyntax)await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            if (!root.IsTopLevelProgram())
            {
                return;
            }

            var acceptableLocation = GetUseProgramMainDiagnosticLocation(root, isHidden: true);

            if (!acceptableLocation.SourceSpan.IntersectsWith(position))
            {
                return;
            }

            var optionSet = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);

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

            var compilation = await document.Project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false);

            if (!CanOfferUseProgramMain(option, root, compilation, forAnalyzer: false))
            {
                return;
            }

            context.RegisterRefactoring(CodeAction.CreateWithPriority(
                                            CodeActionPriority.Low,
                                            CSharpAnalyzersResources.Convert_to_Program_Main_style_program,
                                            c => ConvertToProgramMainAsync(document, c),
                                            nameof(CSharpAnalyzersResources.Convert_to_Program_Main_style_program)));
        }
Пример #6
0
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var(document, _, cancellationToken) = context;

            var typeAndPriority =
                await GetRelevantTypeFromHeaderAsync(context).ConfigureAwait(false) ??
                await GetRelevantTypeFromMethodAsync(context).ConfigureAwait(false);

            if (typeAndPriority == null)
            {
                return;
            }

            var(type, priority) = typeAndPriority.Value;

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

            var compilation = semanticModel.Compilation;

            var debuggerAttributeTypeSymbol = compilation.GetTypeByMetadataName("System.Diagnostics.DebuggerDisplayAttribute");

            if (debuggerAttributeTypeSymbol is null)
            {
                return;
            }

            var typeSymbol = (INamedTypeSymbol)semanticModel.GetRequiredDeclaredSymbol(type, context.CancellationToken);

            if (typeSymbol.IsStatic || !IsClassOrStruct(typeSymbol))
            {
                return;
            }

            if (HasDebuggerDisplayAttribute(typeSymbol, compilation))
            {
                return;
            }

            context.RegisterRefactoring(CodeAction.CreateWithPriority(
                                            priority,
                                            FeaturesResources.Add_DebuggerDisplay_attribute,
                                            c => ApplyAsync(document, type, debuggerAttributeTypeSymbol, c),
                                            nameof(FeaturesResources.Add_DebuggerDisplay_attribute)));
        }
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var(document, span, cancellationToken) = context;

            // can only suggest moving to top level statement on c# 9 or above.
            if (document.Project.ParseOptions !.LanguageVersion() < LanguageVersion.CSharp9 ||
                !IsApplication(document.Project.CompilationOptions !))
            {
                return;
            }

            var methodDeclaration = await context.TryGetRelevantNodeAsync <MethodDeclarationSyntax>().ConfigureAwait(false);

            if (methodDeclaration is null)
            {
                return;
            }

            var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);

            var option = options.GetOption(CSharpCodeStyleOptions.PreferTopLevelStatements);

            if (!CanOfferUseTopLevelStatements(option, forAnalyzer: false))
            {
                return;
            }

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

            var compilation = semanticModel.Compilation;

            if (!IsProgramMainMethod(semanticModel, methodDeclaration, GetMainTypeName(compilation), cancellationToken, out var canConvert) ||
                !canConvert)
            {
                return;
            }

            context.RegisterRefactoring(CodeAction.CreateWithPriority(
                                            CodeActionPriority.Low,
                                            CSharpAnalyzersResources.Convert_to_top_level_statements,
                                            c => ConvertToTopLevelStatementsAsync(document, methodDeclaration, context.Options, c),
                                            nameof(CSharpAnalyzersResources.Convert_to_top_level_statements)));
        }
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var(document, _, cancellationToken) = context;

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

            if (root is null)
            {
                return;
            }

            var token = root.FindToken(context.Span.Start);

            if (!context.Span.IntersectsWith(token.Span))
            {
                return;
            }

            var syntaxKinds = document.GetRequiredLanguageService <ISyntaxKindsService>();

            if (token.RawKind != syntaxKinds.StringLiteralToken)
            {
                return;
            }

            var literalExpression = token.GetRequiredParent();

            // Check the string literal for errors.  This will ensure that we do not try to fixup an incomplete string.
            if (literalExpression.GetDiagnostics().Any(d => d.Severity == DiagnosticSeverity.Error))
            {
                return;
            }

            if (!token.Text.Contains('{') && !token.Text.Contains('}'))
            {
                return;
            }

            var syntaxFacts = document.GetRequiredLanguageService <ISyntaxFactsService>();

            if (!syntaxFacts.SupportsConstantInterpolatedStrings(document.Project.ParseOptions !))
            {
                // If there is a const keyword, do not offer the refactoring (an interpolated string is not const)
                var declarator = literalExpression.FirstAncestorOrSelf <SyntaxNode>(syntaxFacts.IsVariableDeclarator);
                if (declarator != null)
                {
                    var generator = SyntaxGenerator.GetGenerator(document);
                    if (generator.GetModifiers(declarator).IsConst)
                    {
                        return;
                    }
                }

                // Attributes also only allow constant values.
                var attribute = literalExpression.FirstAncestorOrSelf <SyntaxNode>(syntaxFacts.IsAttribute);
                if (attribute != null)
                {
                    return;
                }
            }

            context.RegisterRefactoring(
                CodeAction.CreateWithPriority(
                    CodeActionPriority.Low,
                    FeaturesResources.Convert_to_interpolated_string,
                    _ => UpdateDocumentAsync(document, root, token),
                    nameof(FeaturesResources.Convert_to_interpolated_string)),
                literalExpression.Span);
        }