Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dotnet] Finalize nullability in internal devtools generator #15088

Merged
merged 7 commits into from
Jan 16, 2025
2 changes: 1 addition & 1 deletion third_party/dotnet/devtools/src/generator/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ load("//dotnet:defs.bzl", "csharp_binary", "framework")
csharp_binary(
name = "generator",
srcs = glob(["**/*.cs"]),
nullable = "annotations",
nullable = "enable",
# Used as a tool in our build, so just target one framework
target_frameworks = ["net8.0"],
visibility = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public sealed class CodeGenerationSettings
/// Gets the version number of the runtime.
/// </summary>
[JsonPropertyName("runtimeVersion")]
public string RuntimeVersion { get; set; }
public string? RuntimeVersion { get; set; }

[JsonPropertyName("definitionTemplates")]
public CodeGenerationDefinitionTemplateSettings DefinitionTemplates { get; set; } = new CodeGenerationDefinitionTemplateSettings();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ namespace OpenQA.Selenium.DevToolsGenerator.CodeGen
public class CodeGenerationTemplateSettings
{
[JsonPropertyName("templatePath")]
public string TemplatePath { get; set; }
[JsonRequired]
public string TemplatePath { get; set; } = null!;

[JsonPropertyName("outputPath")]
public string OutputPath { get; set; }
[JsonRequired]
public string OutputPath { get; set; } = null!;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace OpenQA.Selenium.DevToolsGenerator.CodeGen
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class CodeGeneratorBase<T> : ICodeGenerator<T>
where T : IDefinition
where T : class, IDefinition
{
private readonly Lazy<CodeGenerationSettings> m_settings;
private readonly Lazy<TemplatesManager> m_templatesManager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ namespace OpenQA.Selenium.DevToolsGenerator.CodeGen
/// <summary>
/// Represents the current context of the code generator.
/// </summary>
public sealed class CodeGeneratorContext
public sealed class CodeGeneratorContext(DomainDefinition domain, Dictionary<string, TypeInfo> knownTypes)
{
public DomainDefinition Domain { get; set; }
public DomainDefinition Domain { get; } = domain;

public Dictionary<string, TypeInfo> KnownTypes { get; set; }
public Dictionary<string, TypeInfo> KnownTypes { get; } = knownTypes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ namespace OpenQA.Selenium.DevToolsGenerator.CodeGen
/// <summary>
/// Represents information about a Chrome Debugger Protocol command.
/// </summary>
public sealed class CommandInfo
public sealed class CommandInfo(string commandName, string fullTypeName, string fullResponseTypeName)
{
public string CommandName { get; set; }
public string CommandName { get; } = commandName;

public string FullTypeName { get; set; }
public string FullTypeName { get; } = fullTypeName;

public string FullResponseTypeName { get; set; }
public string FullResponseTypeName { get; } = fullResponseTypeName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ namespace OpenQA.Selenium.DevToolsGenerator.CodeGen
/// <summary>
/// Represents information about a Chrome Debugger Protocol event.
/// </summary>
public sealed class EventInfo
public sealed class EventInfo(string eventName, string fullTypeName)
{
public string EventName { get; set; }
public string EventName { get; } = eventName;

public string FullTypeName { get; set; }
public string FullTypeName { get; } = fullTypeName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace OpenQA.Selenium.DevToolsGenerator.CodeGen
/// </summary>
/// <typeparam name="T"></typeparam>
public interface ICodeGenerator<T>
where T : IDefinition
where T : class, IDefinition
{
/// <summary>
/// Generates one or more code files for the specified IDefinition item
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using OpenQA.Selenium.DevToolsGenerator.ProtocolDefinition;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;

Expand All @@ -22,7 +23,7 @@ public override IDictionary<string, string> GenerateCode(ProtocolDefinition.Prot
{
if (string.IsNullOrWhiteSpace(Settings.TemplatesPath))
{
Settings.TemplatesPath = Path.GetDirectoryName(Settings.TemplatesPath);
Settings.TemplatesPath = Path.GetDirectoryName(Settings.TemplatesPath)!;
}

ICollection<DomainDefinition> domains = protocolDefinition.Domains;
Expand All @@ -44,11 +45,11 @@ public override IDictionary<string, string> GenerateCode(ProtocolDefinition.Prot
foreach (var command in domain.Commands)
{
commands.Add(new CommandInfo
{
CommandName = $"{domain.Name}.{command.Name}",
FullTypeName = $"{domain.Name.Dehumanize()}.{command.Name.Dehumanize()}CommandSettings",
FullResponseTypeName = $"{domain.Name.Dehumanize()}.{command.Name.Dehumanize()}CommandResponse"
});
(
commandName: $"{domain.Name}.{command.Name}",
fullTypeName: $"{domain.Name.Dehumanize()}.{command.Name.Dehumanize()}CommandSettings",
fullResponseTypeName: $"{domain.Name.Dehumanize()}.{command.Name.Dehumanize()}CommandResponse"
));
}
}

Expand All @@ -60,10 +61,10 @@ public override IDictionary<string, string> GenerateCode(ProtocolDefinition.Prot
foreach (var @event in domain.Events)
{
events.Add(new EventInfo
{
EventName = $"{domain.Name}.{@event.Name}",
FullTypeName = $"{domain.Name.Dehumanize()}.{@event.Name.Dehumanize()}EventArgs"
});
(
eventName: $"{domain.Name}.{@event.Name}",
fullTypeName: $"{domain.Name.Dehumanize()}.{@event.Name.Dehumanize()}EventArgs")
);
}
}

Expand Down Expand Up @@ -102,7 +103,7 @@ public override IDictionary<string, string> GenerateCode(ProtocolDefinition.Prot
return result;
}

private Dictionary<string, TypeInfo> GetTypesInDomain(ICollection<DomainDefinition> domains)
private static Dictionary<string, TypeInfo> GetTypesInDomain(ICollection<DomainDefinition> domains)
{
var knownTypes = new Dictionary<string, TypeInfo>(StringComparer.OrdinalIgnoreCase);

Expand All @@ -116,9 +117,9 @@ private Dictionary<string, TypeInfo> GetTypesInDomain(ICollection<DomainDefiniti
{
if (propertyType.Type == "string" && type.Enum != null && propertyType.Enum.Count > 0)
{
TypeDefinition propertyTypeDefinition = new TypeDefinition()
string id = $"{type.Id.Dehumanize()}{propertyType.Name.Dehumanize()}Values";
TypeDefinition propertyTypeDefinition = new TypeDefinition(id)
{
Id = type.Id.Dehumanize() + propertyType.Name.Dehumanize() + "Values",
Type = propertyType.Type,
Description = $"Enumerated values for {domain.Name}.{type.Id}.{propertyType.Name}"
};
Expand All @@ -136,35 +137,33 @@ private Dictionary<string, TypeInfo> GetTypesInDomain(ICollection<DomainDefiniti
switch (type.Type)
{
case "object":
typeInfo = new TypeInfo
{
IsPrimitive = false,
TypeName = type.Id.Dehumanize(),
};
typeInfo = new TypeInfo(typeName: type.Id.Dehumanize(), isPrimitive: false);
break;

case "string":
if (type.Enum != null && type.Enum.Count > 0)
{
typeInfo = new TypeInfo
typeInfo = new TypeInfo(typeName: type.Id.Dehumanize(), isPrimitive: false)
{
ByRef = true,
IsPrimitive = false,
TypeName = type.Id.Dehumanize(),
};
}
else
{
typeInfo = new TypeInfo
{
IsPrimitive = true,
TypeName = "string"
};
typeInfo = new TypeInfo("string", isPrimitive: true);
}

break;

case "array":
if ((type.Items == null || string.IsNullOrWhiteSpace(type.Items.Type)) &&
type.Items.TypeReference != "StringIndex" && type.Items.TypeReference != "FilterEntry")
if (type.Items is null)
{
throw new InvalidOperationException("Type definition's Type was array but Items is missing");
}

if (string.IsNullOrWhiteSpace(type.Items.Type) &&
type.Items.TypeReference != "StringIndex" &&
type.Items.TypeReference != "FilterEntry")
{
throw new NotImplementedException("Did not expect a top-level domain array type to specify a TypeReference");
}
Expand Down Expand Up @@ -199,28 +198,23 @@ private Dictionary<string, TypeInfo> GetTypesInDomain(ICollection<DomainDefiniti
default:
throw new NotImplementedException($"Did not expect a top-level domain array type to specify items of type {type.Items.Type}");
}
typeInfo = new TypeInfo
{
IsPrimitive = true,
TypeName = $"{itemType}[]"
};
typeInfo = new TypeInfo(typeName: $"{itemType}[]", isPrimitive: true);
break;

case "number":
typeInfo = new TypeInfo
typeInfo = new TypeInfo("double", isPrimitive: true)
{
ByRef = true,
IsPrimitive = true,
TypeName = "double"
};
break;

case "integer":
typeInfo = new TypeInfo
typeInfo = new TypeInfo("long", isPrimitive: true)
{
ByRef = true,
IsPrimitive = true,
TypeName = "long"
};
break;

default:
throw new InvalidOperationException($"Unknown Type Definition Type: {type.Id}");
}
Expand All @@ -232,11 +226,9 @@ private Dictionary<string, TypeInfo> GetTypesInDomain(ICollection<DomainDefiniti

foreach (var embeddedEnumType in embeddedTypes)
{
TypeInfo propertyTypeInfo = new TypeInfo
TypeInfo propertyTypeInfo = new TypeInfo(typeName: embeddedEnumType.Id, isPrimitive: false)
{
TypeName = embeddedEnumType.Id,
ByRef = true,
IsPrimitive = false,
Namespace = domain.Name.Dehumanize(),
SourcePath = $"{domain.Name}.{embeddedEnumType.Id}"
};
Expand All @@ -257,7 +249,7 @@ private Dictionary<string, string> GenerateCode(ICollection<DomainDefinition> do
//Generate types/events/commands for all domains.
foreach (var domain in domains)
{
var context = new CodeGeneratorContext { Domain = domain, KnownTypes = knownTypes };
var context = new CodeGeneratorContext(domain, knownTypes);
foreach (KeyValuePair<string, string> x in domainGenerator.GenerateCode(domain, context))
{
result.Add(x.Key, x.Value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ public TemplatesManager(CodeGenerationSettings settings)
public Func<object, string> GetGeneratorForTemplate(CodeGenerationTemplateSettings templateSettings)
{
var templatePath = templateSettings.TemplatePath;
if (m_templateGenerators.ContainsKey(templatePath))
if (m_templateGenerators.TryGetValue(templatePath, out Func<object, string>? value))
{
return m_templateGenerators[templatePath];
return value;
}

var targetTemplate = templatePath;
Expand All @@ -47,7 +47,7 @@ public Func<object, string> GetGeneratorForTemplate(CodeGenerationTemplateSettin

if (!File.Exists(targetTemplate))
{
throw new FileNotFoundException($"Unable to locate a template at {targetTemplate} - please ensure that a template file exists at this location.");
throw new FileNotFoundException($"Unable to locate a template at {targetTemplate} - please ensure that a template file exists at this location.", targetTemplate);
}

var templateContents = File.ReadAllText(targetTemplate);
Expand All @@ -59,7 +59,7 @@ public Func<object, string> GetGeneratorForTemplate(CodeGenerationTemplateSettin
throw new HandlebarsException("{{humanize}} helper must have exactly one argument");
}

var str = arguments[0].ToString();
var str = arguments[0].ToString()!;

//Some overrides for values that start with '-' -- this fixes two instances in Runtime.UnserializableValue
if (str.StartsWith("-"))
Expand Down
10 changes: 5 additions & 5 deletions third_party/dotnet/devtools/src/generator/CodeGen/TypeInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ namespace OpenQA.Selenium.DevToolsGenerator.CodeGen
/// <summary>
/// Represents information about a Chrome Debugger Protocol type.
/// </summary>
public sealed class TypeInfo
public sealed class TypeInfo(string typeName, bool isPrimitive)
{
public bool ByRef { get; set; }

public string Namespace { get; set; }
public string? Namespace { get; set; }

public bool IsPrimitive { get; set; }
public bool IsPrimitive { get; } = isPrimitive;

public string TypeName { get; set; }
public string TypeName { get; } = typeName;

public string SourcePath { get; set; }
public string? SourcePath { get; set; }
}
}
Loading
Loading