-
Notifications
You must be signed in to change notification settings - Fork 201
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Json serializer type discovery (#18)
* Create JsonSerializableAttribute attribute for type discovery * Include reflection utils and implement basic type discovery * Update unit tests for TypeDiscovery * Use linq for cleaner JsonSerializationSyntaxReceiver * Update license for reflection utils * Update tests and generator to latest model * Add external class unit tests for Type Discovery * Update summary, variable names and other nits * Update csharp coding style applied to vars * Separated Unit Tests into helper classes and minor changes for nullables in Syntax Receiver * Create test cases checking full type wrapper in end to end and change typewrapper to show private methods * Update dicitonary to list for syntax receiver * Separate syntax receiver to new file
- Loading branch information
Showing
22 changed files
with
1,428 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...on/System.Text.Json.SourceGeneration.Tests/System.Text.Json.SourceGeneration.Tests.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
...ries/System.Text.Json/System.Text.Json.SourceGeneration/JsonSerializableSyntaxReceiver.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
|
||
namespace System.Text.Json.SourceGeneration | ||
{ | ||
public class JsonSerializableSyntaxReceiver : ISyntaxReceiver | ||
{ | ||
public List<KeyValuePair<string, IdentifierNameSyntax>> ExternalClassTypes = new List<KeyValuePair<string, IdentifierNameSyntax>>(); | ||
public List<KeyValuePair<string, TypeDeclarationSyntax>> InternalClassTypes = new List<KeyValuePair<string, TypeDeclarationSyntax>>(); | ||
|
||
public void OnVisitSyntaxNode(SyntaxNode syntaxNode) | ||
{ | ||
// Look for classes or structs for JsonSerializable Attribute. | ||
if (syntaxNode is ClassDeclarationSyntax || syntaxNode is StructDeclarationSyntax) | ||
{ | ||
// Find JsonSerializable Attributes. | ||
IEnumerable<AttributeSyntax>? serializableAttributes = null; | ||
AttributeListSyntax attributeList = ((TypeDeclarationSyntax)syntaxNode).AttributeLists.SingleOrDefault(); | ||
if (attributeList != null) | ||
{ | ||
serializableAttributes = attributeList.Attributes.Where(node => (node is AttributeSyntax attr && attr.Name.ToString() == "JsonSerializable")).Cast<AttributeSyntax>(); | ||
} | ||
|
||
if (serializableAttributes?.Any() == true) | ||
{ | ||
// JsonSerializableAttribute has AllowMultiple as False, should only have 1 attribute. | ||
Debug.Assert(serializableAttributes.Count() == 1); | ||
AttributeSyntax attributeNode = serializableAttributes.First(); | ||
|
||
// Check if the attribute is being passed a type. | ||
if (attributeNode.DescendantNodes().Where(node => node is TypeOfExpressionSyntax).Any()) | ||
{ | ||
// Get JsonSerializable attribute arguments. | ||
AttributeArgumentSyntax attributeArgumentNode = (AttributeArgumentSyntax)attributeNode.DescendantNodes().Where(node => node is AttributeArgumentSyntax).SingleOrDefault(); | ||
// Get external class token from arguments. | ||
IdentifierNameSyntax externalTypeNode = (IdentifierNameSyntax)attributeArgumentNode?.DescendantNodes().Where(node => node is IdentifierNameSyntax).SingleOrDefault(); | ||
ExternalClassTypes.Add(new KeyValuePair<string, IdentifierNameSyntax>(((TypeDeclarationSyntax)syntaxNode).Identifier.Text, externalTypeNode)); | ||
} | ||
else | ||
{ | ||
InternalClassTypes.Add(new KeyValuePair<string, TypeDeclarationSyntax>(((TypeDeclarationSyntax)syntaxNode).Identifier.Text, (TypeDeclarationSyntax)syntaxNode)); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.