Skip to content

Commit

Permalink
Enable Nullable compilation on the Options source gen (#88973)
Browse files Browse the repository at this point in the history
Co-authored-by: Viktor Hofer <[email protected]>
  • Loading branch information
tarekgh and ViktorHofer authored Jul 18, 2023
1 parent 6ae364d commit 6c3af6a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 12 deletions.
6 changes: 3 additions & 3 deletions src/libraries/Microsoft.Extensions.Options/gen/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@ public class Generator : IIncrementalGenerator
{
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))
{
Expand Down
Original file line number Diff line number Diff line change
@@ -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>
Expand Down Expand Up @@ -32,4 +35,5 @@
<Compile Include="SymbolLoader.cs" />
<Compile Include="TypeDeclarationSyntaxReceiver.cs" />
</ItemGroup>

</Project>
18 changes: 10 additions & 8 deletions src/libraries/Microsoft.Extensions.Options/gen/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ public IReadOnlyList<ValidatorType> GetValidatorTypes(IEnumerable<(TypeDeclarati
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);
Expand Down Expand Up @@ -128,7 +129,7 @@ public IReadOnlyList<ValidatorType> GetValidatorTypes(IEnumerable<(TypeDeclarati
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,
Expand Down Expand Up @@ -267,8 +268,9 @@ private List<ValidatedMember> GetMembersToValidate(ITypeSymbol modelType, bool s
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);
Expand Down Expand Up @@ -556,7 +558,7 @@ private List<ValidatedMember> GetMembersToValidate(ITypeSymbol modelType, bool s
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",
Expand Down Expand Up @@ -638,12 +640,12 @@ private string GetArgumentExpression(ITypeSymbol type, object? value)

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)}";
Expand Down

0 comments on commit 6c3af6a

Please sign in to comment.