diff --git a/eng/Versions.props b/eng/Versions.props
index 021b31aa65bcc..02eefd820a2d4 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -41,9 +41,9 @@
-
- 3.9.0
- 3.9.0
+
+ 4.0.0-3.final
+ 4.0.0-3.final
diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs
index 9fb4433e743bd..ceae5d7a55296 100644
--- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs
+++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs
@@ -78,15 +78,15 @@ private sealed partial class Emitter
defaultSeverity: DiagnosticSeverity.Warning,
isEnabledByDefault: true);
- private readonly GeneratorExecutionContext _executionContext;
+ private readonly SourceProductionContext _sourceProductionContext;
private ContextGenerationSpec _currentContext = null!;
private readonly SourceGenerationSpec _generationSpec = null!;
- public Emitter(in GeneratorExecutionContext executionContext, SourceGenerationSpec generationSpec)
+ public Emitter(in SourceProductionContext sourceProductionContext, SourceGenerationSpec generationSpec)
{
- _executionContext = executionContext;
+ _sourceProductionContext = sourceProductionContext;
_generationSpec = generationSpec;
}
@@ -165,7 +165,7 @@ namespace {@namespace}
sb.AppendLine("}");
}
- _executionContext.AddSource(fileName, SourceText.From(sb.ToString(), Encoding.UTF8));
+ _sourceProductionContext.AddSource(fileName, SourceText.From(sb.ToString(), Encoding.UTF8));
}
private void GenerateTypeInfo(TypeGenerationSpec typeGenerationSpec)
@@ -242,7 +242,7 @@ private void GenerateTypeInfo(TypeGenerationSpec typeGenerationSpec)
break;
case ClassType.TypeUnsupportedBySourceGen:
{
- _executionContext.ReportDiagnostic(
+ _sourceProductionContext.ReportDiagnostic(
Diagnostic.Create(TypeNotSupported, Location.None, new string[] { typeGenerationSpec.TypeRef }));
return;
}
@@ -258,7 +258,7 @@ private void GenerateTypeInfo(TypeGenerationSpec typeGenerationSpec)
}
catch (ArgumentException)
{
- _executionContext.ReportDiagnostic(Diagnostic.Create(DuplicateTypeName, Location.None, new string[] { typeGenerationSpec.TypeInfoPropertyName }));
+ _sourceProductionContext.ReportDiagnostic(Diagnostic.Create(DuplicateTypeName, Location.None, new string[] { typeGenerationSpec.TypeInfoPropertyName }));
}
}
diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs
index 33a60562a3a10..2d38c15ddc0ce 100644
--- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs
+++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs
@@ -4,6 +4,7 @@
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
@@ -31,7 +32,8 @@ private sealed class Parser
private const string JsonPropertyNameAttributeFullName = "System.Text.Json.Serialization.JsonPropertyNameAttribute";
private const string JsonPropertyOrderAttributeFullName = "System.Text.Json.Serialization.JsonPropertyOrderAttribute";
- private readonly GeneratorExecutionContext _executionContext;
+ private readonly Compilation _compilation;
+ private readonly SourceProductionContext _sourceProductionContext;
private readonly MetadataLoadContextInternal _metadataLoadContext;
private readonly Type _ilistOfTType;
@@ -96,10 +98,11 @@ private sealed class Parser
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);
- public Parser(in GeneratorExecutionContext executionContext)
+ public Parser(Compilation compilation, in SourceProductionContext sourceProductionContext)
{
- _executionContext = executionContext;
- _metadataLoadContext = new MetadataLoadContextInternal(executionContext.Compilation);
+ _compilation = compilation;
+ _sourceProductionContext = sourceProductionContext;
+ _metadataLoadContext = new MetadataLoadContextInternal(_compilation);
_ilistOfTType = _metadataLoadContext.Resolve(SpecialType.System_Collections_Generic_IList_T);
_icollectionOfTType = _metadataLoadContext.Resolve(SpecialType.System_Collections_Generic_ICollection_T);
@@ -138,9 +141,9 @@ public Parser(in GeneratorExecutionContext executionContext)
PopulateKnownTypes();
}
- public SourceGenerationSpec? GetGenerationSpec(List classDeclarationSyntaxList)
+ public SourceGenerationSpec? GetGenerationSpec(ImmutableArray classDeclarationSyntaxList)
{
- Compilation compilation = _executionContext.Compilation;
+ Compilation compilation = _compilation;
INamedTypeSymbol jsonSerializerContextSymbol = compilation.GetTypeByMetadataName("System.Text.Json.Serialization.JsonSerializerContext");
INamedTypeSymbol jsonSerializableAttributeSymbol = compilation.GetTypeByMetadataName("System.Text.Json.Serialization.JsonSerializableAttribute");
INamedTypeSymbol jsonSourceGenerationOptionsAttributeSymbol = compilation.GetTypeByMetadataName("System.Text.Json.Serialization.JsonSourceGenerationOptionsAttribute");
@@ -198,7 +201,7 @@ public Parser(in GeneratorExecutionContext executionContext)
if (!TryGetClassDeclarationList(contextTypeSymbol, out List classDeclarationList))
{
// Class or one of its containing types is not partial so we can't add to it.
- _executionContext.ReportDiagnostic(Diagnostic.Create(ContextClassesMustBePartial, Location.None, new string[] { contextTypeSymbol.Name }));
+ _sourceProductionContext.ReportDiagnostic(Diagnostic.Create(ContextClassesMustBePartial, Location.None, new string[] { contextTypeSymbol.Name }));
continue;
}
@@ -729,7 +732,7 @@ private TypeGenerationSpec GetOrAddTypeGenerationSpec(Type type, JsonSourceGener
if (!type.TryGetDeserializationConstructor(useDefaultCtorInAnnotatedStructs, out ConstructorInfo? constructor))
{
classType = ClassType.TypeUnsupportedBySourceGen;
- _executionContext.ReportDiagnostic(Diagnostic.Create(MultipleJsonConstructorAttribute, Location.None, new string[] { $"{type}" }));
+ _sourceProductionContext.ReportDiagnostic(Diagnostic.Create(MultipleJsonConstructorAttribute, Location.None, new string[] { $"{type}" }));
}
else
{
diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.cs
index 84212e8c19c78..54b76c7e061ba 100644
--- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.cs
+++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
@@ -16,22 +17,23 @@ namespace System.Text.Json.SourceGeneration
/// Generates source code to optimize serialization and deserialization with JsonSerializer.
///
[Generator]
- public sealed partial class JsonSourceGenerator : ISourceGenerator
+ public sealed partial class JsonSourceGenerator : IIncrementalGenerator
{
- ///
- /// Registers a syntax resolver to receive compilation units.
- ///
- ///
- public void Initialize(GeneratorInitializationContext context)
+ private const string SystemTextJsonSourceGenerationName = "System.Text.Json.SourceGeneration";
+ private const string IJsonOnSerializedFullName = "System.Text.Json.Serialization.IJsonOnSerialized";
+ private const string IJsonOnSerializingFullName = "System.Text.Json.Serialization.IJsonOnSerializing";
+
+
+ public void Initialize(IncrementalGeneratorInitializationContext context)
{
- context.RegisterForSyntaxNotifications(() => new SyntaxReceiver());
+ var classDeclarations = context.SyntaxProvider.CreateSyntaxProvider((s, _) => s is ClassDeclarationSyntax, (s, _) => (ClassDeclarationSyntax)s.Node);
+
+ var compilationAndClasses = context.CompilationProvider.Combine(classDeclarations.Collect());
+
+ context.RegisterSourceOutput(compilationAndClasses, (spc, source) => Execute(source.Left, source.Right, spc));
}
- ///
- /// Generates source code to optimize serialization and deserialization with JsonSerializer.
- ///
- ///
- public void Execute(GeneratorExecutionContext executionContext)
+ private void Execute(Compilation compilation, ImmutableArray contextClasses, SourceProductionContext context)
{
#if LAUNCH_DEBUGGER
if (!Diagnostics.Debugger.IsAttached)
@@ -39,36 +41,22 @@ public void Execute(GeneratorExecutionContext executionContext)
Diagnostics.Debugger.Launch();
}
#endif
- SyntaxReceiver receiver = (SyntaxReceiver)executionContext.SyntaxReceiver;
- List? contextClasses = receiver.ClassDeclarationSyntaxList;
- if (contextClasses == null)
+ if (contextClasses.IsDefaultOrEmpty)
{
return;
}
- Parser parser = new(executionContext);
- SourceGenerationSpec? spec = parser.GetGenerationSpec(receiver.ClassDeclarationSyntaxList);
+ Parser parser = new(compilation, context);
+ SourceGenerationSpec? spec = parser.GetGenerationSpec(contextClasses);
if (spec != null)
{
_rootTypes = spec.ContextGenerationSpecList[0].RootSerializableTypes;
- Emitter emitter = new(executionContext, spec);
+ Emitter emitter = new(context, spec);
emitter.Emit();
}
}
- private sealed class SyntaxReceiver : ISyntaxReceiver
- {
- public List? ClassDeclarationSyntaxList { get; private set; }
-
- public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
- {
- if (syntaxNode is ClassDeclarationSyntax { AttributeLists.Count: > 0, BaseList.Types.Count: > 0 } cds)
- {
- (ClassDeclarationSyntaxList ??= new List()).Add(cds);
- }
- }
- }
///
/// Helper for unit tests.