diff --git a/Source/Tools/Flax.Build/Build/NativeCpp/Builder.NativeCpp.cs b/Source/Tools/Flax.Build/Build/NativeCpp/Builder.NativeCpp.cs index 086cff297..225e46ba7 100644 --- a/Source/Tools/Flax.Build/Build/NativeCpp/Builder.NativeCpp.cs +++ b/Source/Tools/Flax.Build/Build/NativeCpp/Builder.NativeCpp.cs @@ -7,7 +7,8 @@ using System.Linq; using Flax.Build.Bindings; using Flax.Build.Graph; using Flax.Build.NativeCpp; -using Newtonsoft.Json; +using System.Text.Json.Serialization; +using System.Text.Json; namespace Flax.Build { @@ -56,34 +57,52 @@ namespace Flax.Build { public string Name; - [NonSerialized] + [JsonIgnore] public string NativePath; - [JsonProperty("NativePath")] + [JsonPropertyName("NativePath")] public string NativePathProcessed; - [NonSerialized] + [JsonIgnore] public string ManagedPath; - [JsonProperty("ManagedPath")] + [JsonPropertyName("ManagedPath")] public string ManagedPathProcessed; } public class BuildTargetReferenceInfo { - [NonSerialized] + [JsonIgnore] public string ProjectPath; - [JsonProperty("ProjectPath")] + [JsonPropertyName("ProjectPath")] public string ProjectPathProcessed; - [NonSerialized] + [JsonIgnore] public string Path; - [JsonProperty("Path")] + [JsonPropertyName("Path")] public string PathProcessed; } + [JsonSourceGenerationOptions(IncludeFields = true)] + [JsonSerializable(typeof(BuildTargetBinaryModuleInfo))] + internal partial class BuildTargetBinaryModuleInfoSourceGenerationContext : JsonSerializerContext + { + } + + [JsonSourceGenerationOptions(IncludeFields = true)] + [JsonSerializable(typeof(BuildTargetReferenceInfo))] + internal partial class BuildTargetReferenceInfoSourceGenerationContext : JsonSerializerContext + { + } + + [JsonSourceGenerationOptions(IncludeFields = true)] + [JsonSerializable(typeof(BuildTargetInfo))] + internal partial class BuildTargetInfoSourceGenerationContext : JsonSerializerContext + { + } + public class BuildTargetInfo { public string Name; @@ -985,7 +1004,7 @@ namespace Flax.Build buildData.BuildInfo.AddReferencedBuilds(ref i, project.ProjectFolderPath, buildData.ReferenceBuilds); if (!buildData.Target.IsPreBuilt) - Utilities.WriteFileIfChanged(Path.Combine(outputPath, target.Name + ".Build.json"), JsonConvert.SerializeObject(buildData.BuildInfo, Formatting.Indented)); + Utilities.WriteFileIfChanged(Path.Combine(outputPath, target.Name + ".Build.json"), JsonSerializer.Serialize(buildData.BuildInfo, new JsonSerializerOptions() { WriteIndented = true, IncludeFields = true, TypeInfoResolver = BuildTargetInfoSourceGenerationContext.Default })); } // Deploy files @@ -1184,7 +1203,7 @@ namespace Flax.Build buildData.BuildInfo.AddReferencedBuilds(ref i, project.ProjectFolderPath, buildData.ReferenceBuilds); if (!buildData.Target.IsPreBuilt) - Utilities.WriteFileIfChanged(Path.Combine(outputPath, target.Name + ".Build.json"), JsonConvert.SerializeObject(buildData.BuildInfo, Formatting.Indented)); + Utilities.WriteFileIfChanged(Path.Combine(outputPath, target.Name + ".Build.json"), JsonSerializer.Serialize(buildData.BuildInfo, new JsonSerializerOptions() { WriteIndented = true, IncludeFields = true, TypeInfoResolver = BuildTargetInfoSourceGenerationContext.Default })); } // Deploy files diff --git a/Source/Tools/Flax.Build/Flax.Build.csproj b/Source/Tools/Flax.Build/Flax.Build.csproj index 626b81502..9c837ee89 100644 --- a/Source/Tools/Flax.Build/Flax.Build.csproj +++ b/Source/Tools/Flax.Build/Flax.Build.csproj @@ -41,9 +41,6 @@ ..\..\..\Source\Platforms\DotNet\System.Text.Encoding.CodePages.dll - - ..\..\..\Source\Platforms\DotNet\Newtonsoft.Json.dll - ..\..\..\Source\Platforms\DotNet\Mono.Cecil.dll diff --git a/Source/Tools/Flax.Build/ProjectInfo.cs b/Source/Tools/Flax.Build/ProjectInfo.cs index 78cb48107..7830f59c1 100644 --- a/Source/Tools/Flax.Build/ProjectInfo.cs +++ b/Source/Tools/Flax.Build/ProjectInfo.cs @@ -4,11 +4,12 @@ using System; using System.IO; using System.Collections.Generic; using System.Linq; -using Newtonsoft.Json; +using System.Text.Json; +using System.Text.Json.Serialization; namespace Flax.Build { - public class FlaxVersionConverter : JsonConverter + public class FlaxVersionConverter : JsonConverter { /// /// Writes the JSON representation of the object. @@ -16,20 +17,9 @@ namespace Flax.Build /// The to write to. /// The value. /// The calling serializer. - public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) + public override void Write(Utf8JsonWriter writer, Version value, JsonSerializerOptions options) { - if (value == null) - { - writer.WriteNull(); - } - else if (value is Version) - { - writer.WriteValue(value.ToString()); - } - else - { - throw new JsonSerializationException("Expected Version object value"); - } + writer.WriteStringValue(value.ToString()); } /// @@ -40,27 +30,27 @@ namespace Flax.Build /// The existing property value of the JSON that is being converted. /// The calling serializer. /// The object value. - public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) + public override Version? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - if (reader.TokenType == JsonToken.Null) + if (reader.TokenType == JsonTokenType.Null) { return null; } else { - if (reader.TokenType == JsonToken.StartObject) + if (reader.TokenType == JsonTokenType.StartObject) { try { reader.Read(); Dictionary values = new Dictionary(); - while (reader.TokenType == JsonToken.PropertyName) + while (reader.TokenType == JsonTokenType.PropertyName) { - var key = reader.Value as string; + var key = reader.GetString(); reader.Read(); - var val = (long)reader.Value; + var val = reader.GetInt32(); reader.Read(); - values.Add(key, (int)val); + values.Add(key, val); } int major = 0, minor = 0, build = 0; @@ -73,24 +63,24 @@ namespace Flax.Build } catch (Exception ex) { - throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex); + throw new Exception(String.Format("Error parsing version string: {0}", reader.GetString()), ex); } } - else if (reader.TokenType == JsonToken.String) + else if (reader.TokenType == JsonTokenType.String) { try { - Version v = new Version((string)reader.Value!); + Version v = new Version((string)reader.GetString()!); return v; } catch (Exception ex) { - throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex); + throw new Exception(String.Format("Error parsing version string: {0}", reader.GetString()), ex); } } else { - throw new Exception(String.Format("Unexpected token or value when parsing version. Token: {0}, Value: {1}", reader.TokenType, reader.Value)); + throw new Exception(String.Format("Unexpected token or value when parsing version. Token: {0}, Value: {1}", reader.TokenType, reader.GetString())); } } } @@ -108,6 +98,51 @@ namespace Flax.Build } } + public class ConfigurationDictionaryConverter : System.Text.Json.Serialization.JsonConverter> + { + public override Dictionary? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var dictionary = new Dictionary(); + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + return dictionary; + if (reader.TokenType != JsonTokenType.PropertyName) + throw new Exception(); + + string key = reader.GetString(); + reader.Read(); + + string value; + if (reader.TokenType == JsonTokenType.True) + value = "true"; + else if (reader.TokenType == JsonTokenType.False) + value = "false"; + else + value = reader.GetString(); + dictionary.Add(key, value); + } + throw new Exception(); + } + + public override void Write(Utf8JsonWriter writer, Dictionary dictionary, JsonSerializerOptions options) + { + writer.WriteStartObject(); + foreach ((string key, string value) in dictionary) + { + var propertyName = key.ToString(); + writer.WritePropertyName(options.PropertyNamingPolicy?.ConvertName(propertyName) ?? propertyName); + writer.WriteStringValue(value); + } + writer.WriteEndObject(); + } + } + + [JsonSourceGenerationOptions(IncludeFields = true)] + [JsonSerializable(typeof(ProjectInfo))] + internal partial class ProjectInfoSourceGenerationContext : JsonSerializerContext + { + } /// /// Contains information about Flax project. @@ -129,7 +164,7 @@ namespace Flax.Build /// /// The referenced project. /// - [NonSerialized] + [JsonIgnore] public ProjectInfo Project; /// @@ -147,13 +182,13 @@ namespace Flax.Build /// /// The project file path. /// - [NonSerialized] + [JsonIgnore] public string ProjectPath; /// /// The project root folder path. /// - [NonSerialized] + [JsonIgnore] public string ProjectFolderPath; /// @@ -199,6 +234,7 @@ namespace Flax.Build /// /// The custom build configuration entries loaded from project file. /// + [System.Text.Json.Serialization.JsonConverter(typeof(ConfigurationDictionaryConverter))] public Dictionary Configuration; /// @@ -255,7 +291,7 @@ namespace Flax.Build /// public void Save() { - var contents = JsonConvert.SerializeObject(this, new JsonSerializerSettings() { Converters = new[] { new FlaxVersionConverter() } }); + var contents = JsonSerializer.Serialize(this, new JsonSerializerOptions() { Converters = { new FlaxVersionConverter() }, TypeInfoResolver = ProjectInfoSourceGenerationContext.Default }); File.WriteAllText(ProjectPath, contents); } @@ -281,7 +317,8 @@ namespace Flax.Build // Load Log.Verbose("Loading project file from \"" + path + "\"..."); var contents = File.ReadAllText(path); - var project = JsonConvert.DeserializeObject(contents, new JsonSerializerSettings() { Converters = new[] { new FlaxVersionConverter() } }); + var project = JsonSerializer.Deserialize(contents.AsSpan(), + new JsonSerializerOptions() { Converters = { new FlaxVersionConverter() }, IncludeFields = true, TypeInfoResolver = ProjectInfoSourceGenerationContext.Default }); project.ProjectPath = path; project.ProjectFolderPath = Path.GetDirectoryName(path);