Skip to content

Commit b1cb7cd

Browse files
fix: INTL0101 code fix NotImplementedException for non-class declaration types (#411)
## Description Describe your changes here. Fixes #Issue_Number (if available) ### Ensure that your pull request has followed all the steps below: - [ ] Code compilation - [ ] Created tests which fail without the change (if possible) - [ ] All tests passing - [ ] Extended the README / documentation, if necessary Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 418f62d commit b1cb7cd

2 files changed

Lines changed: 311 additions & 30 deletions

File tree

IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/AttributesOnSeparateLines.cs

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Collections.Immutable;
43
using System.Composition;
54
using System.Linq;
@@ -48,8 +47,8 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
4847
attributeList = attributeList.Parent;
4948
}
5049

51-
// Get the class, method or property adjacent to the AttributeList
52-
if (attributeList?.Parent is not SyntaxNode parentDeclaration)
50+
// Get the member declaration adjacent to the AttributeList
51+
if (attributeList?.Parent is not MemberDeclarationSyntax parentDeclaration)
5352
{
5453
return;
5554
}
@@ -63,12 +62,12 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
6362
diagnostic);
6463
}
6564

66-
private static async Task<Document> PutOnSeparateLine(Document document, SyntaxNode parentDeclaration, CancellationToken cancellationToken)
65+
private static async Task<Document> PutOnSeparateLine(Document document, MemberDeclarationSyntax parentDeclaration, CancellationToken cancellationToken)
6766
{
6867
var attributeLists = new SyntaxList<AttributeListSyntax>();
6968

7069
// put every attribute into it's own attributelist eg.: [A,B,C] => [A][B][C]
71-
foreach (AttributeSyntax attribute in GetAttributeListSyntaxes(parentDeclaration).SelectMany(l => l.Attributes))
70+
foreach (AttributeSyntax attribute in parentDeclaration.AttributeLists.SelectMany(l => l.Attributes))
7271
{
7372
attributeLists = attributeLists.Add(
7473
SyntaxFactory.AttributeList(
@@ -80,7 +79,7 @@ private static async Task<Document> PutOnSeparateLine(Document document, SyntaxN
8079
}
8180

8281
// the formatter-annotation will wrap every attribute on a separate line
83-
SyntaxNode newNode = BuildNodeWithAttributeLists(parentDeclaration, attributeLists)
82+
MemberDeclarationSyntax newNode = parentDeclaration.WithAttributeLists(attributeLists)
8483
.WithAdditionalAnnotations(Formatter.Annotation);
8584

8685
// Replace the old local declaration with the new local declaration.
@@ -90,29 +89,5 @@ private static async Task<Document> PutOnSeparateLine(Document document, SyntaxN
9089

9190
return document.WithSyntaxRoot(newRoot);
9291
}
93-
94-
private static IEnumerable<AttributeListSyntax> GetAttributeListSyntaxes(SyntaxNode node)
95-
{
96-
return node switch
97-
{
98-
ClassDeclarationSyntax c => c.AttributeLists,
99-
MethodDeclarationSyntax m => m.AttributeLists,
100-
PropertyDeclarationSyntax p => p.AttributeLists,
101-
FieldDeclarationSyntax f => f.AttributeLists,
102-
_ => throw new NotImplementedException(),
103-
};
104-
}
105-
106-
private static SyntaxNode BuildNodeWithAttributeLists(SyntaxNode node, SyntaxList<AttributeListSyntax> attributeLists)
107-
{
108-
return node switch
109-
{
110-
ClassDeclarationSyntax c => c.WithAttributeLists(attributeLists),
111-
MethodDeclarationSyntax m => m.WithAttributeLists(attributeLists),
112-
PropertyDeclarationSyntax p => p.WithAttributeLists(attributeLists),
113-
FieldDeclarationSyntax f => f.WithAttributeLists(attributeLists),
114-
_ => throw new NotImplementedException(),
115-
};
116-
}
11792
}
11893
}

IntelliTect.Analyzer/IntelliTect.Analyzer.Test/AttributesOnSeparateLinesTests.cs

Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,312 @@ static void Main()
390390
await VerifyCSharpFix(test, fixTest);
391391
}
392392

393+
[TestMethod]
394+
public async Task StructAttributeLineViolation_CodeFix_TwoAttributesOnSameLine_TwoAttributesOnSeparateLines()
395+
{
396+
string test = @"using System;
397+
398+
namespace ConsoleApp
399+
{
400+
class AAttribute : Attribute
401+
{
402+
}
403+
404+
class BAttribute : Attribute
405+
{
406+
}
407+
408+
[A][B]
409+
struct MyStruct
410+
{
411+
}
412+
}";
413+
414+
string fixTest = @"using System;
415+
416+
namespace ConsoleApp
417+
{
418+
class AAttribute : Attribute
419+
{
420+
}
421+
422+
class BAttribute : Attribute
423+
{
424+
}
425+
426+
[A]
427+
[B]
428+
struct MyStruct
429+
{
430+
}
431+
}";
432+
await VerifyCSharpFix(test, fixTest);
433+
}
434+
435+
[TestMethod]
436+
public async Task RecordAttributeLineViolation_CodeFix_TwoAttributesOnSameLine_TwoAttributesOnSeparateLines()
437+
{
438+
string test = @"using System;
439+
440+
namespace ConsoleApp
441+
{
442+
class AAttribute : Attribute
443+
{
444+
}
445+
446+
class BAttribute : Attribute
447+
{
448+
}
449+
450+
[A][B]
451+
record MyRecord
452+
{
453+
}
454+
}";
455+
456+
string fixTest = @"using System;
457+
458+
namespace ConsoleApp
459+
{
460+
class AAttribute : Attribute
461+
{
462+
}
463+
464+
class BAttribute : Attribute
465+
{
466+
}
467+
468+
[A]
469+
[B]
470+
record MyRecord
471+
{
472+
}
473+
}";
474+
await VerifyCSharpFix(test, fixTest);
475+
}
476+
477+
[TestMethod]
478+
public async Task InterfaceAttributeLineViolation_CodeFix_TwoAttributesOnSameLine_TwoAttributesOnSeparateLines()
479+
{
480+
string test = @"using System;
481+
482+
namespace ConsoleApp
483+
{
484+
class AAttribute : Attribute
485+
{
486+
}
487+
488+
class BAttribute : Attribute
489+
{
490+
}
491+
492+
[A][B]
493+
interface IMyInterface
494+
{
495+
}
496+
}";
497+
498+
string fixTest = @"using System;
499+
500+
namespace ConsoleApp
501+
{
502+
class AAttribute : Attribute
503+
{
504+
}
505+
506+
class BAttribute : Attribute
507+
{
508+
}
509+
510+
[A]
511+
[B]
512+
interface IMyInterface
513+
{
514+
}
515+
}";
516+
await VerifyCSharpFix(test, fixTest);
517+
}
518+
519+
[TestMethod]
520+
public async Task EnumAttributeLineViolation_CodeFix_TwoAttributesOnSameLine_TwoAttributesOnSeparateLines()
521+
{
522+
string test = @"using System;
523+
524+
namespace ConsoleApp
525+
{
526+
class AAttribute : Attribute
527+
{
528+
}
529+
530+
class BAttribute : Attribute
531+
{
532+
}
533+
534+
[A][B]
535+
enum MyEnum
536+
{
537+
Foo
538+
}
539+
}";
540+
541+
string fixTest = @"using System;
542+
543+
namespace ConsoleApp
544+
{
545+
class AAttribute : Attribute
546+
{
547+
}
548+
549+
class BAttribute : Attribute
550+
{
551+
}
552+
553+
[A]
554+
[B]
555+
enum MyEnum
556+
{
557+
Foo
558+
}
559+
}";
560+
await VerifyCSharpFix(test, fixTest);
561+
}
562+
563+
[TestMethod]
564+
public async Task ConstructorAttributeLineViolation_CodeFix_TwoAttributesOnSameLine_TwoAttributesOnSeparateLines()
565+
{
566+
string test = @"using System;
567+
568+
namespace ConsoleApp
569+
{
570+
class AAttribute : Attribute
571+
{
572+
}
573+
574+
class BAttribute : Attribute
575+
{
576+
}
577+
578+
class Program
579+
{
580+
[A][B]
581+
Program()
582+
{
583+
}
584+
}
585+
}";
586+
587+
string fixTest = @"using System;
588+
589+
namespace ConsoleApp
590+
{
591+
class AAttribute : Attribute
592+
{
593+
}
594+
595+
class BAttribute : Attribute
596+
{
597+
}
598+
599+
class Program
600+
{
601+
[A]
602+
[B]
603+
Program()
604+
{
605+
}
606+
}
607+
}";
608+
await VerifyCSharpFix(test, fixTest);
609+
}
610+
611+
[TestMethod]
612+
public async Task EnumMemberAttributeLineViolation_CodeFix_TwoAttributesOnSameLine_TwoAttributesOnSeparateLines()
613+
{
614+
string test = @"using System;
615+
616+
namespace ConsoleApp
617+
{
618+
class AAttribute : Attribute
619+
{
620+
}
621+
622+
class BAttribute : Attribute
623+
{
624+
}
625+
626+
enum MyEnum
627+
{
628+
[A][B]
629+
Bar
630+
}
631+
}";
632+
633+
string fixTest = @"using System;
634+
635+
namespace ConsoleApp
636+
{
637+
class AAttribute : Attribute
638+
{
639+
}
640+
641+
class BAttribute : Attribute
642+
{
643+
}
644+
645+
enum MyEnum
646+
{
647+
[A]
648+
[B]
649+
Bar
650+
}
651+
}";
652+
await VerifyCSharpFix(test, fixTest);
653+
}
654+
655+
[TestMethod]
656+
public async Task IndexerAttributeLineViolation_CodeFix_TwoAttributesOnSameLine_TwoAttributesOnSeparateLines()
657+
{
658+
string test = @"using System;
659+
660+
namespace ConsoleApp
661+
{
662+
class AAttribute : Attribute
663+
{
664+
}
665+
666+
class BAttribute : Attribute
667+
{
668+
}
669+
670+
class Program
671+
{
672+
[A][B]
673+
int this[int i] { get => 0; }
674+
}
675+
}";
676+
677+
string fixTest = @"using System;
678+
679+
namespace ConsoleApp
680+
{
681+
class AAttribute : Attribute
682+
{
683+
}
684+
685+
class BAttribute : Attribute
686+
{
687+
}
688+
689+
class Program
690+
{
691+
[A]
692+
[B]
693+
int this[int i] { get => 0; }
694+
}
695+
}";
696+
await VerifyCSharpFix(test, fixTest);
697+
}
698+
393699
[TestMethod]
394700
[Description("Analyzer should not report on generated code")]
395701
public void AttributesOnSameLine_InGeneratedCode_NoDiagnostic()

0 commit comments

Comments
 (0)