Esempio n. 1
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());
        }