Skip to content

Commit 644f3d1

Browse files
RenderMichaelgryznar
authored andcommitted
[dotnet] Move devtools generator to System.Text.Json, update to .NET 8 (SeleniumHQ#15061)
1 parent 1a74cd7 commit 644f3d1

16 files changed

+122
-126
lines changed

third_party/dotnet/devtools/src/generator/BUILD.bazel

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ load("//dotnet:defs.bzl", "csharp_binary", "framework")
33
csharp_binary(
44
name = "generator",
55
srcs = glob(["**/*.cs"]),
6+
nullable = "annotations",
67
# Used as a tool in our build, so just target one framework
7-
target_frameworks = ["net7.0"],
8+
target_frameworks = ["net8.0"],
89
visibility = [
910
"//dotnet:__subpackages__",
1011
],
@@ -14,6 +15,5 @@ csharp_binary(
1415
framework("nuget", "Humanizer.Core"),
1516
framework("nuget", "Microsoft.Extensions.DependencyInjection"),
1617
framework("nuget", "Microsoft.Extensions.DependencyInjection.Abstractions"),
17-
framework("nuget", "Newtonsoft.Json"),
1818
],
1919
)

third_party/dotnet/devtools/src/generator/CodeGen/CodeGenerationDefinitionTemplateSettings.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace OpenQA.Selenium.DevToolsGenerator.CodeGen
22
{
3-
using Newtonsoft.Json;
3+
using System.Text.Json.Serialization;
44

55
/// <summary>
66
/// Represents settings around Definition templates.
@@ -47,22 +47,22 @@ public CodeGenerationDefinitionTemplateSettings()
4747
};
4848
}
4949

50-
[JsonProperty("domainTemplate")]
50+
[JsonPropertyName("domainTemplate")]
5151
public CodeGenerationTemplateSettings DomainTemplate { get; set; }
5252

53-
[JsonProperty("commandTemplate")]
53+
[JsonPropertyName("commandTemplate")]
5454
public CodeGenerationTemplateSettings CommandTemplate { get; set; }
5555

56-
[JsonProperty("eventTemplate")]
56+
[JsonPropertyName("eventTemplate")]
5757
public CodeGenerationTemplateSettings EventTemplate { get; set; }
5858

59-
[JsonProperty("typeObjectTemplate")]
59+
[JsonPropertyName("typeObjectTemplate")]
6060
public CodeGenerationTemplateSettings TypeObjectTemplate { get; set; }
6161

62-
[JsonProperty("typeHashTemplate")]
62+
[JsonPropertyName("typeHashTemplate")]
6363
public CodeGenerationTemplateSettings TypeHashTemplate { get; set; }
6464

65-
[JsonProperty("typeEnumTemplate")]
65+
[JsonPropertyName("typeEnumTemplate")]
6666
public CodeGenerationTemplateSettings TypeEnumTemplate { get; set; }
6767
}
6868
}

