Skip to content

Commit

Permalink
Address review feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
layomia committed Jun 25, 2021
1 parent e939506 commit 93a1da7
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public JsonSerializableAttribute(Type type) { }
public string? TypeInfoPropertyName { get; set; }

/// <summary>
/// Determines what the source generator should generate for the type.
/// Determines what the source generator should generate for the type. If the value is <see cref="JsonSourceGenerationMode.Default"/>,
/// then the setting specified on <see cref="JsonSourceGenerationOptionsAttribute.GenerationMode"/> will be used.
/// </summary>
public JsonSourceGenerationMode GenerationMode { get; set; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ namespace System.Text.Json.Serialization
enum JsonSourceGenerationMode
{
/// <summary>
/// Unspecified source generation mode.
/// When specified on <see cref="JsonSourceGenerationOptionsAttribute.GenerationMode"/>, indicates that both type-metadata initialization logic
/// and optimized serialization logic should be generated for all types. When specified on <see cref="JsonSerializableAttribute.GenerationMode"/>,
/// indicates that the setting on <see cref="JsonSourceGenerationOptionsAttribute.GenerationMode"/> should be used.
/// </summary>
Unspecified = 0,
Default = 0,

/// <summary>
/// Instructs the JSON source generator to generate type-metadata initialization logic.
Expand All @@ -28,7 +30,7 @@ enum JsonSourceGenerationMode
Metadata = 1,

/// <summary>
/// Instructs the JSON source generator to generate serialization logic.
/// Instructs the JSON source generator to generate optimized serialization logic.
/// </summary>
/// <remarks>
/// This mode supports only a subset of <see cref="JsonSerializer"/> features.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ class JsonSourceGenerationOptionsAttribute : JsonAttribute
public bool WriteIndented { get; set; }

/// <summary>
/// Specifies the source generation mode.
/// Specifies the source generation mode for types that don't explicitly set the mode with <see cref="JsonSerializableAttribute.GenerationMode"/>.
/// </summary>
public JsonSourceGenerationMode GenerationMode { get; set; } = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization;
public JsonSourceGenerationMode GenerationMode { get; set; }
}
}
36 changes: 28 additions & 8 deletions src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -310,18 +310,19 @@ private static bool TryGetClassDeclarationList(INamedTypeSymbol typeSymbol, [Not
NameEqualsSyntax? propertyNameNode = childNodes.First() as NameEqualsSyntax;
Debug.Assert(propertyNameNode != null);

SyntaxNode? propertyValueMode = childNodes.ElementAtOrDefault(1);
SyntaxNode? propertyValueNode = childNodes.ElementAtOrDefault(1);
string optionName = propertyNameNode.Name.Identifier.ValueText;

if (optionName == nameof(JsonSerializableAttribute.TypeInfoPropertyName))
{
typeInfoPropertyName = propertyValueMode.GetFirstToken().ValueText;
typeInfoPropertyName = propertyValueNode.GetFirstToken().ValueText;
}
else if (optionName == nameof(JsonSerializableAttribute.GenerationMode))
{
if (Enum.TryParse<JsonSourceGenerationMode>(propertyValueMode.GetLastToken().ValueText, out JsonSourceGenerationMode value))
JsonSourceGenerationMode? mode = GetJsonSourceGenerationModeEnumVal(propertyValueNode);
if (mode.HasValue)
{
generationMode = value;
generationMode = mode.Value;
}
}
}
Expand All @@ -348,10 +349,10 @@ private static bool TryGetClassDeclarationList(INamedTypeSymbol typeSymbol, [Not
typeGenerationSpec.TypeInfoPropertyName = typeInfoPropertyName;
}

ClassType classType = typeGenerationSpec.ClassType;
CollectionType collectionType = typeGenerationSpec.CollectionType;
switch (generationMode)
{
case JsonSourceGenerationMode.Default:
break;
case JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization:
typeGenerationSpec.GenerateSerializationLogic = typeGenerationSpec.FastPathIsSupported();
typeGenerationSpec.GenerateMetadata = true;
Expand All @@ -371,6 +372,24 @@ private static bool TryGetClassDeclarationList(INamedTypeSymbol typeSymbol, [Not
return typeGenerationSpec;
}

private static JsonSourceGenerationMode? GetJsonSourceGenerationModeEnumVal(SyntaxNode propertyValueMode)
{
IEnumerable<string> enumTokens = propertyValueMode
.DescendantTokens()
.Where(token => IsValidEnumIdentifier(token.ValueText))
.Select(token => token.ValueText);
string enumAsStr = string.Join(",", enumTokens);

if (Enum.TryParse<JsonSourceGenerationMode>(enumAsStr, out JsonSourceGenerationMode value))
{
return value;
}

return null;

static bool IsValidEnumIdentifier(string token) => token != nameof(JsonSourceGenerationMode) && token != "." && token != "|";
}

private static JsonSourceGenerationOptionsAttribute? GetSerializerOptions(AttributeSyntax? attributeSyntax)
{
if (attributeSyntax == null)
Expand Down Expand Up @@ -452,9 +471,10 @@ private static bool TryGetClassDeclarationList(INamedTypeSymbol typeSymbol, [Not
break;
case nameof(JsonSourceGenerationOptionsAttribute.GenerationMode):
{
if (Enum.TryParse<JsonSourceGenerationMode>(propertyValueStr, out JsonSourceGenerationMode value))
JsonSourceGenerationMode? mode = GetJsonSourceGenerationModeEnumVal(propertyValueNode);
if (mode.HasValue)
{
options.GenerationMode = value;
options.GenerationMode = mode.Value;
}
}
break;
Expand Down
1 change: 0 additions & 1 deletion src/libraries/System.Text.Json/gen/JsonSourceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public void Initialize(GeneratorInitializationContext context)
/// <param name="executionContext"></param>
public void Execute(GeneratorExecutionContext executionContext)
{
//if (!Diagnostics.Debugger.IsAttached) { Diagnostics.Debugger.Launch(); };
SyntaxReceiver receiver = (SyntaxReceiver)executionContext.SyntaxReceiver;
List<ClassDeclarationSyntax>? contextClasses = receiver.ClassDeclarationSyntaxList;
if (contextClasses == null)
Expand Down
6 changes: 4 additions & 2 deletions src/libraries/System.Text.Json/gen/TypeGenerationSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ internal class TypeGenerationSpec
private bool? _generateMetadata;
public bool GenerateMetadata
{
get => _generateMetadata ??= (JsonSourceGenerationMode.Metadata & _generationMode) != 0;
get => _generateMetadata ??= GenerationModeIsSpecified(JsonSourceGenerationMode.Metadata);
// Optionally set during type metadata computation.
set => _generateMetadata = value;
}

private bool? _generateSerializationLogic;
public bool GenerateSerializationLogic
{
get => _generateSerializationLogic ??= ((JsonSourceGenerationMode.Serialization & _generationMode) != 0) && FastPathIsSupported();
get => _generateSerializationLogic ??= GenerationModeIsSpecified(JsonSourceGenerationMode.Serialization) && FastPathIsSupported();
// Optionally set during type metadata computation.
set => _generateSerializationLogic = value;
}
Expand Down Expand Up @@ -117,5 +117,7 @@ public bool FastPathIsSupported()

return false;
}

private bool GenerationModeIsSpecified(JsonSourceGenerationMode mode) => _generationMode == JsonSourceGenerationMode.Default || (mode & _generationMode) != 0;
}
}
2 changes: 1 addition & 1 deletion src/libraries/System.Text.Json/ref/System.Text.Json.cs
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,7 @@ public JsonSourceGenerationOptionsAttribute() { }
[System.FlagsAttribute]
public enum JsonSourceGenerationMode
{
Unspecified = 0,
Default = 0,
Metadata = 1,
Serialization = 2,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace System.Text.Json.SourceGeneration.Tests
[JsonSerializable(typeof(WeatherForecastWithPOCOs), GenerationMode = JsonSourceGenerationMode.Metadata)]
[JsonSerializable(typeof(EmptyPoco), GenerationMode = JsonSourceGenerationMode.Serialization)]
[JsonSerializable(typeof(HighLowTemps), GenerationMode = JsonSourceGenerationMode.Serialization)]
[JsonSerializable(typeof(MyType), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)]
[JsonSerializable(typeof(MyType), GenerationMode = JsonSourceGenerationMode.Default)]
[JsonSerializable(typeof(MyType2), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)]
[JsonSerializable(typeof(MyIntermediateType), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)]
[JsonSerializable(typeof(HighLowTempsImmutable), GenerationMode = JsonSourceGenerationMode.Metadata)]
Expand Down Expand Up @@ -83,7 +83,6 @@ public override void RoundTripCollectionsDictionary()
{
WeatherForecastWithPOCOs expected = CreateWeatherForecastWithPOCOs();

if (!Diagnostics.Debugger.IsAttached) { Diagnostics.Debugger.Launch(); };
string json = JsonSerializer.Serialize(expected, DefaultContext.WeatherForecastWithPOCOs);
JsonTestHelper.AssertThrows_PropMetadataInit(() => JsonSerializer.Deserialize(json, DefaultContext.WeatherForecastWithPOCOs), typeof(HighLowTemps));

Expand Down

0 comments on commit 93a1da7

Please sign in to comment.