private static void CreateTearDownMethod(DocumentEditor editor, ISymbol fieldOrProperty, MethodDeclarationSyntax setupMethod, QualifiedType tearDownType, CancellationToken cancellationToken) { var code = StringBuilderPool.Borrow() .AppendLine($"[{tearDownType.FullName}]") .AppendLine($"public void {tearDownType.Type.Replace("Attribute", string.Empty)}()") .AppendLine("{") .AppendLine($" {Snippet.DisposeStatement(fieldOrProperty, editor.SemanticModel, cancellationToken)}") .AppendLine("}") .Return(); var tearDownMethod = Parse.MethodDeclaration(code) .WithSimplifiedNames() .WithLeadingTrivia(SyntaxFactory.ElasticMarker) .WithTrailingTrivia(SyntaxFactory.ElasticMarker) .WithAdditionalAnnotations(Formatter.Annotation); editor.InsertAfter(setupMethod, tearDownMethod); }
private static async Task <Document> OverrideDisposeAsync(CodeFixContext context, ClassDeclarationSyntax classDeclaration, IMethodSymbol baseDispose, CancellationToken cancellationToken) { var editor = await DocumentEditor.CreateAsync(context.Document, cancellationToken) .ConfigureAwait(false); var type = (ITypeSymbol)editor.SemanticModel.GetDeclaredSymbol(classDeclaration, cancellationToken); var usesUnderscoreNames = editor.SemanticModel.UnderscoreFields(); var field = editor.AddField( classDeclaration, usesUnderscoreNames ? "_disposed" : "disposed", Accessibility.Private, DeclarationModifiers.None, SyntaxFactory.ParseTypeName("bool"), cancellationToken); var code = StringBuilderPool.Borrow() .AppendLine($"{baseDispose.DeclaredAccessibility.ToCodeString()} override void Dispose(bool disposing)") .AppendLine("{") .AppendLine(" if (this.disposed)") .AppendLine(" {") .AppendLine(" return;") .AppendLine(" }") .AppendLine() .AppendLine(" this.disposed = true;") .AppendLine(" if (disposing)") .AppendLine(" {") .AppendLine(" }") .AppendLine() .AppendLine(" base.Dispose(disposing);") .AppendLine("}") .Return(); _ = editor.AddMethod( classDeclaration, ParseMethod(code, usesUnderscoreNames, field)); if (!type.GetMembers().TryFirst(x => x.Name == "ThrowIfDisposed", out _)) { if (type.BaseType.TryFindSingleMethodRecursive("ThrowIfDisposed", out var baseThrow) && baseThrow.Parameters.Length == 0) { if (baseThrow.IsVirtual) { code = StringBuilderPool.Borrow() .AppendLine($"{baseThrow.DeclaredAccessibility.ToCodeString()} override void ThrowIfDisposed()") .AppendLine("{") .AppendLine(" if (this.disposed)") .AppendLine(" {") .AppendLine(" throw new System.ObjectDisposedException(this.GetType().FullName);") .AppendLine(" }") .AppendLine() .AppendLine(" base.ThrowIfDisposed();") .AppendLine("}") .Return(); _ = editor.AddMethod( classDeclaration, ParseMethod(code, usesUnderscoreNames, field)); } } else { _ = editor.AddMethod( classDeclaration, ParseMethod( @"protected virtual void ThrowIfDisposed() { if (this.disposed) { throw new System.ObjectDisposedException(this.GetType().FullName); } }", usesUnderscoreNames, field)); } } return(editor.GetChangedDocument()); }