private async Task <Tuple <CodeAction, string> > GetCodeActionAsync( Document document, TextSpan textSpan, CancellationToken cancellationToken) { var options = document.Project.Solution.Workspace.Options; try { var result = await service.ExtractMethodAsync( document, textSpan, options, cancellationToken).ConfigureAwait(false); if (result.Succeeded || result.SucceededWithSuggestion) { var description = options.GetOption(ExtractMethodOptions.AllowMovingDeclaration, document.Project.Language) ? GettextCatalog.GetString("Extract Method + Local") : GettextCatalog.GetString("Extract Method"); var codeAction = new DocumentChangeAction(textSpan, DiagnosticSeverity.Info, description, (c) => AddRenameAnnotationAsync(result.Document, result.InvocationNameToken, c)); var methodBlock = result.MethodDeclarationNode; return(Tuple.Create <CodeAction, string>(codeAction, methodBlock.ToString())); } } catch (Exception) { // currently the extract method refactoring crashes often. Ignore the roslyn issues for now. } return(null); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var document = context.Document; var span = context.Span; var cancellationToken = context.CancellationToken; var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var optionSet = document.Project.Solution.Workspace.Options; string diagnosticId; var node = GetNodeToSimplify(root, model, span, optionSet, out diagnosticId, cancellationToken); if (node == null) { return; } var id = GetCodeActionId(diagnosticId, node.ToString()); var title = id; var codeAction = new DocumentChangeAction(node.Span, DiagnosticSeverity.Warning, title, (c) => SimplifyTypeNameAsync(document, node, c)); context.RegisterCodeFix(codeAction, context.Diagnostics); }
private async Task<Tuple<CodeAction, string>> GetCodeActionAsync( Document document, TextSpan textSpan, CancellationToken cancellationToken) { var options = document.Project.Solution.Workspace.Options; try { var result = await service.ExtractMethodAsync( document, textSpan, options, cancellationToken).ConfigureAwait(false); if (result.Succeeded || result.SucceededWithSuggestion) { var description = options.GetOption(ExtractMethodOptions.AllowMovingDeclaration, document.Project.Language) ? GettextCatalog.GetString ("Extract Method + Local") : GettextCatalog.GetString ("Extract Method"); var codeAction = new DocumentChangeAction(textSpan, DiagnosticSeverity.Info, description, (c) => AddRenameAnnotationAsync(result.Document, result.InvocationNameToken, c)); var methodBlock = result.MethodDeclarationNode; return Tuple.Create<CodeAction, string>(codeAction, methodBlock.ToString()); } } catch (Exception) { // currently the extract method refactoring crashes often. Ignore the roslyn issues for now. } return null; }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var document = context.Document; var span = context.Span; var diagnostics = context.Diagnostics; var cancellationToken = context.CancellationToken; var project = document.Project; var diagnostic = diagnostics.First(); var model = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false); if (model.IsFromGeneratedCode(context.CancellationToken)) { return; } var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var ancestors = root.FindToken(span.Start, findInsideTrivia: true).GetAncestors <SyntaxNode>(); if (!ancestors.Any()) { return; } var node = ancestors.FirstOrDefault(n => n.Span.Contains(span) && n != root); if (node == null) { return; } var placeSystemNamespaceFirst = true; //document.Project.Solution.Workspace.Options.GetOption(Microsoft.CodeAnalysis.Shared.Options.OrganizerOptions.PlaceSystemNamespaceFirst, document.Project.Language); if (!cancellationToken.IsCancellationRequested) { if (this.CanAddImport(node, cancellationToken)) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); //var containingType = semanticModel.GetEnclosingNamedType(node.SpanStart, cancellationToken); //var containingTypeOrAssembly = containingType ?? (ISymbol)semanticModel.Compilation.Assembly; var namespacesInScope = this.GetNamespacesInScope(semanticModel, node, cancellationToken); var matchingTypesNamespaces = await this.GetNamespacesForMatchingTypesAsync(project, diagnostic, node, semanticModel, namespacesInScope, cancellationToken).ConfigureAwait(false); var matchingTypes = await this.GetMatchingTypesAsync(project, diagnostic, node, semanticModel, namespacesInScope, cancellationToken).ConfigureAwait(false); var matchingNamespaces = await this.GetNamespacesForMatchingNamespacesAsync(project, diagnostic, node, semanticModel, namespacesInScope, cancellationToken).ConfigureAwait(false); var matchingExtensionMethodsNamespaces = await this.GetNamespacesForMatchingExtensionMethodsAsync(project, diagnostic, node, semanticModel, namespacesInScope, cancellationToken).ConfigureAwait(false); var matchingFieldsAndPropertiesAsync = await this.GetNamespacesForMatchingFieldsAndPropertiesAsync(project, diagnostic, node, semanticModel, namespacesInScope, cancellationToken).ConfigureAwait(false); var queryPatternsNamespaces = await this.GetNamespacesForQueryPatternsAsync(project, diagnostic, node, semanticModel, namespacesInScope, cancellationToken).ConfigureAwait(false); if (matchingTypesNamespaces != null || matchingNamespaces != null || matchingExtensionMethodsNamespaces != null || matchingFieldsAndPropertiesAsync != null || queryPatternsNamespaces != null || matchingTypes != null) { matchingTypesNamespaces = matchingTypesNamespaces ?? SpecializedCollections.EmptyList <INamespaceSymbol>(); matchingNamespaces = matchingNamespaces ?? SpecializedCollections.EmptyList <INamespaceSymbol>(); matchingExtensionMethodsNamespaces = matchingExtensionMethodsNamespaces ?? SpecializedCollections.EmptyList <INamespaceSymbol>(); matchingFieldsAndPropertiesAsync = matchingFieldsAndPropertiesAsync ?? SpecializedCollections.EmptyList <INamespaceSymbol>(); queryPatternsNamespaces = queryPatternsNamespaces ?? SpecializedCollections.EmptyList <INamespaceSymbol>(); matchingTypes = matchingTypes ?? SpecializedCollections.EmptyList <ITypeSymbol>(); var proposedImports = matchingTypesNamespaces.Cast <INamespaceOrTypeSymbol> () .Concat(matchingNamespaces.Cast <INamespaceOrTypeSymbol> ()) .Concat(matchingExtensionMethodsNamespaces.Cast <INamespaceOrTypeSymbol> ()) .Concat(matchingFieldsAndPropertiesAsync.Cast <INamespaceOrTypeSymbol> ()) .Concat(queryPatternsNamespaces.Cast <INamespaceOrTypeSymbol> ()) .Concat(matchingTypes.Cast <INamespaceOrTypeSymbol> ()) .Distinct() .Where(NotNull) .Where(NotGlobalNamespace) .ToList(); proposedImports.Sort(INamespaceOrTypeSymbolExtensions.CompareNamespaceOrTypeSymbols); proposedImports = proposedImports.Take(8).ToList(); if (proposedImports.Count > 0) { cancellationToken.ThrowIfCancellationRequested(); foreach (var import in proposedImports) { var action = new DocumentChangeAction( node.Span, DiagnosticSeverity.Error, this.GetDescription(import, semanticModel, node), (c) => this.AddImportAsync(node, import, document, placeSystemNamespaceFirst, cancellationToken) ); context.RegisterCodeFix(action, diagnostic); } } } } } }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var document = context.Document; var span = context.Span; var diagnostics = context.Diagnostics; var cancellationToken = context.CancellationToken; var project = document.Project; var diagnostic = diagnostics.First(); var model = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait (false); if (model.IsFromGeneratedCode (context.CancellationToken)) return; var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var node = root.FindToken(span.Start).GetAncestors<SyntaxNode>().First(n => n.Span.Contains(span)); // Has to be a simple identifier or generic name. if (node != null && CanFullyQualify(diagnostic, ref node)) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var matchingTypes = await this.GetMatchingTypesAsync(project, semanticModel, node, cancellationToken).ConfigureAwait(false); var matchingNamespaces = await this.GetMatchingNamespacesAsync(project, semanticModel, node, cancellationToken).ConfigureAwait(false); if (matchingTypes != null || matchingNamespaces != null) { matchingTypes = matchingTypes ?? SpecializedCollections.EmptyEnumerable<ISymbol>(); matchingNamespaces = matchingNamespaces ?? SpecializedCollections.EmptyEnumerable<ISymbol>(); var matchingTypeContainers = FilterAndSort(GetContainers(matchingTypes, semanticModel.Compilation)); var matchingNamespaceContainers = FilterAndSort(GetContainers(matchingNamespaces, semanticModel.Compilation)); var proposedContainers = matchingTypeContainers.Concat(matchingNamespaceContainers) .Distinct() .Take(8); foreach (var container in proposedContainers) { var containerName = RoslynCompletionData.SafeMinimalDisplayString (container, semanticModel, node.SpanStart); string name; int arity; node.GetNameAndArityOfSimpleName(out name, out arity); // Actual member name might differ by case. string memberName; if (this.IgnoreCase) { var member = container.GetMembers(name).FirstOrDefault(); memberName = member != null ? member.Name : name; } else { memberName = name; } var codeAction = new DocumentChangeAction( node.Span, DiagnosticSeverity.Info, string.Format(GettextCatalog.GetString ("Change '{0}' to '{1}.{2}'"), name, containerName, memberName), (c) => { var newRoot = this.ReplaceNode(node, containerName, c); return Task.FromResult(document.WithSyntaxRoot(newRoot)); }); context.RegisterCodeFix(codeAction, diagnostic); } } } }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var document = context.Document; var span = context.Span; var diagnostics = context.Diagnostics; var cancellationToken = context.CancellationToken; var project = document.Project; var diagnostic = diagnostics.First(); var model = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait (false); if (model.IsFromGeneratedCode (context.CancellationToken)) return; var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); if (root.FullSpan.Length < span.Start) return; var ancestors = root.FindToken(span.Start, findInsideTrivia: true).GetAncestors<SyntaxNode>(); if (!ancestors.Any()) { return; } var node = ancestors.FirstOrDefault(n => n.Span.Contains(span) && n != root); if (node == null) { return; } var placeSystemNamespaceFirst = true; //document.Project.Solution.Workspace.Options.GetOption(Microsoft.CodeAnalysis.Shared.Options.OrganizerOptions.PlaceSystemNamespaceFirst, document.Project.Language); if (!cancellationToken.IsCancellationRequested) { if (this.CanAddImport(node, cancellationToken)) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); //var containingType = semanticModel.GetEnclosingNamedType(node.SpanStart, cancellationToken); //var containingTypeOrAssembly = containingType ?? (ISymbol)semanticModel.Compilation.Assembly; var namespacesInScope = this.GetNamespacesInScope(semanticModel, node, cancellationToken); var matchingTypesNamespaces = await this.GetNamespacesForMatchingTypesAsync(project, diagnostic, node, semanticModel, namespacesInScope, cancellationToken).ConfigureAwait(false); var matchingTypes = await this.GetMatchingTypesAsync(project, diagnostic, node, semanticModel, namespacesInScope, cancellationToken).ConfigureAwait(false); var matchingNamespaces = await this.GetNamespacesForMatchingNamespacesAsync(project, diagnostic, node, semanticModel, namespacesInScope, cancellationToken).ConfigureAwait(false); var matchingExtensionMethodsNamespaces = await this.GetNamespacesForMatchingExtensionMethodsAsync(project, diagnostic, node, semanticModel, namespacesInScope, cancellationToken).ConfigureAwait(false); var matchingFieldsAndPropertiesAsync = await this.GetNamespacesForMatchingFieldsAndPropertiesAsync(project, diagnostic, node, semanticModel, namespacesInScope, cancellationToken).ConfigureAwait(false); var queryPatternsNamespaces = await this.GetNamespacesForQueryPatternsAsync(project, diagnostic, node, semanticModel, namespacesInScope, cancellationToken).ConfigureAwait(false); if (matchingTypesNamespaces != null || matchingNamespaces != null || matchingExtensionMethodsNamespaces != null || matchingFieldsAndPropertiesAsync != null || queryPatternsNamespaces != null || matchingTypes != null) { matchingTypesNamespaces = matchingTypesNamespaces ?? SpecializedCollections.EmptyList<INamespaceSymbol>(); matchingNamespaces = matchingNamespaces ?? SpecializedCollections.EmptyList<INamespaceSymbol>(); matchingExtensionMethodsNamespaces = matchingExtensionMethodsNamespaces ?? SpecializedCollections.EmptyList<INamespaceSymbol>(); matchingFieldsAndPropertiesAsync = matchingFieldsAndPropertiesAsync ?? SpecializedCollections.EmptyList<INamespaceSymbol>(); queryPatternsNamespaces = queryPatternsNamespaces ?? SpecializedCollections.EmptyList<INamespaceSymbol>(); matchingTypes = matchingTypes ?? SpecializedCollections.EmptyList<ITypeSymbol>(); var proposedImports = matchingTypesNamespaces.Cast<INamespaceOrTypeSymbol> () .Concat (matchingNamespaces.Cast<INamespaceOrTypeSymbol> ()) .Concat (matchingExtensionMethodsNamespaces.Cast<INamespaceOrTypeSymbol> ()) .Concat (matchingFieldsAndPropertiesAsync.Cast<INamespaceOrTypeSymbol> ()) .Concat (queryPatternsNamespaces.Cast<INamespaceOrTypeSymbol> ()) .Concat (matchingTypes.Cast<INamespaceOrTypeSymbol> ()) .Distinct () .Where (NotNull) .Where (NotGlobalNamespace) .ToList (); proposedImports.Sort (INamespaceOrTypeSymbolExtensions.CompareNamespaceOrTypeSymbols); proposedImports = proposedImports.Take (8).ToList (); if (proposedImports.Count > 0) { cancellationToken.ThrowIfCancellationRequested(); foreach (var import in proposedImports) { var action = new DocumentChangeAction( node.Span, DiagnosticSeverity.Error, this.GetDescription(import, semanticModel, node), (c) => this.AddImportAsync(node, import, document, placeSystemNamespaceFirst, cancellationToken) ); context.RegisterCodeFix(action, diagnostic); } } } } } }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var document = context.Document; var span = context.Span; var diagnostics = context.Diagnostics; var cancellationToken = context.CancellationToken; var project = document.Project; var diagnostic = diagnostics.First(); var model = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false); if (model.IsFromGeneratedCode(context.CancellationToken)) { return; } var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var node = root.FindToken(span.Start).GetAncestors <SyntaxNode>().First(n => n.Span.Contains(span)); // Has to be a simple identifier or generic name. if (node != null && CanFullyQualify(diagnostic, ref node)) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var matchingTypes = await this.GetMatchingTypesAsync(project, semanticModel, node, cancellationToken).ConfigureAwait(false); var matchingNamespaces = await this.GetMatchingNamespacesAsync(project, semanticModel, node, cancellationToken).ConfigureAwait(false); if (matchingTypes != null || matchingNamespaces != null) { matchingTypes = matchingTypes ?? SpecializedCollections.EmptyEnumerable <ISymbol>(); matchingNamespaces = matchingNamespaces ?? SpecializedCollections.EmptyEnumerable <ISymbol>(); var matchingTypeContainers = FilterAndSort(GetContainers(matchingTypes, semanticModel.Compilation)); var matchingNamespaceContainers = FilterAndSort(GetContainers(matchingNamespaces, semanticModel.Compilation)); var proposedContainers = matchingTypeContainers.Concat(matchingNamespaceContainers) .Distinct() .Take(8); foreach (var container in proposedContainers) { var containerName = RoslynCompletionData.SafeMinimalDisplayString(container, semanticModel, node.SpanStart); string name; int arity; node.GetNameAndArityOfSimpleName(out name, out arity); // Actual member name might differ by case. string memberName; if (this.IgnoreCase) { var member = container.GetMembers(name).FirstOrDefault(); memberName = member != null ? member.Name : name; } else { memberName = name; } var codeAction = new DocumentChangeAction( node.Span, DiagnosticSeverity.Info, string.Format(GettextCatalog.GetString("Change '{0}' to '{1}.{2}'"), name, containerName, memberName), (c) => { var newRoot = this.ReplaceNode(node, containerName, c); return(Task.FromResult(document.WithSyntaxRoot(newRoot))); }); context.RegisterCodeFix(codeAction, diagnostic); } } } }