protected override async Task <Document> PerformCodeFixActionAsync(CodeFixContext context, SyntaxNode syntaxNode, CancellationToken cancellationToken) { var document = context.Document; var semanticModel = await document.GetSemanticModelAsync(); var interfaceDeclarationNode = syntaxNode.GetNearestParentOfType <InterfaceDeclarationSyntax>(); var profileAttribute = ExtendedSyntaxFactory.Attribute <TypeConstraintProfileAttribute>(); var profileGroupAttribute = interfaceDeclarationNode.AttributeLists .SelectMany(list => list.Attributes) .Where(attribute => semanticModel.GetTypeInfo(attribute).Type.Name == nameof(TypeConstraintProfileGroupAttribute)) .OnlyOrDefault(); if (profileGroupAttribute is null) { // Create new profile attribute var newInterfaceDeclarationNode = interfaceDeclarationNode.AddAttributeLists(ExtendedSyntaxFactory.AttributeList(profileAttribute)); return(await document.ReplaceNodeAsync(interfaceDeclarationNode, newInterfaceDeclarationNode)); } else { // Replace existing profile group attribute with the created profile one return(await document.ReplaceNodeAsync(profileGroupAttribute, profileAttribute)); } }
private void GenericProfileRelatedInterfaceWithCodeFix(string attributeName) { ExtendedSyntaxFactory.SimplifyAttributeNameUsage(ref attributeName); var testCode = $@" [{attributeName}] interface {{|*:IProfile1|}}<T1> {{ }} [{attributeName}] interface {{|*:IProfile2|}}<T1, T2> {{ }} [{attributeName}] interface {{|*:IProfile3|}}<T1, T2, T3> {{ }} "; var fixedCode = $@" [{attributeName}] interface IProfile1 {{ }} [{attributeName}] interface IProfile2 {{ }} [{attributeName}] interface IProfile3 {{ }} "; TestCodeFixWithUsings(testCode, fixedCode); }