private static async Task <Document> ImplementIDisposable(Document document, SyntaxNode declaration, CancellationToken cancellationToken)
        {
            DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);

            SyntaxGenerator generator = editor.Generator;
            SemanticModel   model     = editor.SemanticModel;

            // Add the interface to the baselist.
            SyntaxNode interfaceType = generator.TypeExpression(WellKnownTypes.IDisposable(model.Compilation));

            editor.AddInterfaceType(declaration, interfaceType);

            // Find a Dispose method. If one exists make that implement IDisposable, else generate a new method.
            var           typeSymbol    = model.GetDeclaredSymbol(declaration) as INamedTypeSymbol;
            IMethodSymbol disposeMethod = (typeSymbol?.GetMembers("Dispose"))?.OfType <IMethodSymbol>()?.Where(m => m.Parameters.Length == 0).FirstOrDefault();

            if (disposeMethod != null && disposeMethod.DeclaringSyntaxReferences.Length == 1)
            {
                SyntaxNode memberPartNode = await disposeMethod.DeclaringSyntaxReferences.Single().GetSyntaxAsync(cancellationToken).ConfigureAwait(false);

                memberPartNode = generator.GetDeclaration(memberPartNode);
                editor.ReplaceNode(memberPartNode, generator.AsPublicInterfaceImplementation(memberPartNode, interfaceType));
            }
            else
            {
                SyntaxNode throwStatement = generator.ThrowStatement(generator.ObjectCreationExpression(WellKnownTypes.NotImplementedException(model.Compilation)));
                SyntaxNode member         = generator.MethodDeclaration(TypesThatOwnDisposableFieldsShouldBeDisposableAnalyzer <SyntaxNode> .Dispose, statements: new[] { throwStatement });
                member = generator.AsPublicInterfaceImplementation(member, interfaceType);
                editor.AddMember(declaration, member);
            }

            return(editor.GetChangedDocument());
        }
示例#2
0
        public static void AddInterfaceIfNeeded(this DocumentEditor editor, ClassDeclarationSyntax oldClass,
                                                IdentifierNameSyntax baseClass)
        {
            if (oldClass.BaseList != null && oldClass.BaseList.Types.Any(bts =>
                                                                         bts.DescendantNodes <IdentifierNameSyntax>()
                                                                         .Any(ins => ins.Identifier.Text == baseClass.Identifier.Text)))
            {
                return;
            }
            var model = editor.SemanticModel;
            var oc    = model.GetDeclaredSymbol(oldClass);

            if (oc.AllInterfaces.Any(i => i.Name == baseClass.Identifier.Text))
            {
                return;
            }

            editor.AddInterfaceType(oldClass, baseClass);
        }
        public static void ImplementIIrcConnection(CodeFixContext context, SemanticModel semanticModel, ClassDeclarationSyntax classDeclaration, DocumentEditor editor)
        {
            var type = (ITypeSymbol)semanticModel.GetDeclaredSymbol(classDeclaration, context.CancellationToken);

            editor.AddInterfaceType(classDeclaration, SyntaxFactory.ParseTypeName("DigiBotExtension.IIrcConnection").WithTrailingTrivia(SyntaxFactory.ElasticMarker).WithAdditionalAnnotations(Simplifier.Annotation, SyntaxAnnotation.ElasticAnnotation));
        }
        private static void ImplementINotifyPropertyChanged(CodeFixContext context, SemanticModel semanticModel, ClassDeclarationSyntax classDeclaration, DocumentEditor editor)
        {
            var type             = (ITypeSymbol)semanticModel.GetDeclaredSymbol(classDeclaration, context.CancellationToken);
            var underscoreFields = CodeStyle.UnderscoreFields(semanticModel);

            if (!type.Is(KnownSymbol.INotifyPropertyChanged))
            {
                if (classDeclaration.BaseList != null &&
                    classDeclaration.BaseList.Types.TryFirst(
                        x => (x.Type as IdentifierNameSyntax)?.Identifier.ValueText.Contains("INotifyPropertyChanged") == true,
                        out var baseType) &&
                    context.Diagnostics.Any(IsINotifyPropertyChangedMissing))
                {
                    editor.ReplaceNode(baseType, SyntaxFactory.SimpleBaseType(INotifyPropertyChangedType));
                }
                else
                {
                    editor.AddInterfaceType(classDeclaration, INotifyPropertyChangedType);
                }
            }

            if (!type.TryFindEventRecursive("PropertyChanged", out _))
            {
                editor.AddEvent(
                    classDeclaration,
                    (EventFieldDeclarationSyntax)editor.Generator.EventDeclaration(
                        "PropertyChanged",
                        PropertyChangedEventHandlerType,
                        Accessibility.Public));
            }

            if (!type.TryFindFirstMethodRecursive(
                    "OnPropertyChanged",
                    m => m.Parameters.Length == 1 &&
                    m.Parameters[0]
                    .Type == KnownSymbol.String,
                    out _))
            {
                if (type.IsSealed)
                {
                    editor.AddMethod(
                        classDeclaration,
                        ParseMethod(
                            @"private void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
                              {
                                  this.PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
                              }",
                            underscoreFields));
                }
                else
                {
                    editor.AddMethod(
                        classDeclaration,
                        ParseMethod(
                            @"protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
                              {
                                  this.PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
                              }",
                            underscoreFields));
                }
            }
        }