Enable Nullable compilation on the Options source gen (#88973)
authorTarek Mahmoud Sayed <tarekms@microsoft.com>
Tue, 18 Jul 2023 17:26:56 +0000 (10:26 -0700)
committerGitHub <noreply@github.com>
Tue, 18 Jul 2023 17:26:56 +0000 (10:26 -0700)
Co-authored-by: Viktor Hofer <viktor.hofer@microsoft.com>
src/libraries/Microsoft.Extensions.Options/gen/Generator.cs
src/libraries/Microsoft.Extensions.Options/gen/Microsoft.Extensions.Options.SourceGeneration.csproj
src/libraries/Microsoft.Extensions.Options/gen/Parser.cs

index b24f43b..7fc1806 100644 (file)
@@ -17,20 +17,20 @@ namespace Microsoft.Extensions.Options.Generators
     {
         public void Initialize(IncrementalGeneratorInitializationContext context)
         {
-            IncrementalValuesProvider<(TypeDeclarationSyntax TypeSyntax, SemanticModel SemanticModel)> typeDeclarations = context.SyntaxProvider
+            IncrementalValuesProvider<(TypeDeclarationSyntax? TypeSyntax, SemanticModel SemanticModel)> typeDeclarations = context.SyntaxProvider
                 .ForAttributeWithMetadataName(
                     SymbolLoader.OptionsValidatorAttribute,
                     (node, _) => node is TypeDeclarationSyntax,
                     (context, _) => (TypeSyntax:context.TargetNode as TypeDeclarationSyntax, SemanticModel: context.SemanticModel))
                 .Where(static m => m.TypeSyntax is not null);
 
-            IncrementalValueProvider<(Compilation, ImmutableArray<(TypeDeclarationSyntax TypeSyntax, SemanticModel SemanticModel)>)> compilationAndTypes =
+            IncrementalValueProvider<(Compilation, ImmutableArray<(TypeDeclarationSyntax? TypeSyntax, SemanticModel SemanticModel)>)> compilationAndTypes =
                 context.CompilationProvider.Combine(typeDeclarations.Collect());
 
             context.RegisterSourceOutput(compilationAndTypes, static (spc, source) => HandleAnnotatedTypes(source.Item1, source.Item2, spc));
         }
 
-        private static void HandleAnnotatedTypes(Compilation compilation, ImmutableArray<(TypeDeclarationSyntax TypeSyntax, SemanticModel SemanticModel)> types, SourceProductionContext context)
+        private static void HandleAnnotatedTypes(Compilation compilation, ImmutableArray<(TypeDeclarationSyntax? TypeSyntax, SemanticModel SemanticModel)> types, SourceProductionContext context)
         {
             if (!SymbolLoader.TryLoad(compilation, out var symbolHolder))
             {
index 12bc4a7..41ceaf6 100644 (file)
@@ -1,6 +1,9 @@
 <Project Sdk="Microsoft.NET.Sdk">
+
   <PropertyGroup>
-    <TargetFramework>netstandard2.0</TargetFramework>
+    <!-- Source generators must target netstandard2.0 which doesn't support nullable reference types. In order
+         to enable the nullable reference type compiler checks, we also target NetCoreAppCurrent. -->
+    <TargetFrameworks>$(NetCoreAppCurrent);netstandard2.0</TargetFrameworks>
     <CLSCompliant>false</CLSCompliant>
     <EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
     <UsingToolXliff>true</UsingToolXliff>
@@ -32,4 +35,5 @@
     <Compile Include="SymbolLoader.cs" />
     <Compile Include="TypeDeclarationSyntaxReceiver.cs" />
   </ItemGroup>
+
 </Project>
index 0876ffa..c4d1da9 100644 (file)
@@ -93,8 +93,9 @@ namespace Microsoft.Extensions.Options.Generators
                                 continue;
                             }
 
-                            Location lowerLocationInCompilation = _compilation.ContainsSyntaxTree(modelType.GetLocation().SourceTree)
-                                ? modelType.GetLocation()
+                            Location? modelTypeLocation = modelType.GetLocation();
+                            Location lowerLocationInCompilation = modelTypeLocation is not null && modelTypeLocation.SourceTree is not null && _compilation.ContainsSyntaxTree(modelTypeLocation.SourceTree)
+                                ? modelTypeLocation
                                 : syntax.GetLocation();
 
                             var membersToValidate = GetMembersToValidate(modelType, true, lowerLocationInCompilation, validatorType);
@@ -128,7 +129,7 @@ namespace Microsoft.Extensions.Options.Generators
                         parents.Reverse();
 
                         results.Add(new ValidatorType(
-                            validatorType.ContainingNamespace.IsGlobalNamespace ? string.Empty : validatorType.ContainingNamespace.ToString(),
+                            validatorType.ContainingNamespace.IsGlobalNamespace ? string.Empty : validatorType.ContainingNamespace.ToString()!,
                             GetMinimalFQN(validatorType),
                             GetMinimalFQNWithoutGenerics(validatorType),
                             keyword,
@@ -267,8 +268,9 @@ namespace Microsoft.Extensions.Options.Generators
             var membersToValidate = new List<ValidatedMember>();
             foreach (var member in members)
             {
-                Location location = _compilation.ContainsSyntaxTree(member.GetLocation().SourceTree)
-                    ? member.GetLocation()
+                Location? memberLocation = member.GetLocation();
+                Location location = memberLocation is not null && memberLocation.SourceTree is not null && _compilation.ContainsSyntaxTree(memberLocation.SourceTree)
+                    ? memberLocation
                     : lowerLocationInCompilation;
 
                 var memberInfo = GetMemberInfo(member, speculate, location, validatorType);
@@ -556,7 +558,7 @@ namespace Microsoft.Extensions.Options.Generators
             var validatorTypeName = "__" + mt.Name + "Validator__";
 
             var result = new ValidatorType(
-                mt.ContainingNamespace.IsGlobalNamespace ? string.Empty : mt.ContainingNamespace.ToString(),
+                mt.ContainingNamespace.IsGlobalNamespace ? string.Empty : mt.ContainingNamespace.ToString()!,
                 validatorTypeName,
                 validatorTypeName,
                 "class",
@@ -638,12 +640,12 @@ namespace Microsoft.Extensions.Options.Generators
 
             if (type.SpecialType == SpecialType.System_String)
             {
-                return $@"""{EscapeString(value.ToString())}""";
+                return $@"""{EscapeString(value.ToString()!)}""";
             }
 
             if (type.SpecialType == SpecialType.System_Char)
             {
-                return $@"'{EscapeString(value.ToString())}'";
+                return $@"'{EscapeString(value.ToString()!)}'";
             }
 
             return $"({type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}){Convert.ToString(value, CultureInfo.InvariantCulture)}";