third_party/dotnet/devtools/src/generator/CodeGen/CodeGenerationSettings.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace OpenQA.Selenium.DevToolsGenerator.CodeGen
22
{
3-
using Newtonsoft.Json;
3+
using System.Text.Json.Serialization;
44
using System.Collections.Generic;
55

66
/// <summary>
@@ -26,43 +26,43 @@ public CodeGenerationSettings()
2626
/// <summary>
2727
/// Collection of templates that will be parsed and output in the target folder.
2828
/// </summary>
29-
[JsonProperty("include")]
29+
[JsonPropertyName("include")]
3030
public ICollection<CodeGenerationTemplateSettings> Include { get; set; }
3131

3232
/// <summary>
3333
/// Indicates whether or not domains marked as depreciated will be generated. (Default: true)
3434
/// </summary>
35-
[JsonProperty("includeDeprecatedDomains")]
35+
[JsonPropertyName("includeDeprecatedDomains")]
3636
public bool IncludeDeprecatedDomains { get; set; }
3737

3838
/// <summary>
3939
/// Indicates whether or not domains marked as depreciated will be generated. (Default: true)
4040
/// </summary>
41-
[JsonProperty("includeExperimentalDomains")]
41+
[JsonPropertyName("includeExperimentalDomains")]
4242
public bool IncludeExperimentalDomains { get; set; }
4343

4444
/// <summary>
4545
/// Gets or sets the root namespace of generated classes.
4646
/// </summary>
47-
[JsonProperty("rootNamespace")]
47+
[JsonPropertyName("rootNamespace")]
4848
public string RootNamespace { get; set; }
4949

5050
/// <summary>
5151
/// Gets the version number of the runtime.
5252
/// </summary>
53-
[JsonProperty("runtimeVersion")]
53+
[JsonPropertyName("runtimeVersion")]
5454
public string RuntimeVersion { get; set; }
5555

56-
[JsonProperty("definitionTemplates")]
56+
[JsonPropertyName("definitionTemplates")]
5757
public CodeGenerationDefinitionTemplateSettings DefinitionTemplates { get; set; }
5858

59-
[JsonProperty("templatesPath")]
59+
[JsonPropertyName("templatesPath")]
6060
public string TemplatesPath { get; set; }
6161

6262
/// <summary>
6363
/// The using statements that will be included on each generated file.
6464
/// </summary>
65-
[JsonProperty("usingStatements")]
65+
[JsonPropertyName("usingStatements")]
6666
public ICollection<string> UsingStatements { get; set; }
6767
}
6868
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
namespace OpenQA.Selenium.DevToolsGenerator.CodeGen
22
{
3-
using Newtonsoft.Json;
3+
using System.Text.Json.Serialization;
44

55
/// <summary>
66
/// Defines settings around templates
77
/// </summary>
88
public class CodeGenerationTemplateSettings
99
{
10-
[JsonProperty("templatePath")]
10+
[JsonPropertyName("templatePath")]
1111
public string TemplatePath { get; set; }
1212

13-
[JsonProperty("outputPath")]
13+
[JsonPropertyName("outputPath")]
1414
public string OutputPath { get; set; }
1515
}
1616
}
Lines changed: 39 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,59 @@
11
namespace OpenQA.Selenium.DevToolsGenerator.Converters
22
{
3-
using Newtonsoft.Json;
43
using System;
4+
using System.Text.Json;
5+
using System.Text.Json.Serialization;
56

67
/// <summary>
78
/// Handles converting JSON string values into a C# boolean data type.
89
/// </summary>
9-
public class BooleanJsonConverter : JsonConverter
10+
public class BooleanJsonConverter : JsonConverter<bool>
1011
{
11-
/// <summary>
12-
/// Determines whether this instance can convert the specified object type.
13-
/// </summary>
14-
/// <param name="objectType">Type of the object.</param>
15-
/// <returns>
16-
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
17-
/// </returns>
18-
public override bool CanConvert(Type objectType)
19-
{
20-
// Handle only boolean types.
21-
return objectType == typeof(bool);
22-
}
12+
public override bool HandleNull => false;
2313

24-
/// <summary>
25-
/// Reads the JSON representation of the object.
26-
/// </summary>
27-
/// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param>
28-
/// <param name="objectType">Type of the object.</param>
29-
/// <param name="existingValue">The existing value of object being read.</param>
30-
/// <param name="serializer">The calling serializer.</param>
31-
/// <returns>
32-
/// The object value.
33-
/// </returns>
34-
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
14+
public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
3515
{
36-
switch (reader.Value.ToString().ToLower().Trim())
16+
switch (reader.TokenType)
3717
{
38-
case "true":
39-
case "yes":
40-
case "y":
41-
case "1":
18+
case JsonTokenType.True:
4219
return true;
43-
case "false":
44-
case "no":
45-
case "n":
46-
case "0":
20+
21+
case JsonTokenType.False:
4722
return false;
48-
}
4923

50-
// If we reach here, we're pretty much going to throw an error so let's let Json.NET throw it's pretty-fied error message.
51-
return new JsonSerializer().Deserialize(reader, objectType);
52-
}
24+
case JsonTokenType.String:
25+
string boolString = reader.GetString()!;
26+
if (bool.TryParse(boolString, out bool b))
27+
{
28+
return b;
29+
}
30+
31+
boolString = boolString.ToLowerInvariant();
5332

54-
/// <summary>
55-
/// Specifies that this converter will not participate in writing results.
56-
/// </summary>
57-
public override bool CanWrite => false;
33+
if (boolString.AsSpan().Trim().SequenceEqual("yes".AsSpan()) ||
34+
boolString.AsSpan().Trim().SequenceEqual("y".AsSpan()) ||
35+
boolString.AsSpan().Trim().SequenceEqual("1".AsSpan()))
36+
{
37+
return true;
38+
}
39+
40+
if (boolString.AsSpan().Trim().SequenceEqual("no".AsSpan()) ||
41+
boolString.AsSpan().Trim().SequenceEqual("n".AsSpan()) ||
42+
boolString.AsSpan().Trim().SequenceEqual("0".AsSpan()))
43+
{
44+
return false;
45+
}
46+
47+
throw new JsonException();
48+
49+
default:
50+
throw new JsonException();
51+
}
52+
}
5853

