Skip to content

Commit f9e8de3

Browse files
authored
Merge pull request #650 from drewnoakes/fix-VSMEF006
Don't fire VSMEF006 in non-nullable contexts
2 parents 4c83c76 + 719e0bb commit f9e8de3

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed

src/Microsoft.VisualStudio.Composition.Analyzers/VSMEF006ImportNullabilityAnalyzer.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,16 @@ static void AnalyzeMember(SymbolAnalysisContext context, ISymbol member, ITypeSy
104104
return;
105105
}
106106

107+
// Skip analysis if nullable context is not enabled
108+
// When nullable is disabled or not specified, non-nullable reference types have NullableAnnotation.None
109+
// When nullable is enabled, non-nullable reference types have NullableAnnotation.NotAnnotated
110+
// So we check: if a reference type import has None, nullable context is not enabled
111+
if (type.IsReferenceType && type.NullableAnnotation == NullableAnnotation.None)
112+
{
113+
// Oblivious mode - nullable reference types are not enabled
114+
return;
115+
}
116+
107117
bool isNullableReferenceType = IsNullableReferenceType(type);
108118
bool hasAllowDefault = Utils.GetAllowDefaultValue(importAttribute);
109119

test/Microsoft.VisualStudio.Composition.Analyzers.Tests/VSMEF006ImportNullabilityAnalyzerTests.cs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,4 +592,99 @@ class Foo
592592

593593
await VerifyCS.VerifyCodeFixAsync(test, expected, fixedTest);
594594
}
595+
596+
[Fact]
597+
public async Task NullableDisabledImportWithAllowDefault_NoWarning()
598+
{
599+
string test = """
600+
#nullable disable
601+
using System.ComponentModel.Composition;
602+
603+
class Foo
604+
{
605+
[Import(AllowDefault = true)]
606+
public string Value { get; set; }
607+
}
608+
""";
609+
610+
await VerifyCS.VerifyAnalyzerAsync(test);
611+
}
612+
613+
[Fact]
614+
public async Task NullableUnspecifiedImportWithAllowDefault_NoWarning()
615+
{
616+
string test = """
617+
using System.ComponentModel.Composition;
618+
619+
class Foo
620+
{
621+
[Import(AllowDefault = true)]
622+
public string Value { get; set; }
623+
}
624+
""";
625+
626+
await VerifyCS.VerifyAnalyzerAsync(test);
627+
}
628+
629+
[Fact]
630+
public async Task LazyImportWithAllowDefault_LazyIsNullable()
631+
{
632+
string test = """
633+
#nullable enable
634+
using System;
635+
using System.ComponentModel.Composition;
636+
637+
class Foo
638+
{
639+
[Import(AllowDefault = true)]
640+
public Lazy<string>? Value { get; set; }
641+
}
642+
""";
643+
644+
await VerifyCS.VerifyAnalyzerAsync(test);
645+
}
646+
647+
[Fact]
648+
public async Task LazyImportWithAllowDefault_LazyNotNullable_Warning()
649+
{
650+
string test = """
651+
#nullable enable
652+
using System;
653+
using System.ComponentModel.Composition;
654+
655+
class Foo
656+
{
657+
[Import(AllowDefault = true)]
658+
public Lazy<string> {|#0:Value|} { get; set; }
659+
}
660+
""";
661+
662+
DiagnosticResult expected = VerifyCS.Diagnostic(VSMEF006ImportNullabilityAnalyzer.AllowDefaultWithoutNullableDescriptor)
663+
.WithLocation(0)
664+
.WithArguments("Value");
665+
666+
await VerifyCS.VerifyAnalyzerAsync(test, expected);
667+
}
668+
669+
[Fact]
670+
public async Task LazyImportNullable_WithoutAllowDefault_Warning()
671+
{
672+
string test = """
673+
#nullable enable
674+
using System;
675+
using System.ComponentModel.Composition;
676+
677+
class Foo
678+
{
679+
[Import]
680+
public Lazy<string>? {|#0:Value|} { get; set; }
681+
}
682+
""";
683+
684+
DiagnosticResult expected = VerifyCS.Diagnostic(VSMEF006ImportNullabilityAnalyzer.NullableWithoutAllowDefaultDescriptor)
685+
.WithLocation(0)
686+
.WithArguments("Value");
687+
688+
await VerifyCS.VerifyAnalyzerAsync(test, expected);
689+
}
595690
}

0 commit comments

Comments
 (0)