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);
        }
Ejemplo n.º 2
0
        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());
        }