59-
/// <summary>
60-
/// Writes the JSON representation of the object.
61-
/// </summary>
62-
/// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param><param name="value">The value.</param><param name="serializer">The calling serializer.</param>
63-
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
54+
public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOptions options)
6455
{
65-
throw new NotSupportedException();
56+
writer.WriteBooleanValue(value);
6657
}
6758
}
6859
}

third_party/dotnet/devtools/src/generator/DevToolsGenerator.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net60</TargetFramework>
5+
<TargetFramework>net8.0</TargetFramework>
66
<RootNamespace>OpenQA.Selenium.DevToolsGenerator</RootNamespace>
7+
<Nullable>annotations</Nullable>
78
</PropertyGroup>
89

910
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -19,7 +20,6 @@
1920
<PackageReference Include="Handlebars.Net" Version="1.11.5" />
2021
<PackageReference Include="Humanizer.Core" Version="2.14.1" />
2122
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.32" />
22-
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
2323
</ItemGroup>
2424

2525
</Project>

third_party/dotnet/devtools/src/generator/Program.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
using System.Text;
44
using CommandLine;
55
using Microsoft.Extensions.DependencyInjection;
6-
using Newtonsoft.Json;
7-
using Newtonsoft.Json.Linq;
6+
using System.Text.Json.Serialization;
87
using OpenQA.Selenium.DevToolsGenerator.CodeGen;
98
using OpenQA.Selenium.DevToolsGenerator.ProtocolDefinition;
9+
using System.Text.Json;
10+
using System.Text.Json.Nodes;
1011

1112
namespace OpenQA.Selenium.DevToolsGenerator
1213
{
@@ -24,7 +25,7 @@ static int Main(string[] args)
2425
}
2526

