protected override async Task <SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document) { var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false); if (diagnostics.IsEmpty) { return(null); } DocumentEditor editor = await DocumentEditor.CreateAsync(document, fixAllContext.CancellationToken).ConfigureAwait(false); SyntaxNode root = editor.GetChangedRoot(); ImmutableList <SyntaxNode> nodesToChange = ImmutableList.Create <SyntaxNode>(); // Make sure all nodes we care about are tracked foreach (var diagnostic in diagnostics) { var location = diagnostic.Location; var syntaxNode = root.FindNode(location.SourceSpan); if (syntaxNode != null) { editor.TrackNode(syntaxNode); nodesToChange = nodesToChange.Add(syntaxNode); } } foreach (var node in nodesToChange) { editor.ReplaceNode(node, node.WithLeadingTrivia(SyntaxFactory.ElasticCarriageReturnLineFeed)); } return(editor.GetChangedRoot()); }
public void AddNSubstituteUsing() { CompilationUnitSyntax root = _editor.GetChangedRoot() as CompilationUnitSyntax; if (!root.Usings.Any(x => x.Name.GetText().ToString() == "NSubstitute")) { var newUsing = SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName("NSubstitute")); _editor.InsertBefore((_editor.OriginalRoot as CompilationUnitSyntax).Usings.FirstOrDefault(), newUsing); } }
// search for using statements with the old sdk. Then if they are found then look for classes that coresponded to the custom attributes // if classes are found then replace the old using statement with the new one // oldSDKUsings is a list of the old sdk using statements public SyntaxTree ReplaceSyntax() { ReplaceUsingStatements(); ReplaceQualifiedNames(); ReplaceIdentifierNames(); return(documentEditor.GetChangedRoot().SyntaxTree); }
private async Task <Solution> RemoveNodes(Document document, Diagnostic diagnostic, CancellationToken cancellationToken) { var solution = document.Project.Solution; var pairs = await GetNodesToRemoveAsync(document, diagnostic, cancellationToken).ConfigureAwait(false); foreach (var group in pairs.GroupBy(p => p.Key)) { DocumentEditor editor = await DocumentEditor.CreateAsync(solution.GetDocument(group.Key), cancellationToken).ConfigureAwait(false); // Start removing from bottom to top to keep spans of nodes that are removed later. foreach (var value in group.OrderByDescending(v => v.Value.SpanStart)) { editor.RemoveNode(value.Value); } solution = solution.WithDocumentSyntaxRoot(group.Key, editor.GetChangedRoot()); } return(solution); }
private static async Task <Document> AddKeyAttributeAsync(Document document, INamedTypeSymbol type, CancellationToken cancellationToken) { if (type.DeclaringSyntaxReferences.Length != 0) { document = document.Project.GetDocument(type.DeclaringSyntaxReferences[0].SyntaxTree); } DocumentEditor editor = await DocumentEditor.CreateAsync(document).ConfigureAwait(false); ISymbol[] targets = type.GetAllMembers() .Where(x => x.Kind == SymbolKind.Property || x.Kind == SymbolKind.Field) .Where(x => x.GetAttributes().FindAttributeShortName(MessagePackAnalyzer.IgnoreShortName) == null && x.GetAttributes().FindAttributeShortName(MessagePackAnalyzer.IgnoreDataMemberShortName) == null) .Where(x => !x.IsStatic) .Where(x => { var p = x as IPropertySymbol; if (p == null) { var f = x as IFieldSymbol; if (f.IsImplicitlyDeclared) { return(false); } return(true); } return(p.ExplicitInterfaceImplementations.Length == 0); }) .ToArray(); var startOrder = targets .Select(x => x.GetAttributes().FindAttributeShortName(MessagePackAnalyzer.KeyAttributeShortName)) .Where(x => x != null) .Select(x => x.ConstructorArguments[0]) .Where(x => !x.IsNull) .Where(x => x.Value.GetType() == typeof(int)) .Select(x => (int)x.Value) .DefaultIfEmpty(-1) // if empty, start from zero. .Max() + 1; foreach (ISymbol item in targets) { SyntaxNode node = await item.DeclaringSyntaxReferences[0].GetSyntaxAsync().ConfigureAwait(false); AttributeData attr = item.GetAttributes().FindAttributeShortName(MessagePackAnalyzer.KeyAttributeShortName); if (attr != null) { continue; // already tagged Index. } AttributeListSyntax attribute = RoslynExtensions.ParseAttributeList($"[Key({startOrder++})]") .WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed); editor.AddAttribute(node, attribute); } if (type.GetAttributes().FindAttributeShortName(MessagePackAnalyzer.MessagePackObjectAttributeShortName) == null) { SyntaxNode rootNode = await type.DeclaringSyntaxReferences[0].GetSyntaxAsync().ConfigureAwait(false); editor.AddAttribute(rootNode, RoslynExtensions.ParseAttributeList("[MessagePackObject]")); } Document newDocument = editor.GetChangedDocument(); var newRoot = editor.GetChangedRoot() as CompilationUnitSyntax; newDocument = newDocument.WithSyntaxRoot(newRoot.WithUsing("MessagePack")); return(newDocument); }