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()); }
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)); } } }