-
-
Notifications
You must be signed in to change notification settings - Fork 8.4k
[dotnet] Fully annotate Command
for AOT support
#15527
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
base: trunk
Are you sure you want to change the base?
Conversation
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Explore these optional code suggestions:
|
dotnet/src/webdriver/Command.cs
Outdated
@@ -31,24 +32,33 @@ namespace OpenQA.Selenium | |||
/// </summary> | |||
public class Command |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Best viewed with whitespace off
private readonly static JsonSerializerOptions s_jsonSerializerOptions = new() | ||
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = $"All trimming-unsafe access points to {nameof(s_jsonSerializerOptions)} are annotated as such")] | ||
[UnconditionalSuppressMessage("AOT", "IL3050", Justification = $"All AOT-unsafe access points to {nameof(s_jsonSerializerOptions)} are annotated as such")] | ||
private static class JsonOptionsHolder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason to introduce dummy class? Just to hold some object used only in here? I think standard field
is good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fields cannot be AOT-annotated, only types and methods. Having a “holder” type is common when you want to annotate specific fields as AOT-unsafe but not everything in the type.
@@ -40,7 +40,7 @@ public class WebDriver : IWebDriver, ISearchContext, IJavaScriptExecutor, IFinds | |||
/// </summary> | |||
protected static readonly TimeSpan DefaultCommandTimeout = TimeSpan.FromSeconds(60); | |||
private IFileDetector fileDetector = new DefaultFileDetector(); | |||
private NetworkManager network; | |||
private NetworkManager? network; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unintentional change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s intentional and correct (it is lazy-initialized) but not necessarily relevant to this PR. Just one more internal warning gone.
get | ||
{ | ||
if (this.Parameters != null && this.Parameters.Count > 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.Parameters?.Count > 0
pretty simple to not introduce new method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.Parameters
is an AOT-unsafe member. We must handle the logic inside Command
for the AOT annotations.
} | ||
catch (NotSupportedException ex) | ||
{ | ||
throw new WebDriverException("Attempted to serialize an unsupported type. Ensure you are using Selenium types, or well-known .NET types such as Dictionary<string, object> and object[]", ex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought we support any type, falling back to reflection based if not in the json context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not if we are AOT-compiled. the reflection fallback will not work. That is the only case this NotSupportedException
is thrown.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then we are not AOT-compatible. Users will don't see warnings at compile time, but will face issues at runtime. And what we?.. just suppress it. It is bad :(
I don't see good solution as a quick win, right solution would be avoid any object
type and be strongly typed?
{ | ||
// Extract the URL parameter, and remove it from the parameters dictionary | ||
// so it doesn't get transmitted as a JSON parameter. | ||
if (commandToExecute.Parameters.TryGetValue(propertyName, out var propertyValueObject)) | ||
if (commandToExecute.TryGetValueAndRemoveIfNotNull(propertyName, out var propertyValueObject)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, interesting situation. Transmitter checks each time whether some "infected" parameter should be removed. What are these cases? I hope we can just fix it on consumer side. Based on comments, somebody tries to send url
, thus we should fix this somebody
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The case is for parameters in the URL. This extracts those values from the dictionary and uses them in the URL instead of the parameter body.
This is show stopper: #15527 (comment) |
User description
AOT warnings are user-facing, even if those warnings are within Selenium's own code. For that reason, we should ensure we are not emitting any warnings unless such code paths are annotated as AOT-unsafe.
Motivation and Context
Contributes to #14480
Types of changes
Checklist
PR Type
Enhancement
Description
Added AOT-friendly annotations to the
Command
class.Refactored
JsonSerializerOptions
into a static nested class for safety.Introduced helper methods for parameter handling in
Command
.Updated
HttpCommandInfo
to use new parameter handling methods.Changes walkthrough 📝
Command.cs
Refactor `Command` class for AOT compatibility
dotnet/src/webdriver/Command.cs
JsonSerializerOptions
into a static nested class.HasParameters
andTryGetValueAndRemoveIfNotNull
helpermethods.
HttpCommandInfo.cs
Update parameter handling in `HttpCommandInfo`
dotnet/src/webdriver/HttpCommandInfo.cs
HasParameters
andTryGetValueAndRemoveIfNotNull
.