2627
var settingsJson = File.ReadAllText(cliArguments.Settings);
27-
var settings = JsonConvert.DeserializeObject<CodeGenerationSettings>(settingsJson);
28+
var settings = JsonSerializer.Deserialize<CodeGenerationSettings>(settingsJson);
2829
if (!string.IsNullOrEmpty(cliArguments.TemplatesPath))
2930
{
3031
settings.TemplatesPath = cliArguments.TemplatesPath;
@@ -48,7 +49,7 @@ static int Main(string[] args)
4849

4950
var protocolDefinitionData = GetProtocolDefinitionData(cliArguments);
5051

51-
var protocolDefinition = protocolDefinitionData.ToObject<ProtocolDefinition.ProtocolDefinition>(new JsonSerializer() { MetadataPropertyHandling = MetadataPropertyHandling.Ignore });
52+
var protocolDefinition = protocolDefinitionData.Deserialize<ProtocolDefinition.ProtocolDefinition>(new JsonSerializerOptions() { ReferenceHandler = ReferenceHandler.IgnoreCycles });
5253

5354
//Begin the code generation process.
5455
if (!cliArguments.Quiet)
@@ -113,9 +114,9 @@ static int Main(string[] args)
113114
/// </summary>
114115
/// <param name="args"></param>
115116
/// <returns></returns>
116-
public static JObject GetProtocolDefinitionData(CommandLineOptions args)
117+
public static JsonObject GetProtocolDefinitionData(CommandLineOptions args)
117118
{
118-
JObject protocolData;
119+
JsonObject protocolData;
119120
string browserProtocolPath = args.BrowserProtocolPath;
120121
if (!File.Exists(browserProtocolPath))
121122
{
@@ -134,15 +135,15 @@ public static JObject GetProtocolDefinitionData(CommandLineOptions args)
134135
}
135136
}
136137

137-
JObject browserProtocol = JObject.Parse(File.ReadAllText(browserProtocolPath));
138-
JObject jsProtocol = JObject.Parse(File.ReadAllText(jsProtocolPath));
138+
JsonObject browserProtocol = JsonNode.Parse(File.ReadAllText(browserProtocolPath)).AsObject();
139+
JsonObject jsProtocol = JsonNode.Parse(File.ReadAllText(jsProtocolPath)).AsObject();
139140

140141
ProtocolVersionDefinition currentVersion = new ProtocolVersionDefinition();
141142
currentVersion.ProtocolVersion = "1.3";
142143
currentVersion.Browser = "Chrome/86.0";
143144

144145
protocolData = MergeJavaScriptProtocolDefinitions(browserProtocol, jsProtocol);
145-
protocolData["browserVersion"] = JToken.FromObject(currentVersion);
146+
protocolData["browserVersion"] = JsonSerializer.SerializeToNode(currentVersion);
146147

147148
return protocolData;
148149
}
@@ -153,7 +154,7 @@ public static JObject GetProtocolDefinitionData(CommandLineOptions args)
153154
/// <param name="browserProtocol"></param>
154155
/// <param name="jsProtocol"></param>
155156
/// <returns></returns>
156-
public static JObject MergeJavaScriptProtocolDefinitions(JObject browserProtocol, JObject jsProtocol)
157+
public static JsonObject MergeJavaScriptProtocolDefinitions(JsonObject? browserProtocol, JsonObject? jsProtocol)
157158
{
158159
//Merge the 2 protocols together.
159160
if (jsProtocol["version"]["majorVersion"] != browserProtocol["version"]["majorVersion"] ||
@@ -162,11 +163,11 @@ public static JObject MergeJavaScriptProtocolDefinitions(JObject browserProtocol
162163
throw new InvalidOperationException("Protocol mismatch -- The WebKit and V8 protocol versions should match.");
163164
}
164165

165-
var result = browserProtocol.DeepClone() as JObject;
166-
foreach (var domain in jsProtocol["domains"])
166+
var result = browserProtocol.DeepClone().AsObject();
167+
foreach (var domain in jsProtocol["domains"].AsArray())
167168
{
168-
JArray jDomains = (JArray)result["domains"];
169-
jDomains.Add(domain);
169+
JsonArray jDomains = result["domains"].AsArray();
170+
jDomains.Add(domain.DeepClone());
170171
}
171172

172173
return result;

third_party/dotnet/devtools/src/generator/ProtocolDefinition/CommandDefinition.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace OpenQA.Selenium.DevToolsGenerator.ProtocolDefinition
22
{
3-
using Newtonsoft.Json;
3+
using System.Text.Json.Serialization;
44
using System.Collections.Generic;
55
using System.Collections.ObjectModel;
66

@@ -14,16 +14,16 @@ public CommandDefinition()
1414
Returns = new Collection<TypeDefinition>();
1515
}
1616

17-
[JsonProperty(PropertyName = "handlers")]
17+
[JsonPropertyName("handlers")]
1818
public ICollection<string> Handlers { get; set; }
1919

20-
[JsonProperty(PropertyName = "parameters")]
20+
[JsonPropertyName("parameters")]
2121
public ICollection<TypeDefinition> Parameters { get; set; }
2222

23-
[JsonProperty(PropertyName = "returns")]
23+
[JsonPropertyName("returns")]
2424
public ICollection<TypeDefinition> Returns { get; set; }
2525

26-
[JsonProperty(PropertyName = "redirect")]
26+
[JsonPropertyName("redirect")]
2727
public string Redirect { get; set; }
2828

2929
[JsonIgnore]

0 commit comments

Comments
 (0)