diff --git a/Directory.Build.props b/Directory.Build.props index 1a021bada07e7..eea40af21a60b 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -349,6 +349,7 @@ '$(IsPublishedAppTestProject)' != 'true' and '$(IsTestSupportProject)' != 'true' and '$(UsingMicrosoftDotNetSharedFrameworkSdk)' != 'true' and + '$(MSBuildProjectExtension)' != '.pkgproj' and '$(UsingMicrosoftNoTargetsSdk)' != 'true' and '$(UsingMicrosoftTraversalSdk)' != 'true'">true diff --git a/Directory.Build.targets b/Directory.Build.targets index 8af90e774da17..471f5f44e66c2 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -77,7 +77,7 @@ $(PackageDescription) - + $(IsReferenceAssemblyProject) @@ -118,14 +118,15 @@ <_analyzerPath Condition="'$(AnalyzerLanguage)' != ''">$(_analyzerPath)/$(AnalyzerLanguage) + - <_AnalyzerPackFile Include="@(_BuildOutputInPackage)" IsSymbol="false" /> - <_AnalyzerPackFile Include="@(_TargetPathsToSymbols)" IsSymbol="true" /> + <_AnalyzerPackFile Include="@(_BuildOutputInPackage->WithMetadataValue('TargetFramework', 'netstandard2.0'))" IsSymbol="false" /> + <_AnalyzerPackFile Include="@(_TargetPathsToSymbols->WithMetadataValue('TargetFramework', 'netstandard2.0'))" IsSymbol="true" /> <_AnalyzerPackFile PackagePath="$(_analyzerPath)/%(TargetPath)" /> - + @@ -161,6 +162,35 @@ + + + + <_targetingPackReferenceExclusion Include="$(TargetName)" /> + <_targetingPackReferenceExclusion Include="@(_ResolvedProjectReferencePaths->Metadata('Filename'))" /> + <_targetingPackReferenceExclusion Include="@(DefaultReferenceExclusion)" /> + + + + + <_targetingPackReferenceExclusion Include="@(NetFxReference)" /> + <_targetingPackReferenceExclusion Include="netstandard" /> + + + + <_targetingPackReferenceWithProjectName Include="@(Reference->WithMetadataValue('ExternallyResolved', 'true')->Metadata('Filename'))" + OriginalIdentity="%(Identity)" /> + <_targetingPackIncludedReferenceWithProjectName Include="@(_targetingPackReferenceWithProjectName)" + Exclude="@(_targetingPackReferenceExclusion)" /> + <_targetingPackExcludedReferenceWithProjectName Include="@(_targetingPackReferenceWithProjectName)" + Exclude="@(_targetingPackIncludedReferenceWithProjectName)" /> + + + + - 4.4.0-2.22423.18 + 4.4.0 - 4.4.0-2.22423.18 + 4.4.0 $(MicrosoftCodeAnalysisVersion) 1.0.1-beta1.21265.1 diff --git a/eng/packaging.targets b/eng/packaging.targets index f516aff70e6a5..14c07bf40ede7 100644 --- a/eng/packaging.targets +++ b/eng/packaging.targets @@ -150,7 +150,8 @@ + Targets="GetAnalyzerPackFiles" + RemoveProperties="SetTargetFramework"> diff --git a/eng/targetingpacks.targets b/eng/targetingpacks.targets index 2d7d89bde1c6e..1df3493b74c9f 100644 --- a/eng/targetingpacks.targets +++ b/eng/targetingpacks.targets @@ -19,7 +19,7 @@ '$(TargetFrameworkIdentifier)' == '.NETCoreApp' and '$(TargetFrameworkVersion)' == 'v$(NetCoreAppCurrentVersion)'"> true - true + $(UseLocalTargetingRuntimePack) false - - - <_targetingPackReferenceExclusion Include="$(TargetName)" /> - <_targetingPackReferenceExclusion Include="@(_ResolvedProjectReferencePaths->Metadata('Filename'))" /> - <_targetingPackReferenceExclusion Include="@(DefaultReferenceExclusion)" /> - - - - - <_targetingPackReferenceExclusion Include="@(NetFxReference)" /> - <_targetingPackReferenceExclusion Include="netstandard" /> - - - - <_targetingPackReferenceWithProjectName Include="@(Reference->WithMetadataValue('ExternallyResolved', 'true')->Metadata('Filename'))" - OriginalIdentity="%(Identity)" /> - <_targetingPackIncludedReferenceWithProjectName Include="@(_targetingPackReferenceWithProjectName)" - Exclude="@(_targetingPackReferenceExclusion)" /> - <_targetingPackExcludedReferenceWithProjectName Include="@(_targetingPackReferenceWithProjectName)" - Exclude="@(_targetingPackIncludedReferenceWithProjectName)" /> - - - diff --git a/src/libraries/Common/src/Roslyn/SyntaxValueProvider_ForAttributeWithSimpleName.cs b/src/libraries/Common/src/Roslyn/SyntaxValueProvider_ForAttributeWithSimpleName.cs index 3e6f947065a1d..53c718404b30d 100644 --- a/src/libraries/Common/src/Roslyn/SyntaxValueProvider_ForAttributeWithSimpleName.cs +++ b/src/libraries/Common/src/Roslyn/SyntaxValueProvider_ForAttributeWithSimpleName.cs @@ -36,10 +36,10 @@ public SyntaxTreeInfo(SyntaxTree tree, bool containsGlobalAliases, bool contains ContainsAttributeList = containsAttributeList; } - public bool Equals(SyntaxTreeInfo other) + public bool Equals(SyntaxTreeInfo? other) => Tree == other?.Tree; - public override bool Equals(object obj) + public override bool Equals(object? obj) => this.Equals(obj as SyntaxTreeInfo); public override int GetHashCode() diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index b733711bdab52..c7decd2eade99 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -55,6 +55,8 @@ !$(NetCoreAppLibraryNoReference.Contains('$(AssemblyName);'))">true true + + false + Condition="'$(IsNETCoreAppAnalyzer)' == 'true' and + '$(TargetFramework)' == 'netstandard2.0'" /> diff --git a/src/libraries/System.Text.Json/Common/ReflectionExtensions.cs b/src/libraries/System.Text.Json/Common/ReflectionExtensions.cs index 87a0d2b95c96b..ed3414e575b9b 100644 --- a/src/libraries/System.Text.Json/Common/ReflectionExtensions.cs +++ b/src/libraries/System.Text.Json/Common/ReflectionExtensions.cs @@ -41,9 +41,14 @@ internal static partial class ReflectionExtensions public static Type? GetCompatibleGenericBaseClass( this Type type, - Type baseType, + Type? baseType, bool sourceGenType = false) { + if (baseType is null) + { + return null; + } + Debug.Assert(baseType.IsGenericType); Debug.Assert(!baseType.IsInterface); Debug.Assert(baseType == baseType.GetGenericTypeDefinition()); diff --git a/src/libraries/System.Text.Json/System.Text.Json.sln b/src/libraries/System.Text.Json/System.Text.Json.sln index 820721e85b226..948f9d3d8d8b7 100644 --- a/src/libraries/System.Text.Json/System.Text.Json.sln +++ b/src/libraries/System.Text.Json/System.Text.Json.sln @@ -43,7 +43,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json", "ref\Sys EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json", "src\System.Text.Json.csproj", "{1285FF43-F491-4BE0-B92C-37DA689CBD4B}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "System.Text.Json.FSharp.Tests", "tests\System.Text.Json.FSharp.Tests\System.Text.Json.FSharp.Tests.fsproj", "{5720BF06-2031-4AD8-B9B4-31A01E27ABB8}" +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "System.Text.Json.FSharp.Tests", "tests\System.Text.Json.FSharp.Tests\System.Text.Json.FSharp.Tests.fsproj", "{5720BF06-2031-4AD8-B9B4-31A01E27ABB8}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json.TestLibrary.Roslyn3.11", "tests\System.Text.Json.SourceGeneration.TestLibrary\System.Text.Json.TestLibrary.Roslyn3.11.csproj", "{5C0CE30B-DD4A-4F7A-87C0-5243F0C86885}" EndProject @@ -199,35 +199,35 @@ Global EndGlobalSection GlobalSection(NestedProjects) = preSolution {102945CA-3736-4B2C-8E68-242A0B247F2B} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} - {5720BF06-2031-4AD8-B9B4-31A01E27ABB8} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} - {5C0CE30B-DD4A-4F7A-87C0-5243F0C86885} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} - {FCA21178-0411-45D6-B597-B7BE145CEE33} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} - {66AD4B7E-CF15-4A8F-8BF8-7E1BC6176D07} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} - {33599A6C-F340-4E1B-9B4D-CB8946C22140} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} - {256A4653-4287-44B3-BDEF-67FC1522ED2F} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} - {F6A18EB5-A8CC-4A39-9E85-5FA226019C3D} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} - {A0178BAA-A1AF-4C69-8E4A-A700A2723DDC} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} {73D5739C-E382-4E22-A7D3-B82705C58C74} = {0371C5D8-D5F5-4747-9810-D91D71D8C0E4} + {E9AA0AEB-AEAE-4B28-8D4D-17A6D7C89D17} = {E49881A9-09F6-442F-9E1D-6D87F5F837F1} {282400DF-F3D8-4419-90F1-1E2F2D8B760C} = {0371C5D8-D5F5-4747-9810-D91D71D8C0E4} + {6E9E4359-44F8-45AA-AEC5-D0F9FFBB13D6} = {E49881A9-09F6-442F-9E1D-6D87F5F837F1} {09F77672-101E-4495-9D88-29376919C121} = {0371C5D8-D5F5-4747-9810-D91D71D8C0E4} {BE27618A-2916-4269-9AD5-6BC5EDC32B30} = {0371C5D8-D5F5-4747-9810-D91D71D8C0E4} + {1C8262DB-7355-40A8-A2EC-4EED7363134A} = {E49881A9-09F6-442F-9E1D-6D87F5F837F1} {C2C7BA09-F9EE-4E43-8EE4-871CC000342C} = {0371C5D8-D5F5-4747-9810-D91D71D8C0E4} {4774F56D-16A8-4ABB-8C73-5F57609F1773} = {0371C5D8-D5F5-4747-9810-D91D71D8C0E4} + {D05FD93A-BC51-466E-BD56-3F3D6BBE6B06} = {E49881A9-09F6-442F-9E1D-6D87F5F837F1} {B6D364E7-E5DB-4CF4-B87F-3CEDA3FF7478} = {0371C5D8-D5F5-4747-9810-D91D71D8C0E4} + {B815304D-502E-402C-ACE1-878DB4985CCC} = {F254F143-4704-4432-9995-20D87FA8BF8D} + {E4B72517-C694-486A-950E-6AB03C651FDC} = {F254F143-4704-4432-9995-20D87FA8BF8D} {FAB4FFF2-964D-45FF-89CC-8BB9CE618ED1} = {0371C5D8-D5F5-4747-9810-D91D71D8C0E4} {C56337BB-8CBC-4EE5-AB4D-8BB0A922813E} = {0371C5D8-D5F5-4747-9810-D91D71D8C0E4} - {7015E94D-D20D-48C8-86D7-6A996BE99E0E} = {0371C5D8-D5F5-4747-9810-D91D71D8C0E4} - {E9AA0AEB-AEAE-4B28-8D4D-17A6D7C89D17} = {E49881A9-09F6-442F-9E1D-6D87F5F837F1} - {6E9E4359-44F8-45AA-AEC5-D0F9FFBB13D6} = {E49881A9-09F6-442F-9E1D-6D87F5F837F1} - {1C8262DB-7355-40A8-A2EC-4EED7363134A} = {E49881A9-09F6-442F-9E1D-6D87F5F837F1} - {D05FD93A-BC51-466E-BD56-3F3D6BBE6B06} = {E49881A9-09F6-442F-9E1D-6D87F5F837F1} {9BCCDA15-8907-4AE3-8871-2F17775DDE4C} = {E49881A9-09F6-442F-9E1D-6D87F5F837F1} - {1285FF43-F491-4BE0-B92C-37DA689CBD4B} = {E49881A9-09F6-442F-9E1D-6D87F5F837F1} - {B815304D-502E-402C-ACE1-878DB4985CCC} = {F254F143-4704-4432-9995-20D87FA8BF8D} - {E4B72517-C694-486A-950E-6AB03C651FDC} = {F254F143-4704-4432-9995-20D87FA8BF8D} {04AEB008-EE4F-44DE-A361-2DBD2D0FD6A4} = {F254F143-4704-4432-9995-20D87FA8BF8D} {6485EED4-C313-4551-9865-8ADCED603629} = {F254F143-4704-4432-9995-20D87FA8BF8D} {143AFE8A-3490-444C-A82D-6A375EB59F01} = {F254F143-4704-4432-9995-20D87FA8BF8D} + {7015E94D-D20D-48C8-86D7-6A996BE99E0E} = {0371C5D8-D5F5-4747-9810-D91D71D8C0E4} + {1285FF43-F491-4BE0-B92C-37DA689CBD4B} = {E49881A9-09F6-442F-9E1D-6D87F5F837F1} + {5720BF06-2031-4AD8-B9B4-31A01E27ABB8} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} + {5C0CE30B-DD4A-4F7A-87C0-5243F0C86885} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} + {FCA21178-0411-45D6-B597-B7BE145CEE33} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} + {66AD4B7E-CF15-4A8F-8BF8-7E1BC6176D07} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} + {33599A6C-F340-4E1B-9B4D-CB8946C22140} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} + {256A4653-4287-44B3-BDEF-67FC1522ED2F} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} + {F6A18EB5-A8CC-4A39-9E85-5FA226019C3D} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} + {A0178BAA-A1AF-4C69-8E4A-A700A2723DDC} = {E07C6980-EB71-4D19-A80A-7BEB80B635B1} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5868B757-D821-41FC-952E-2113A0519506} diff --git a/src/libraries/System.Text.Json/gen/ContextGenerationSpec.cs b/src/libraries/System.Text.Json/gen/ContextGenerationSpec.cs index b88bd91867200..c42365552ea59 100644 --- a/src/libraries/System.Text.Json/gen/ContextGenerationSpec.cs +++ b/src/libraries/System.Text.Json/gen/ContextGenerationSpec.cs @@ -16,17 +16,17 @@ namespace System.Text.Json.SourceGeneration [DebuggerDisplay("ContextTypeRef={ContextTypeRef}")] internal sealed class ContextGenerationSpec { - public Location Location { get; init; } + public required Location Location { get; init; } - public JsonSourceGenerationOptionsAttribute GenerationOptions { get; init; } + public required JsonSourceGenerationOptionsAttribute GenerationOptions { get; init; } - public Type ContextType { get; init; } + public required Type ContextType { get; init; } public List RootSerializableTypes { get; } = new(); - public HashSet? ImplicitlyRegisteredTypes { get; } = new(); + public HashSet ImplicitlyRegisteredTypes { get; } = new(); - public List ContextClassDeclarationList { get; init; } + public required List ContextClassDeclarationList { get; init; } /// /// Types that we have initiated serialization metadata generation for. A type may be discoverable in the object graph, diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs index fc3d569ff1fb3..1eeefca9b3583 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs @@ -146,7 +146,7 @@ private void AddSource(string fileName, string source, bool isRootContextDef = f int declarationCount = declarationList.Count; Debug.Assert(declarationCount >= 1); - string @namespace = _currentContext.ContextType.Namespace; + string? @namespace = _currentContext.ContextType.Namespace; bool isInGlobalNamespace = @namespace == JsonConstants.GlobalNamespaceValue; StringBuilder sb = new(@"// @@ -226,8 +226,9 @@ private void GenerateTypeInfo(TypeGenerationSpec typeGenerationSpec) break; case ClassType.Nullable: { - source = GenerateForNullable(typeGenerationSpec); + Debug.Assert(typeGenerationSpec.NullableUnderlyingTypeMetadata != null); + source = GenerateForNullable(typeGenerationSpec); GenerateTypeInfo(typeGenerationSpec.NullableUnderlyingTypeMetadata); } break; @@ -238,21 +239,26 @@ private void GenerateTypeInfo(TypeGenerationSpec typeGenerationSpec) break; case ClassType.Enumerable: { - source = GenerateForCollection(typeGenerationSpec); + Debug.Assert(typeGenerationSpec.CollectionValueTypeMetadata != null); + source = GenerateForCollection(typeGenerationSpec); GenerateTypeInfo(typeGenerationSpec.CollectionValueTypeMetadata); } break; case ClassType.Dictionary: { - source = GenerateForCollection(typeGenerationSpec); + Debug.Assert(typeGenerationSpec.CollectionKeyTypeMetadata != null); + Debug.Assert(typeGenerationSpec.CollectionValueTypeMetadata != null); + source = GenerateForCollection(typeGenerationSpec); GenerateTypeInfo(typeGenerationSpec.CollectionKeyTypeMetadata); GenerateTypeInfo(typeGenerationSpec.CollectionValueTypeMetadata); } break; case ClassType.Object: { + Debug.Assert(typeGenerationSpec.PropertyGenSpecList != null); + source = GenerateForObject(typeGenerationSpec); foreach (PropertyGenerationSpec spec in typeGenerationSpec.PropertyGenSpecList) @@ -492,6 +498,8 @@ private string GenerateForCollection(TypeGenerationSpec typeGenerationSpec) private string GenerateFastPathFuncForEnumerable(TypeGenerationSpec typeGenerationSpec) { + Debug.Assert(typeGenerationSpec.CollectionValueTypeMetadata != null); + TypeGenerationSpec valueTypeGenerationSpec = typeGenerationSpec.CollectionValueTypeMetadata; Type elementType = valueTypeGenerationSpec.Type; @@ -542,6 +550,9 @@ private string GenerateFastPathFuncForEnumerable(TypeGenerationSpec typeGenerati private string GenerateFastPathFuncForDictionary(TypeGenerationSpec typeGenerationSpec) { + Debug.Assert(typeGenerationSpec.CollectionKeyTypeMetadata != null); + Debug.Assert(typeGenerationSpec.CollectionValueTypeMetadata != null); + TypeGenerationSpec keyTypeGenerationSpec = typeGenerationSpec.CollectionKeyTypeMetadata; TypeGenerationSpec valueTypeGenerationSpec = typeGenerationSpec.CollectionValueTypeMetadata; @@ -758,6 +769,8 @@ string GenerateCtorParamMetadataInitFunc(TypeGenerationSpec typeGenerationSpec) { const string parametersVarName = "parameters"; + Debug.Assert(typeGenerationSpec.CtorParamGenSpecArray != null); + ParameterGenerationSpec[] parameters = typeGenerationSpec.CtorParamGenSpecArray; int paramCount = parameters.Length; Debug.Assert(paramCount > 0); @@ -945,6 +958,8 @@ private static bool ShouldIncludePropertyForFastPath(PropertyGenerationSpec prop private static string GetParameterizedCtorInvocationFunc(TypeGenerationSpec typeGenerationSpec) { + Debug.Assert(typeGenerationSpec.CtorParamGenSpecArray != null); + ParameterGenerationSpec[] parameters = typeGenerationSpec.CtorParamGenSpecArray; int paramCount = parameters.Length; Debug.Assert(paramCount != 0); @@ -1017,7 +1032,7 @@ private static string GenerateFastPathFuncForType(TypeGenerationSpec typeGenSpec }}"; } - private static string GetEarlyNullCheckSource(bool canBeNull) + private static string? GetEarlyNullCheckSource(bool canBeNull) { return canBeNull ? $@"if ({ValueVarName} == null) @@ -1355,7 +1370,8 @@ string GetParamDefaultValueAsString(object? value, Type type, string typeRef) { // Roslyn gives us an instance of the underlying type, which is numerical. #if DEBUG - Type runtimeType = _generationSpec.MetadataLoadContext.Resolve(value.GetType()); + Type? runtimeType = _generationSpec.MetadataLoadContext.Resolve(value.GetType()!); + Debug.Assert(runtimeType != null); Debug.Assert(_generationSpec.IsNumberType(runtimeType)); #endif diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs index 8d1f090093595..fe6bee3570073 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs @@ -100,14 +100,14 @@ private sealed class Parser private readonly Type? _jsonDocumentType; // Unsupported types - private readonly Type _delegateType; - private readonly Type _memberInfoType; - private readonly Type _serializationInfoType; - private readonly Type _intPtrType; - private readonly Type _uIntPtrType; + private readonly Type? _delegateType; + private readonly Type? _memberInfoType; + private readonly Type? _serializationInfoType; + private readonly Type? _intPtrType; + private readonly Type? _uIntPtrType; // Needed for converter validation - private readonly Type _jsonConverterOfTType; + private readonly Type? _jsonConverterOfTType; private readonly HashSet _numberTypes = new(); private readonly HashSet _knownTypes = new(); @@ -222,7 +222,7 @@ public Parser(Compilation compilation, in JsonSourceGenerationContext sourceGene _stringType = _metadataLoadContext.Resolve(SpecialType.System_String); _dateTimeOffsetType = _metadataLoadContext.Resolve(typeof(DateTimeOffset)); - _byteArrayType = _metadataLoadContext.Resolve(typeof(byte)).MakeArrayType(); + _byteArrayType = _metadataLoadContext.Resolve(SpecialType.System_Byte).MakeArrayType(); _guidType = _metadataLoadContext.Resolve(typeof(Guid)); _uriType = _metadataLoadContext.Resolve(typeof(Uri)); _versionType = _metadataLoadContext.Resolve(typeof(Version)); @@ -250,10 +250,10 @@ public Parser(Compilation compilation, in JsonSourceGenerationContext sourceGene public SourceGenerationSpec? GetGenerationSpec(IEnumerable classDeclarationSyntaxList, CancellationToken cancellationToken) { Compilation compilation = _compilation; - INamedTypeSymbol jsonSerializerContextSymbol = compilation.GetBestTypeByMetadataName(JsonSerializerContextFullName); - INamedTypeSymbol jsonSerializableAttributeSymbol = compilation.GetBestTypeByMetadataName(JsonSerializableAttributeFullName); - INamedTypeSymbol jsonSourceGenerationOptionsAttributeSymbol = compilation.GetBestTypeByMetadataName(JsonSourceGenerationOptionsAttributeFullName); - INamedTypeSymbol jsonConverterOfTAttributeSymbol = compilation.GetBestTypeByMetadataName(JsonConverterOfTFullName); + INamedTypeSymbol? jsonSerializerContextSymbol = compilation.GetBestTypeByMetadataName(JsonSerializerContextFullName); + INamedTypeSymbol? jsonSerializableAttributeSymbol = compilation.GetBestTypeByMetadataName(JsonSerializableAttributeFullName); + INamedTypeSymbol? jsonSourceGenerationOptionsAttributeSymbol = compilation.GetBestTypeByMetadataName(JsonSourceGenerationOptionsAttributeFullName); + INamedTypeSymbol? jsonConverterOfTAttributeSymbol = compilation.GetBestTypeByMetadataName(JsonConverterOfTFullName); if (jsonSerializerContextSymbol == null || jsonSerializableAttributeSymbol == null || @@ -291,8 +291,7 @@ public Parser(Compilation compilation, in JsonSourceGenerationContext sourceGene foreach (AttributeListSyntax attributeListSyntax in classDeclarationSyntax.AttributeLists) { AttributeSyntax attributeSyntax = attributeListSyntax.Attributes.First(); - IMethodSymbol attributeSymbol = compilationSemanticModel.GetSymbolInfo(attributeSyntax, cancellationToken).Symbol as IMethodSymbol; - if (attributeSymbol == null) + if (compilationSemanticModel.GetSymbolInfo(attributeSyntax, cancellationToken).Symbol is not IMethodSymbol attributeSymbol) { continue; } @@ -315,12 +314,12 @@ public Parser(Compilation compilation, in JsonSourceGenerationContext sourceGene continue; } - INamedTypeSymbol contextTypeSymbol = (INamedTypeSymbol)compilationSemanticModel.GetDeclaredSymbol(classDeclarationSyntax, cancellationToken); + INamedTypeSymbol? contextTypeSymbol = compilationSemanticModel.GetDeclaredSymbol(classDeclarationSyntax, cancellationToken); Debug.Assert(contextTypeSymbol != null); Location contextLocation = contextTypeSymbol.Locations.Length > 0 ? contextTypeSymbol.Locations[0] : Location.None; - if (!TryGetClassDeclarationList(contextTypeSymbol, out List classDeclarationList)) + if (!TryGetClassDeclarationList(contextTypeSymbol, out List? classDeclarationList)) { // Class or one of its containing types is not partial so we can't add to it. _sourceGenerationContext.ReportDiagnostic(Diagnostic.Create(ContextClassesMustBePartial, contextLocation, new string[] { contextTypeSymbol.Name })); @@ -357,7 +356,7 @@ public Parser(Compilation compilation, in JsonSourceGenerationContext sourceGene foreach ((Type Type, DiagnosticDescriptor Descriptor, string[] MessageArgs) diagnostic in _typeLevelDiagnostics) { Type type = diagnostic.Type; - Location location = type.GetDiagnosticLocation(); + Location? location = type.GetDiagnosticLocation(); if (location == null) { @@ -475,7 +474,7 @@ private static bool TryGetClassDeclarationList(INamedTypeSymbol typeSymbol, [Not currentSymbol = currentSymbol.ContainingType; } - Debug.Assert(classDeclarationList.Count > 0); + Debug.Assert(classDeclarationList?.Count > 0); return true; } @@ -543,7 +542,7 @@ private static string GetClassDeclarationName(INamedTypeSymbol typeSymbol) NameEqualsSyntax? propertyNameNode = childNodes.First() as NameEqualsSyntax; Debug.Assert(propertyNameNode != null); - SyntaxNode? propertyValueNode = childNodes.ElementAtOrDefault(1); + SyntaxNode propertyValueNode = childNodes.ElementAt(1); string optionName = propertyNameNode.Name.Identifier.ValueText; if (optionName == nameof(JsonSerializableAttribute.TypeInfoPropertyName)) @@ -620,7 +619,7 @@ private static string GetClassDeclarationName(INamedTypeSymbol typeSymbol) NameEqualsSyntax? propertyNameNode = childNodes.First() as NameEqualsSyntax; Debug.Assert(propertyNameNode != null); - SyntaxNode? propertyValueNode = childNodes.ElementAtOrDefault(1); + SyntaxNode propertyValueNode = childNodes.ElementAt(1); string propertyValueStr = propertyValueNode.GetLastToken().ValueText; switch (propertyNameNode.Name.Identifier.ValueText) @@ -698,7 +697,7 @@ private TypeGenerationSpec GetOrAddTypeGenerationSpec(Type type, JsonSourceGener } // Add metadata to cache now to prevent stack overflow when the same type is found somewhere else in the object graph. - typeMetadata = new TypeGenerationSpec(); + typeMetadata = new TypeGenerationSpec(type); _typeGenerationSpecCache[type] = typeMetadata; ClassType classType; @@ -726,12 +725,12 @@ private TypeGenerationSpec GetOrAddTypeGenerationSpec(Type type, JsonSourceGener foreach (CustomAttributeData attributeData in attributeDataList) { Type attributeType = attributeData.AttributeType; - string attributeTypeFullName = attributeType.FullName; + string? attributeTypeFullName = attributeType.FullName; if (attributeTypeFullName == JsonNumberHandlingAttributeFullName) { IList ctorArgs = attributeData.ConstructorArguments; - numberHandling = (JsonNumberHandling)ctorArgs[0].Value; + numberHandling = (JsonNumberHandling)ctorArgs[0].Value!; continue; } else if (!foundDesignTimeCustomConverter && attributeType.GetCompatibleBaseClass(JsonConverterAttributeFullName) != null) @@ -747,14 +746,14 @@ private TypeGenerationSpec GetOrAddTypeGenerationSpec(Type type, JsonSourceGener if (attributeTypeFullName == JsonDerivedTypeAttributeFullName) { Debug.Assert(attributeData.ConstructorArguments.Count > 0); - ITypeSymbol derivedTypeSymbol = (ITypeSymbol)attributeData.ConstructorArguments[0].Value; + ITypeSymbol derivedTypeSymbol = (ITypeSymbol)attributeData.ConstructorArguments[0].Value!; Type derivedType = derivedTypeSymbol.AsType(_metadataLoadContext); TypeGenerationSpec derivedTypeSpec = GetOrAddTypeGenerationSpec(derivedType, generationMode); _implicitlyRegisteredTypes.Add(derivedTypeSpec); if (!isPolymorphic && generationMode == JsonSourceGenerationMode.Serialization) { - _typeLevelDiagnostics.Add((type, PolymorphismNotSupported, new string[] { type.FullName })); + _typeLevelDiagnostics.Add((type, PolymorphismNotSupported, new string[] { type.FullName! })); } isPolymorphic = true; @@ -801,7 +800,7 @@ private TypeGenerationSpec GetOrAddTypeGenerationSpec(Type type, JsonSourceGener constructionStrategy = ObjectConstructionStrategy.ParameterlessConstructor; } - Type actualTypeToConvert; + Type? actualTypeToConvert; Type? keyType = null; Type valueType; bool needsRuntimeType = false; @@ -812,7 +811,7 @@ private TypeGenerationSpec GetOrAddTypeGenerationSpec(Type type, JsonSourceGener ? ClassType.TypeUnsupportedBySourceGen // Multi-dimentional arrays are not supported in STJ. : ClassType.Enumerable; collectionType = CollectionType.Array; - valueType = type.GetElementType(); + valueType = type.GetElementType()!; } else if ((actualTypeToConvert = GetCompatibleGenericBaseClass(type, _listOfTType)) != null) { @@ -914,7 +913,7 @@ private TypeGenerationSpec GetOrAddTypeGenerationSpec(Type type, JsonSourceGener collectionType = CollectionType.IEnumerableOfT; valueType = actualTypeToConvert.GetGenericArguments()[0]; } - else if (_idictionaryType.IsAssignableFrom(type)) + else if (_idictionaryType?.IsAssignableFrom(type) == true) { classType = ClassType.Dictionary; collectionType = CollectionType.IDictionary; @@ -923,19 +922,19 @@ private TypeGenerationSpec GetOrAddTypeGenerationSpec(Type type, JsonSourceGener needsRuntimeType = type == actualTypeToConvert; } - else if (_ilistType.IsAssignableFrom(type)) + else if (_ilistType?.IsAssignableFrom(type) == true) { classType = ClassType.Enumerable; collectionType = CollectionType.IList; valueType = _objectType; } - else if (_stackType.IsAssignableFrom(type)) + else if (_stackType?.IsAssignableFrom(type) == true) { classType = ClassType.Enumerable; collectionType = CollectionType.Stack; valueType = _objectType; } - else if (_queueType.IsAssignableFrom(type)) + else if (_queueType?.IsAssignableFrom(type) == true) { classType = ClassType.Enumerable; collectionType = CollectionType.Queue; @@ -962,8 +961,8 @@ private TypeGenerationSpec GetOrAddTypeGenerationSpec(Type type, JsonSourceGener } else if ( _knownUnsupportedTypes.Contains(type) || - _memberInfoType.IsAssignableFrom(type) || - _delegateType.IsAssignableFrom(type)) + _memberInfoType?.IsAssignableFrom(type) == true || + _delegateType?.IsAssignableFrom(type) == true) { classType = ClassType.KnownUnsupportedType; } @@ -996,7 +995,7 @@ private TypeGenerationSpec GetOrAddTypeGenerationSpec(Type type, JsonSourceGener for (int i = 0; i < paramCount; i++) { - ParameterInfo parameterInfo = parameters[i]; + ParameterInfo parameterInfo = parameters![i]; TypeGenerationSpec typeGenerationSpec = GetOrAddTypeGenerationSpec(parameterInfo.ParameterType, generationMode); paramGenSpecArray[i] = new ParameterGenerationSpec() @@ -1047,7 +1046,7 @@ private TypeGenerationSpec GetOrAddTypeGenerationSpec(Type type, JsonSourceGener continue; } - CacheMemberHelper(propertyInfo.GetDiagnosticLocation()); + CacheMemberHelper(propertyInfo.GetDiagnosticLocation()!); } foreach (FieldInfo fieldInfo in currentType.GetFields(bindingFlags)) @@ -1063,7 +1062,7 @@ private TypeGenerationSpec GetOrAddTypeGenerationSpec(Type type, JsonSourceGener continue; } - CacheMemberHelper(fieldInfo.GetDiagnosticLocation()); + CacheMemberHelper(fieldInfo.GetDiagnosticLocation()!); } void CacheMemberHelper(Location memberLocation) @@ -1115,7 +1114,6 @@ void CacheMemberHelper(Location memberLocation) typeMetadata.Initialize( generationMode, - type, classType, numberHandling, propGenSpecList, @@ -1128,12 +1126,12 @@ void CacheMemberHelper(Location memberLocation) runtimeTypeRef, dataExtensionPropGenSpec, converterInstatiationLogic, - implementsIJsonOnSerialized : implementsIJsonOnSerialized, - implementsIJsonOnSerializing : implementsIJsonOnSerializing, + implementsIJsonOnSerialized: implementsIJsonOnSerialized, + implementsIJsonOnSerializing: implementsIJsonOnSerializing, canContainNullableReferenceAnnotations: canContainNullableReferenceAnnotations, - hasTypeFactoryConverter : hasTypeFactoryConverter, - hasPropertyFactoryConverters : hasPropertyFactoryConverters, - isPolymorphic : isPolymorphic); + hasTypeFactoryConverter: hasTypeFactoryConverter, + hasPropertyFactoryConverters: hasPropertyFactoryConverters, + isPolymorphic: isPolymorphic); return typeMetadata; } @@ -1158,13 +1156,13 @@ private bool IsValidDataExtensionPropertyType(Type type) return genericArguments[0] == _stringType && (genericArguments[1] == _objectType || genericArguments[1] == _jsonElementType); } - private static Type GetCompatibleGenericBaseClass(Type type, Type baseType) + private static Type? GetCompatibleGenericBaseClass(Type type, Type? baseType) => type.GetCompatibleGenericBaseClass(baseType); private static void CacheMember( PropertyGenerationSpec propGenSpec, ref List propGenSpecList, - ref Dictionary ignoredMembers) + ref Dictionary? ignoredMembers) { propGenSpecList.Add(propGenSpec); @@ -1199,6 +1197,7 @@ private PropertyGenerationSpec GetPropertyGenerationSpec( bool isVirtual, JsonSourceGenerationMode generationMode) { + Debug.Assert(memberInfo.DeclaringType != null); Type memberCLRType = GetMemberClrType(memberInfo); IList attributeDataList = CustomAttributeData.GetCustomAttributes(memberInfo); @@ -1336,7 +1335,7 @@ private void ProcessMemberCustomAttributes( namedArgs[0].MemberInfo.MemberType == MemberTypes.Property && ((PropertyInfo)namedArgs[0].MemberInfo).PropertyType.FullName == JsonIgnoreConditionFullName) { - ignoreCondition = (JsonIgnoreCondition)namedArgs[0].TypedValue.Value; + ignoreCondition = (JsonIgnoreCondition)namedArgs[0].TypedValue.Value!; } } break; @@ -1348,20 +1347,20 @@ private void ProcessMemberCustomAttributes( case JsonNumberHandlingAttributeFullName: { IList ctorArgs = attributeData.ConstructorArguments; - numberHandling = (JsonNumberHandling)ctorArgs[0].Value; + numberHandling = (JsonNumberHandling)ctorArgs[0].Value!; } break; case JsonPropertyNameAttributeFullName: { IList ctorArgs = attributeData.ConstructorArguments; - jsonPropertyName = (string)ctorArgs[0].Value; + jsonPropertyName = (string)ctorArgs[0].Value!; // Null check here is done at runtime within JsonSerializer. } break; case JsonPropertyOrderAttributeFullName: { IList ctorArgs = attributeData.ConstructorArguments; - order = (int)ctorArgs[0].Value; + order = (int)ctorArgs[0].Value!; } break; case JsonExtensionDataAttributeFullName: @@ -1474,17 +1473,14 @@ private static bool PropertyAccessorCanBeReferenced(MethodInfo? accessor) return null; } - ITypeSymbol converterTypeSymbol = (ITypeSymbol)attributeData.ConstructorArguments[0].Value; - Type converterType = converterTypeSymbol.AsType(_metadataLoadContext); + ITypeSymbol converterTypeSymbol = (ITypeSymbol)attributeData.ConstructorArguments[0].Value!; + Type? converterType = converterTypeSymbol.AsType(_metadataLoadContext); if (converterType == null || converterType.GetConstructor(Type.EmptyTypes) == null || converterType.IsNestedPrivate) { return null; } - // Validated when creating the source generation spec. - Debug.Assert(_jsonConverterOfTType != null); - if (converterType.GetCompatibleGenericBaseClass(_jsonConverterOfTType) != null) { return $"new {converterType.GetCompilableName()}()"; @@ -1609,9 +1605,9 @@ private void PopulateKnownTypes() AddTypeIfNotNull(_knownTypes, _jsonValueType); AddTypeIfNotNull(_knownTypes, _jsonDocumentType); - _knownUnsupportedTypes.Add(_serializationInfoType); - _knownUnsupportedTypes.Add(_intPtrType); - _knownUnsupportedTypes.Add(_uIntPtrType); + AddTypeIfNotNull(_knownUnsupportedTypes, _serializationInfoType); + AddTypeIfNotNull(_knownUnsupportedTypes, _intPtrType); + AddTypeIfNotNull(_knownUnsupportedTypes, _uIntPtrType); static void AddTypeIfNotNull(HashSet types, Type? type) { diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn3.11.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn3.11.cs index e64735d1d959e..ba0c41dec209c 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn3.11.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn3.11.cs @@ -1,13 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -//#define LAUNCH_DEBUGGER using System.Collections.Generic; -using System.Collections.Immutable; -using System.Diagnostics; using System.Linq; -using System.Reflection; -using System.Text.Json.Reflection; using System.Threading; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -80,7 +75,7 @@ public void OnVisitSyntaxNode(GeneratorSyntaxContext context) { if (IsSyntaxTargetForGeneration(context.Node)) { - ClassDeclarationSyntax classSyntax = GetSemanticTargetForGeneration(context, _cancellationToken); + ClassDeclarationSyntax? classSyntax = GetSemanticTargetForGeneration(context, _cancellationToken); if (classSyntax != null) { (ClassDeclarationSyntaxList ??= new List()).Add(classSyntax); @@ -100,7 +95,7 @@ public void OnVisitSyntaxNode(GeneratorSyntaxContext context) { cancellationToken.ThrowIfCancellationRequested(); - IMethodSymbol attributeSymbol = context.SemanticModel.GetSymbolInfo(attributeSyntax, cancellationToken).Symbol as IMethodSymbol; + IMethodSymbol? attributeSymbol = context.SemanticModel.GetSymbolInfo(attributeSyntax, cancellationToken).Symbol as IMethodSymbol; if (attributeSymbol == null) { continue; @@ -124,7 +119,7 @@ public void OnVisitSyntaxNode(GeneratorSyntaxContext context) /// /// Helper for unit tests. /// - public Dictionary? GetSerializableTypes() => _rootTypes?.ToDictionary(p => p.Type.FullName, p => p.Type); + public Dictionary? GetSerializableTypes() => _rootTypes?.ToDictionary(p => p.Type.FullName!, p => p.Type); private List? _rootTypes; } diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn4.0.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn4.0.cs index 1a7df0e821e60..76139b2940aba 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn4.0.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn4.0.cs @@ -1,16 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -//#define LAUNCH_DEBUGGER using System.Collections.Generic; using System.Collections.Immutable; -using System.Diagnostics; using System.Linq; -using System.Reflection; -using System.Text.Json.Reflection; -using System.Threading; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; #if !ROSLYN4_4_OR_GREATER @@ -70,7 +64,7 @@ private void Execute(Compilation compilation, ImmutableArray /// Helper for unit tests. /// - public Dictionary? GetSerializableTypes() => _rootTypes?.ToDictionary(p => p.Type.FullName, p => p.Type); + public Dictionary? GetSerializableTypes() => _rootTypes?.ToDictionary(p => p.Type.FullName!, p => p.Type); private List? _rootTypes; } diff --git a/src/libraries/System.Text.Json/gen/ParameterGenerationSpec.cs b/src/libraries/System.Text.Json/gen/ParameterGenerationSpec.cs index d430223b0cfd0..bb021ef5b86a2 100644 --- a/src/libraries/System.Text.Json/gen/ParameterGenerationSpec.cs +++ b/src/libraries/System.Text.Json/gen/ParameterGenerationSpec.cs @@ -1,17 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; using System.Reflection; -using System.Text; namespace System.Text.Json.SourceGeneration { internal sealed class ParameterGenerationSpec { - public TypeGenerationSpec TypeGenerationSpec { get; init; } + public required TypeGenerationSpec TypeGenerationSpec { get; init; } - public ParameterInfo ParameterInfo { get; init; } + public required ParameterInfo ParameterInfo { get; init; } } } diff --git a/src/libraries/System.Text.Json/gen/PropertyGenerationSpec.cs b/src/libraries/System.Text.Json/gen/PropertyGenerationSpec.cs index c885f4219c945..ab7411e1c3c4b 100644 --- a/src/libraries/System.Text.Json/gen/PropertyGenerationSpec.cs +++ b/src/libraries/System.Text.Json/gen/PropertyGenerationSpec.cs @@ -14,9 +14,9 @@ internal sealed class PropertyGenerationSpec /// from the because source code might be decorated /// with '@' for reserved keywords, e.g. public string @event { get; set; } /// - public string NameSpecifiedInSourceCode { get; init; } + public required string NameSpecifiedInSourceCode { get; init; } - public string ClrName { get; init; } + public required string ClrName { get; init; } /// /// Is this a property or a field? @@ -45,9 +45,9 @@ internal sealed class PropertyGenerationSpec /// specified ahead-of-time via . /// Only used in fast-path serialization logic. /// - public string RuntimePropertyName { get; init; } + public required string RuntimePropertyName { get; init; } - public string PropertyNameVarName { get; init; } + public required string PropertyNameVarName { get; init; } /// /// Whether the property has a set method. @@ -103,14 +103,14 @@ internal sealed class PropertyGenerationSpec /// /// Generation specification for the property's type. /// - public TypeGenerationSpec TypeGenerationSpec { get; init; } + public required TypeGenerationSpec TypeGenerationSpec { get; init; } /// /// Compilable name of the property's declaring type. /// - public string DeclaringTypeRef { get; init; } + public required string DeclaringTypeRef { get; init; } - public Type DeclaringType { get; init; } + public required Type DeclaringType { get; init; } /// /// Source code to instantiate design-time specified custom converter. diff --git a/src/libraries/System.Text.Json/gen/Reflection/ConstructorInfoWrapper.cs b/src/libraries/System.Text.Json/gen/Reflection/ConstructorInfoWrapper.cs index 2d825dd76a8a6..11a4a83df3111 100644 --- a/src/libraries/System.Text.Json/gen/Reflection/ConstructorInfoWrapper.cs +++ b/src/libraries/System.Text.Json/gen/Reflection/ConstructorInfoWrapper.cs @@ -80,12 +80,12 @@ public override ParameterInfo[] GetParameters() return parameters.ToArray(); } - public override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) + public override object Invoke(BindingFlags invokeAttr, Binder? binder, object?[]? parameters, CultureInfo? culture) { throw new NotSupportedException(); } - public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) + public override object Invoke(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? parameters, CultureInfo? culture) { throw new NotSupportedException(); } diff --git a/src/libraries/System.Text.Json/gen/Reflection/CustomAttributeDataWrapper.cs b/src/libraries/System.Text.Json/gen/Reflection/CustomAttributeDataWrapper.cs index 0e545c25354c9..624b448ea2821 100644 --- a/src/libraries/System.Text.Json/gen/Reflection/CustomAttributeDataWrapper.cs +++ b/src/libraries/System.Text.Json/gen/Reflection/CustomAttributeDataWrapper.cs @@ -18,10 +18,12 @@ public CustomAttributeDataWrapper(AttributeData a, MetadataLoadContextInternal m throw new InvalidOperationException(); } + Debug.Assert(a.AttributeClass != null); + var namedArguments = new List(); foreach (KeyValuePair na in a.NamedArguments) { - var member = a.AttributeClass.BaseTypes().SelectMany(t => t.GetMembers(na.Key)).First(); + ISymbol member = a.AttributeClass.BaseTypes().SelectMany(t => t.GetMembers(na.Key)).First(); MemberInfo memberInfo = member is IPropertySymbol ? new PropertyInfoWrapper((IPropertySymbol)member, metadataLoadContext) @@ -39,8 +41,8 @@ public CustomAttributeDataWrapper(AttributeData a, MetadataLoadContextInternal m continue; } - object value = ca.Kind == TypedConstantKind.Array ? ca.Values : ca.Value; - constructorArguments.Add(new CustomAttributeTypedArgument(ca.Type.AsType(metadataLoadContext), value)); + object? value = ca.Kind == TypedConstantKind.Array ? ca.Values : ca.Value; + constructorArguments.Add(new CustomAttributeTypedArgument(ca.Type.AsType(metadataLoadContext)!, value)); } Constructor = new ConstructorInfoWrapper(a.AttributeConstructor, metadataLoadContext); diff --git a/src/libraries/System.Text.Json/gen/Reflection/FieldInfoWrapper.cs b/src/libraries/System.Text.Json/gen/Reflection/FieldInfoWrapper.cs index 92f053015937e..7fa70db024f38 100644 --- a/src/libraries/System.Text.Json/gen/Reflection/FieldInfoWrapper.cs +++ b/src/libraries/System.Text.Json/gen/Reflection/FieldInfoWrapper.cs @@ -81,7 +81,7 @@ public override object[] GetCustomAttributes(Type attributeType, bool inherit) throw new NotImplementedException(); } - public override object GetValue(object obj) + public override object? GetValue(object? obj) { throw new NotImplementedException(); } @@ -101,7 +101,7 @@ public override bool IsDefined(Type attributeType, bool inherit) throw new NotImplementedException(); } - public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture) + public override void SetValue(object? obj, object? value, BindingFlags invokeAttr, Binder? binder, CultureInfo? culture) { throw new NotImplementedException(); } diff --git a/src/libraries/System.Text.Json/gen/Reflection/MethodInfoWrapper.cs b/src/libraries/System.Text.Json/gen/Reflection/MethodInfoWrapper.cs index 9dd53120504e2..0ccb18a5657c8 100644 --- a/src/libraries/System.Text.Json/gen/Reflection/MethodInfoWrapper.cs +++ b/src/libraries/System.Text.Json/gen/Reflection/MethodInfoWrapper.cs @@ -89,7 +89,7 @@ public override ParameterInfo[] GetParameters() return parameters.ToArray(); } - public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) + public override object? Invoke(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? parameters, CultureInfo? culture) { throw new NotSupportedException(); } diff --git a/src/libraries/System.Text.Json/gen/Reflection/ParameterInfoWrapper.cs b/src/libraries/System.Text.Json/gen/Reflection/ParameterInfoWrapper.cs index ff65a3fcf0b2d..ce3893b946941 100644 --- a/src/libraries/System.Text.Json/gen/Reflection/ParameterInfoWrapper.cs +++ b/src/libraries/System.Text.Json/gen/Reflection/ParameterInfoWrapper.cs @@ -25,7 +25,7 @@ public ParameterInfoWrapper(IParameterSymbol parameter, MetadataLoadContextInter public override bool HasDefaultValue => _parameter.HasExplicitDefaultValue; - public override object DefaultValue => HasDefaultValue ? _parameter.ExplicitDefaultValue : null; + public override object? DefaultValue => HasDefaultValue ? _parameter.ExplicitDefaultValue : null; public override int Position => _parameter.Ordinal; diff --git a/src/libraries/System.Text.Json/gen/Reflection/PropertyInfoWrapper.cs b/src/libraries/System.Text.Json/gen/Reflection/PropertyInfoWrapper.cs index 086c7df4b130a..3e6816a5222fe 100644 --- a/src/libraries/System.Text.Json/gen/Reflection/PropertyInfoWrapper.cs +++ b/src/libraries/System.Text.Json/gen/Reflection/PropertyInfoWrapper.cs @@ -83,7 +83,7 @@ public override MethodInfo GetSetMethod(bool nonPublic) return _property.SetMethod!.AsMethodInfo(_metadataLoadContext); } - public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture) + public override object? GetValue(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? index, CultureInfo? culture) { throw new NotSupportedException(); } @@ -93,7 +93,7 @@ public override bool IsDefined(Type attributeType, bool inherit) throw new NotImplementedException(); } - public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture) + public override void SetValue(object? obj, object? value, BindingFlags invokeAttr, Binder? binder, object?[]? index, CultureInfo? culture) { throw new NotSupportedException(); } diff --git a/src/libraries/System.Text.Json/gen/Reflection/ReflectionExtensions.cs b/src/libraries/System.Text.Json/gen/Reflection/ReflectionExtensions.cs index 1755fabf87913..7f6bd4ebbf2fa 100644 --- a/src/libraries/System.Text.Json/gen/Reflection/ReflectionExtensions.cs +++ b/src/libraries/System.Text.Json/gen/Reflection/ReflectionExtensions.cs @@ -11,7 +11,7 @@ namespace System.Text.Json.Reflection { internal static partial class ReflectionExtensions { - public static CustomAttributeData GetCustomAttributeData(this MemberInfo memberInfo, Type type) + public static CustomAttributeData? GetCustomAttributeData(this MemberInfo memberInfo, Type type) { return memberInfo.CustomAttributes.FirstOrDefault(a => type.IsAssignableFrom(a.AttributeType)); } diff --git a/src/libraries/System.Text.Json/gen/Reflection/TypeExtensions.cs b/src/libraries/System.Text.Json/gen/Reflection/TypeExtensions.cs index b41bc1cd6c34c..ce7839958cf54 100644 --- a/src/libraries/System.Text.Json/gen/Reflection/TypeExtensions.cs +++ b/src/libraries/System.Text.Json/gen/Reflection/TypeExtensions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Reflection { @@ -11,7 +12,7 @@ public static string GetCompilableName(this Type type) { if (type.IsArray) { - return GetCompilableName(type.GetElementType()) + "[]"; + return GetCompilableName(type.GetElementType()!) + "[]"; } if (type.IsGenericParameter) @@ -23,7 +24,7 @@ public static string GetCompilableName(this Type type) sb.Append("global::"); - string @namespace = type.Namespace; + string? @namespace = type.Namespace; if (!string.IsNullOrEmpty(@namespace) && @namespace != JsonConstants.GlobalNamespaceValue) { sb.Append(@namespace); @@ -37,7 +38,7 @@ public static string GetCompilableName(this Type type) static void AppendTypeChain(StringBuilder sb, Type type, Type[] genericArguments, ref int argumentIndex) { - Type declaringType = type.DeclaringType; + Type? declaringType = type.DeclaringType; if (declaringType != null) { AppendTypeChain(sb, declaringType, genericArguments, ref argumentIndex); @@ -75,7 +76,7 @@ public static string GetTypeInfoPropertyName(this Type type) { if (type.IsArray) { - return GetTypeInfoPropertyName(type.GetElementType()) + "Array"; + return GetTypeInfoPropertyName(type.GetElementType()!) + "Array"; } else if (!type.IsGenericType) { @@ -113,7 +114,7 @@ public static bool IsNullableValueType(this Type type, Type nullableOfTType, out return false; } - public static bool IsNullableValueType(this Type type, out Type? underlyingType) + public static bool IsNullableValueType(this Type type, [NotNullWhen(true)] out Type? underlyingType) { if (type.IsGenericType && type.Name.StartsWith("Nullable`1")) { diff --git a/src/libraries/System.Text.Json/gen/Reflection/TypeWrapper.cs b/src/libraries/System.Text.Json/gen/Reflection/TypeWrapper.cs index 64e49cc552741..ad1f1a23dd474 100644 --- a/src/libraries/System.Text.Json/gen/Reflection/TypeWrapper.cs +++ b/src/libraries/System.Text.Json/gen/Reflection/TypeWrapper.cs @@ -4,10 +4,11 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; -using System.Text.Json; using Microsoft.CodeAnalysis; namespace System.Text.Json.Reflection @@ -22,7 +23,7 @@ internal sealed class TypeWrapper : Type private IArrayTypeSymbol? _arrayTypeSymbol; - private Type _elementType; + private Type? _elementType; public TypeWrapper(ITypeSymbol namedTypeSymbol, MetadataLoadContextInternal metadataLoadContext) { @@ -36,7 +37,7 @@ public TypeWrapper(ITypeSymbol namedTypeSymbol, MetadataLoadContextInternal meta private string? _assemblyQualifiedName; - public override string AssemblyQualifiedName + public override string? AssemblyQualifiedName { get { @@ -109,13 +110,13 @@ public override string AssemblyQualifiedName } } - public override Type BaseType => _typeSymbol.BaseType.AsType(_metadataLoadContext); + public override Type? BaseType => _typeSymbol.BaseType.AsType(_metadataLoadContext); - public override Type DeclaringType => _typeSymbol.ContainingType?.ConstructedFrom.AsType(_metadataLoadContext); + public override Type? DeclaringType => _typeSymbol.ContainingType?.ConstructedFrom.AsType(_metadataLoadContext); private string? _fullName; - public override string FullName + public override string? FullName { get { @@ -191,10 +192,10 @@ static void AppendContainingTypes(StringBuilder sb, ITypeSymbol typeSymbol) public override Module Module => throw new NotImplementedException(); - public override string Namespace => + public override string? Namespace => IsArray ? GetElementType().Namespace : - _typeSymbol.ContainingNamespace?.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat.WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.OmittedAsContaining))!; + _typeSymbol.ContainingNamespace?.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat.WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.OmittedAsContaining)); public override Type UnderlyingSystemType => this; @@ -214,17 +215,19 @@ public override string Name public string SimpleName => _typeSymbol.Name; - private Type _enumType; + private Type? _enumType; public override bool IsEnum { get { _enumType ??= _metadataLoadContext.Resolve(typeof(Enum)); + Debug.Assert(_enumType != null); return IsSubclassOf(_enumType); } } + [MemberNotNullWhen(true, nameof(_namedTypeSymbol))] public override bool IsGenericType => _namedTypeSymbol?.IsGenericType == true; public override bool ContainsGenericParameters @@ -236,7 +239,7 @@ public override bool ContainsGenericParameters return true; } - for (INamedTypeSymbol currentSymbol = _namedTypeSymbol; currentSymbol != null; currentSymbol = currentSymbol.ContainingType) + for (INamedTypeSymbol? currentSymbol = _namedTypeSymbol; currentSymbol != null; currentSymbol = currentSymbol.ContainingType) { if (currentSymbol.TypeArguments.Any(arg => arg.TypeKind == TypeKind.TypeParameter)) { @@ -280,6 +283,11 @@ static void AddTypeArguments(List args, INamedTypeSymbol typeSymbol, Metad public override Type GetGenericTypeDefinition() { + if (!IsGenericType) + { + throw new InvalidOperationException(); + } + return _namedTypeSymbol.ConstructedFrom.AsType(_metadataLoadContext); } @@ -415,6 +423,11 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { + if (_namedTypeSymbol is null) + { + return Array.Empty(); + } + var methods = new List(); foreach (ISymbol m in _typeSymbol.GetMembers()) { @@ -471,7 +484,7 @@ public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) return properties.ToArray(); } - public override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) + public override object InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) { throw new NotSupportedException(); } @@ -528,18 +541,18 @@ protected override TypeAttributes GetAttributeFlagsImpl() return _typeAttributes.Value; } - protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) + protected override ConstructorInfo? GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { foreach (ConstructorInfo constructor in GetConstructors(bindingAttr)) { ParameterInfo[] parameters = constructor.GetParameters(); - if (parameters.Length == types.Length) + if (parameters.Length == (types?.Length ?? 0)) { bool mismatched = false; for (int i = 0; i < parameters.Length; i++) { - if (parameters[i].ParameterType != types[i]) + if (parameters[i].ParameterType != types![i]) { mismatched = true; break; @@ -556,12 +569,12 @@ protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, return null; } - protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) + protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { throw new NotImplementedException(); } - protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) + protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { // TODO: performance; caching; honor bindingAttr foreach (PropertyInfo propertyInfo in GetProperties(bindingAttr)) @@ -585,11 +598,12 @@ protected override bool IsArrayImpl() return _arrayTypeSymbol != null; } - private Type _valueType; + private Type? _valueType; protected override bool IsValueTypeImpl() { _valueType ??= _metadataLoadContext.Resolve(typeof(ValueType)); + Debug.Assert(_valueType != null); return IsSubclassOf(_valueType); } @@ -613,9 +627,14 @@ protected override bool IsPrimitiveImpl() throw new NotImplementedException(); } - public override bool IsAssignableFrom(Type c) + public override bool IsAssignableFrom(Type? c) { - TypeWrapper? tr = c as TypeWrapper ?? _metadataLoadContext.Resolve(c) as TypeWrapper; + TypeWrapper? tr = c switch + { + null => null, + TypeWrapper tw => tw, + _ => _metadataLoadContext.Resolve(c) as TypeWrapper, + }; return tr is not null && (tr._typeSymbol.AllInterfaces.Contains(_typeSymbol, SymbolEqualityComparer.Default) || @@ -636,7 +655,7 @@ public override int GetArrayRank() return _arrayTypeSymbol.Rank; } - public override bool Equals(object o) + public override bool Equals(object? o) { if (o is TypeWrapper tw) { @@ -650,16 +669,20 @@ public override bool Equals(object o) return base.Equals(o); } - public override bool Equals(Type o) + public override bool Equals(Type? o) { - if (o is TypeWrapper tw) + if (o != null) { - return _typeSymbol.Equals(tw._typeSymbol, SymbolEqualityComparer.Default); - } - else if (_metadataLoadContext.Resolve(o) is TypeWrapper tww) - { - return _typeSymbol.Equals(tww._typeSymbol, SymbolEqualityComparer.Default); + if (o is TypeWrapper tw) + { + return _typeSymbol.Equals(tw._typeSymbol, SymbolEqualityComparer.Default); + } + else if (_metadataLoadContext.Resolve(o) is TypeWrapper tww) + { + return _typeSymbol.Equals(tww._typeSymbol, SymbolEqualityComparer.Default); + } } + return base.Equals(o); } diff --git a/src/libraries/System.Text.Json/gen/SourceGenerationSpec.cs b/src/libraries/System.Text.Json/gen/SourceGenerationSpec.cs index 09865cd403c5f..429e7dfad67ca 100644 --- a/src/libraries/System.Text.Json/gen/SourceGenerationSpec.cs +++ b/src/libraries/System.Text.Json/gen/SourceGenerationSpec.cs @@ -1,30 +1,27 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; -using System.Text; using System.Text.Json.Reflection; -using Microsoft.CodeAnalysis; namespace System.Text.Json.SourceGeneration { internal sealed class SourceGenerationSpec { - public List ContextGenerationSpecList { get; init; } + public required List ContextGenerationSpecList { get; init; } #if DEBUG - public MetadataLoadContextInternal MetadataLoadContext { get; init; } + public required MetadataLoadContextInternal MetadataLoadContext { get; init; } #endif - public Type BooleanType { get; init; } - public Type ByteArrayType { get; init; } - public Type CharType { get; init; } - public Type DateTimeType { private get; init; } - public Type DateTimeOffsetType { private get; init; } - public Type GuidType { private get; init; } - public Type StringType { private get; init; } + public required Type BooleanType { get; init; } + public Type? ByteArrayType { get; init; } + public required Type CharType { get; init; } + public Type? DateTimeType { private get; init; } + public Type? DateTimeOffsetType { private get; init; } + public Type? GuidType { private get; init; } + public required Type StringType { private get; init; } - public HashSet NumberTypes { private get; init; } + public required HashSet NumberTypes { private get; init; } public bool IsStringBasedType(Type type) => type == StringType || type == DateTimeType || type == DateTimeOffsetType || type == GuidType; diff --git a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.Roslyn3.11.csproj b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.Roslyn3.11.csproj index 48ac8d6904c5d..8806a744913a7 100644 --- a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.Roslyn3.11.csproj +++ b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.Roslyn3.11.csproj @@ -1,6 +1,7 @@ + netstandard2.0 3.11 $(MicrosoftCodeAnalysisVersion_3_11) diff --git a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.Roslyn4.0.csproj b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.Roslyn4.0.csproj index 638e4a6e4b537..f6105fd254134 100644 --- a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.Roslyn4.0.csproj +++ b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.Roslyn4.0.csproj @@ -1,6 +1,7 @@ + netstandard2.0 4.0 $(MicrosoftCodeAnalysisVersion_4_0) $(DefineConstants);ROSLYN4_0_OR_GREATER diff --git a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.Roslyn4.4.csproj b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.Roslyn4.4.csproj index 9e538deef6e31..4aa02a1438bab 100644 --- a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.Roslyn4.4.csproj +++ b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.Roslyn4.4.csproj @@ -1,6 +1,10 @@ + + $(NetCoreAppToolCurrent);netstandard2.0 4.4 $(MicrosoftCodeAnalysisVersion_4_4) $(DefineConstants);ROSLYN4_0_OR_GREATER;ROSLYN4_4_OR_GREATER @@ -17,4 +21,9 @@ + + + + + diff --git a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets index 0b45537c27dfe..9a25add4452e9 100644 --- a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets +++ b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets @@ -1,6 +1,5 @@ - netstandard2.0 $(MSBuildThisFileName) $(MSBuildThisFileName) SR @@ -24,6 +23,8 @@ + + diff --git a/src/libraries/System.Text.Json/gen/TypeGenerationSpec.cs b/src/libraries/System.Text.Json/gen/TypeGenerationSpec.cs index 08032264b725f..5d6f09591afba 100644 --- a/src/libraries/System.Text.Json/gen/TypeGenerationSpec.cs +++ b/src/libraries/System.Text.Json/gen/TypeGenerationSpec.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Reflection; using System.Text.Json.Reflection; using System.Text.Json.Serialization; using Microsoft.CodeAnalysis; @@ -14,10 +13,18 @@ namespace System.Text.Json.SourceGeneration [DebuggerDisplay("Type={Type}, ClassType={ClassType}")] internal sealed class TypeGenerationSpec { + public TypeGenerationSpec(Type type) + { + Type = type; + TypeRef = type.GetCompilableName(); + TypeInfoPropertyName = type.GetTypeInfoPropertyName(); + IsValueType = type.IsValueType; + } + /// /// Fully qualified assembly name, prefixed with "global::", e.g. global::System.Numerics.BigInteger. /// - public string TypeRef { get; private set; } + public string TypeRef { get; private init; } /// /// If specified as a root type via JsonSerializableAttribute, specifies the location of the attribute application. @@ -42,7 +49,7 @@ internal sealed class TypeGenerationSpec public bool GenerateSerializationLogic => GenerationModeIsSpecified(JsonSourceGenerationMode.Serialization) && FastPathIsSupported(); - public Type Type { get; private set; } + public Type Type { get; private init; } public ClassType ClassType { get; private set; } @@ -50,7 +57,7 @@ internal sealed class TypeGenerationSpec public bool ImplementsIJsonOnSerializing { get; private set; } public bool IsPolymorphic { get; private set; } - public bool IsValueType { get; private set; } + public bool IsValueType { get; private init; } public bool CanBeNull { get; private set; } @@ -93,7 +100,7 @@ public string? ImmutableCollectionBuilderName { get { - string builderName; + string? builderName; if (CollectionType == CollectionType.ImmutableDictionary) { @@ -115,7 +122,6 @@ public string? ImmutableCollectionBuilderName public void Initialize( JsonSourceGenerationMode generationMode, - Type type, ClassType classType, JsonNumberHandling? numberHandling, List? propertyGenSpecList, @@ -136,11 +142,7 @@ public void Initialize( bool isPolymorphic) { GenerationMode = generationMode; - TypeRef = type.GetCompilableName(); - TypeInfoPropertyName = type.GetTypeInfoPropertyName(); - Type = type; ClassType = classType; - IsValueType = type.IsValueType; CanBeNull = !IsValueType || nullableUnderlyingTypeMetadata != null; IsPolymorphic = isPolymorphic; NumberHandling = numberHandling; @@ -166,6 +168,8 @@ public bool TryFilterSerializableProps( [NotNullWhen(true)] out Dictionary? serializableProperties, out bool castingRequiredForProps) { + Debug.Assert(PropertyGenSpecList != null); + castingRequiredForProps = false; serializableProperties = new Dictionary(); Dictionary? ignoredMembers = null; @@ -283,6 +287,8 @@ private bool FastPathIsSupported() return false; } + Debug.Assert(PropertyGenSpecList != null); + foreach (PropertyGenerationSpec property in PropertyGenSpecList) { if (property.TypeGenerationSpec.Type.IsObjectType() ||