Skip to content

Commit

Permalink
Address PR feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
vmoroz committed Aug 2, 2024
1 parent 2171041 commit 5c4e176
Show file tree
Hide file tree
Showing 16 changed files with 171 additions and 164 deletions.
27 changes: 16 additions & 11 deletions src/NodeApi/IJSValue.cs
Original file line number Diff line number Diff line change
@@ -1,40 +1,45 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#if !NET7_0_OR_GREATER
using System;

#if !NET7_0_OR_GREATER
using System.Reflection;
#endif

namespace Microsoft.JavaScript.NodeApi;

#if NET7_0_OR_GREATER
// A static interface that helps with the conversion of JSValue to a specific type.
public interface IJSValue<TSelf> where TSelf : struct, IJSValue<TSelf>
public interface IJSValue<TSelf> : IEquatable<JSValue> where TSelf : struct, IJSValue<TSelf>
{
public static abstract bool CanBeConvertedFrom(JSValue value);
public JSValue AsJSValue();

#if NET7_0_OR_GREATER
public static abstract bool CanCreateFrom(JSValue value);

public static abstract TSelf CreateUnchecked(JSValue value);
#endif
}
#else

#if !NET7_0_OR_GREATER
// A static class that helps with the conversion of JSValue to a specific type.
public static class IJSValueShim<T> where T : struct
internal static class IJSValueShim<T> where T : struct
{
private static readonly Func<JSValue, bool> s_canBeConvertedFrom =
private static readonly Func<JSValue, bool> s_canBeCreatedFrom =
(Func<JSValue, bool>)Delegate.CreateDelegate(
typeof(Func<JSValue, bool>),
typeof(T).GetMethod(
nameof(JSObject.CanBeConvertedFrom),
"CanCreateFrom",
BindingFlags.Static | BindingFlags.Public)!);

private static readonly Func<JSValue, T>s_createUnchecked =
(Func<JSValue, T>)Delegate.CreateDelegate(
typeof(Func<JSValue, T>),
typeof(T).GetMethod(
nameof(JSObject.CreateUnchecked),
BindingFlags.Static | BindingFlags.Public)!);
"CreateUnchecked",
BindingFlags.Static | BindingFlags.NonPublic)!);

public static bool CanBeConvertedFrom(JSValue value) => s_canBeConvertedFrom(value);
public static bool CanCreateFrom(JSValue value) => s_canBeCreatedFrom(value);

public static T CreateUnchecked(JSValue value) => s_createUnchecked(value);
}
Expand Down
23 changes: 11 additions & 12 deletions src/NodeApi/Interop/JSAbortSignal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,13 @@ namespace Microsoft.JavaScript.NodeApi.Interop;
/// https://nodejs.org/api/globals.html#class-abortsignal
/// https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
/// </remarks>
public readonly struct JSAbortSignal : IEquatable<JSValue>
#if NET7_0_OR_GREATER
, IJSValue<JSAbortSignal>
#endif
public readonly struct JSAbortSignal : IJSValue<JSAbortSignal>
{
private readonly JSValue _value;

public static implicit operator JSValue(JSAbortSignal value) => value.AsJSValue();
public static explicit operator JSAbortSignal?(JSValue value) => value.As<JSAbortSignal>();
public static explicit operator JSAbortSignal(JSValue value)
=> value.As<JSAbortSignal>()
?? throw new InvalidCastException("JSValue is not an AbortSignal.");
public static explicit operator JSAbortSignal(JSValue value) => value.CastTo<JSAbortSignal>();

public static explicit operator JSAbortSignal(JSObject obj) => (JSAbortSignal)(JSValue)obj;
public static implicit operator JSObject(JSAbortSignal promise) => (JSObject)promise._value;
Expand All @@ -46,15 +41,19 @@ public static explicit operator JSAbortSignal(CancellationToken? cancellation)

#region IJSValue<JSAbortSignal> implementation

// TODO: (vmoroz) Implement
public static bool CanBeConvertedFrom(JSValue value) => value.IsObject();

public static JSAbortSignal CreateUnchecked(JSValue value) => new(value);
public static bool CanCreateFrom(JSValue value) => value.IsObject();

#endregion
#if NET7_0_OR_GREATER
// TODO: (vmoroz) Implement
static JSAbortSignal IJSValue<JSAbortSignal>.CreateUnchecked(JSValue value) => new(value);
#else
private static JSAbortSignal CreateUnchecked(JSValue value) => new(value);
#endif

public JSValue AsJSValue() => _value;

#endregion

private CancellationToken ToCancellationToken()
{
if (!_value.IsObject())
Expand Down
21 changes: 10 additions & 11 deletions src/NodeApi/JSArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,16 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using static Microsoft.JavaScript.NodeApi.Runtime.JSRuntime;

namespace Microsoft.JavaScript.NodeApi;

public readonly partial struct JSArray : IList<JSValue>, IEquatable<JSValue>
#if NET7_0_OR_GREATER
, IJSValue<JSArray>
#endif
public readonly partial struct JSArray : IJSValue<JSArray>, IList<JSValue>
{
private readonly JSValue _value;

public static implicit operator JSValue(JSArray arr) => arr.AsJSValue();
public static explicit operator JSArray?(JSValue value) => value.As<JSArray>();
public static explicit operator JSArray(JSValue value)
=> value.As<JSArray>() ?? throw new InvalidCastException("JSValue is not an Array");
public static explicit operator JSArray(JSValue value) => value.CastTo<JSArray>();

public static explicit operator JSArray(JSObject obj) => (JSArray)(JSValue)obj;
public static implicit operator JSObject(JSArray arr) => (JSObject)arr._value;
Expand Down Expand Up @@ -53,14 +48,18 @@ public JSArray(JSValue[] array)

#region IJSValue<JSArray> implementation

public static bool CanBeConvertedFrom(JSValue value) => value.IsArray();
public static bool CanCreateFrom(JSValue value) => value.IsArray();

public static JSArray CreateUnchecked(JSValue value) => new(value);

#endregion
#if NET7_0_OR_GREATER
static JSArray IJSValue<JSArray>.CreateUnchecked(JSValue value) => new(value);
#else
private static JSArray CreateUnchecked(JSValue value) => new(value);
#endif

public JSValue AsJSValue() => _value;

#endregion

/// <inheritdoc/>
public int Length => _value.GetArrayLength();

Expand Down
21 changes: 11 additions & 10 deletions src/NodeApi/JSAsyncIterable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,15 @@

namespace Microsoft.JavaScript.NodeApi;

public readonly partial struct JSAsyncIterable : IAsyncEnumerable<JSValue>, IEquatable<JSValue>
#if NET7_0_OR_GREATER
, IJSValue<JSAsyncIterable>
#endif
public readonly partial struct JSAsyncIterable :
IJSValue<JSAsyncIterable>, IAsyncEnumerable<JSValue>
{
private readonly JSValue _value;

public static implicit operator JSValue(JSAsyncIterable value) => value.AsJSValue();
public static explicit operator JSAsyncIterable?(JSValue value) => value.As<JSAsyncIterable>();
public static explicit operator JSAsyncIterable(JSValue value)
=> value.As<JSAsyncIterable>()
?? throw new InvalidCastException("JSValue is not an AsyncIterable.");
=> value.CastTo<JSAsyncIterable>();

public static explicit operator JSAsyncIterable(JSObject obj) => (JSAsyncIterable)(JSValue)obj;
public static implicit operator JSObject(JSAsyncIterable iterable) => (JSObject)iterable._value;
Expand All @@ -32,14 +29,18 @@ private JSAsyncIterable(JSValue value)
#region IJSValue<JSAsyncIterable> implementation

//TODO: (vmoroz) implement proper check using Symbol.asyncIterator
public static bool CanBeConvertedFrom(JSValue value) => value.IsObject();
public static bool CanCreateFrom(JSValue value) => value.IsObject();

public static JSAsyncIterable CreateUnchecked(JSValue value) => new(value);

#endregion
#if NET7_0_OR_GREATER
static JSAsyncIterable IJSValue<JSAsyncIterable>.CreateUnchecked(JSValue value) => new(value);
#else
private static JSAsyncIterable CreateUnchecked(JSValue value) => new(value);
#endif

public JSValue AsJSValue() => _value;

#endregion

#pragma warning disable IDE0060 // Unused parameter
public Enumerator GetAsyncEnumerator(CancellationToken cancellationToken = default)
=> new(_value);
Expand Down
20 changes: 10 additions & 10 deletions src/NodeApi/JSBigInt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,13 @@

namespace Microsoft.JavaScript.NodeApi;

public readonly struct JSBigInt : IEquatable<JSValue>
#if NET7_0_OR_GREATER
, IJSValue<JSBigInt>
#endif
public readonly struct JSBigInt : IJSValue<JSBigInt>
{
private readonly JSValue _value;

public static implicit operator JSValue(JSBigInt value) => value.AsJSValue();
public static explicit operator JSBigInt?(JSValue value) => value.As<JSBigInt>();
public static explicit operator JSBigInt(JSValue value)
=> value.As<JSBigInt>() ?? throw new InvalidCastException("JSValue is not a BigInt");
public static explicit operator JSBigInt(JSValue value) => value.CastTo<JSBigInt>();

public static implicit operator JSBigInt(BigInteger value) => new(value);
public static explicit operator BigInteger(JSBigInt value) => value.ToBigInteger();
Expand Down Expand Up @@ -46,14 +42,18 @@ public JSBigInt(BigInteger value) : this(JSValue.CreateBigInt(value))

#region IJSValue<JSBigInt> implementation

public static bool CanBeConvertedFrom(JSValue value) => value.IsBigInt();
public static bool CanCreateFrom(JSValue value) => value.IsBigInt();

public static JSBigInt CreateUnchecked(JSValue value) => new(value);

#endregion
#if NET7_0_OR_GREATER
static JSBigInt IJSValue<JSBigInt>.CreateUnchecked(JSValue value) => new(value);
#else
private static JSBigInt CreateUnchecked(JSValue value) => new(value);
#endif

public JSValue AsJSValue() => _value;

#endregion

public int GetWordCount() => _value.GetBigIntWordCount();

public void CopyTo(Span<ulong> destination, out int sign, out int wordCount)
Expand Down
20 changes: 10 additions & 10 deletions src/NodeApi/JSDate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,16 @@
using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.JavaScript.NodeApi.Interop;
using static Microsoft.JavaScript.NodeApi.Runtime.JSRuntime;

namespace Microsoft.JavaScript.NodeApi;

public readonly struct JSDate : IEquatable<JSValue>
#if NET7_0_OR_GREATER
, IJSValue<JSDate>
#endif
public readonly struct JSDate : IJSValue<JSDate>
{
private readonly JSValue _value;

public static implicit operator JSValue(JSDate value) => value.AsJSValue();
public static explicit operator JSDate?(JSValue value) => value.As<JSDate>();
public static explicit operator JSDate(JSValue value)
=> value.As<JSDate>() ?? throw new InvalidCastException("JSValue is not a Date");
public static explicit operator JSDate(JSValue value) => value.CastTo<JSDate>();

private JSDate(JSValue value)
{
Expand All @@ -44,13 +39,18 @@ public JSDate(string dateString)

#region IJSValue<JSDate> implementation

public static bool CanBeConvertedFrom(JSValue value) => value.IsDate();
public static bool CanCreateFrom(JSValue value) => value.IsDate();

public static JSDate CreateUnchecked(JSValue value) => new(value);
#if NET7_0_OR_GREATER
static JSDate IJSValue<JSDate>.CreateUnchecked(JSValue value) => new(value);
#else
private static JSDate CreateUnchecked(JSValue value) => new(value);
#endif

public JSValue AsJSValue() => _value;

#endregion

public JSValue AsJSValue() => _value;

public static JSDate FromDateTime(DateTime value)
{
Expand Down
20 changes: 10 additions & 10 deletions src/NodeApi/JSFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,13 @@ namespace Microsoft.JavaScript.NodeApi;
/// <summary>
/// Represents a JavaScript Function value.
/// </summary>
public readonly struct JSFunction : IEquatable<JSValue>
#if NET7_0_OR_GREATER
, IJSValue<JSFunction>
#endif
public readonly struct JSFunction : IJSValue<JSFunction>
{
private readonly JSValue _value;

public static implicit operator JSValue(JSFunction value) => value.AsJSValue();
public static explicit operator JSFunction?(JSValue value) => value.As<JSFunction>();
public static explicit operator JSFunction(JSValue value)
=> value.As<JSFunction>() ?? throw new InvalidCastException("JSValue is not a Function");
public static explicit operator JSFunction(JSValue value) => value.CastTo<JSFunction>();

private JSFunction(JSValue value)
{
Expand Down Expand Up @@ -274,14 +270,18 @@ public JSFunction(

#region IJSValue<JSFunction> implementation

public static bool CanBeConvertedFrom(JSValue value) => value.IsFunction();

public static JSFunction CreateUnchecked(JSValue value) => new(value);
public static bool CanCreateFrom(JSValue value) => value.IsFunction();

#endregion
#if NET7_0_OR_GREATER
static JSFunction IJSValue<JSFunction>.CreateUnchecked(JSValue value) => new(value);
#else
private static JSFunction CreateUnchecked(JSValue value) => new(value);
#endif

public JSValue AsJSValue() => _value;

#endregion

/// <summary>
/// Gets the name of the function, or an empty string if the function is unnamed.
/// </summary>
Expand Down
20 changes: 10 additions & 10 deletions src/NodeApi/JSIterable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,13 @@

namespace Microsoft.JavaScript.NodeApi;

public readonly partial struct JSIterable : IEnumerable<JSValue>, IEquatable<JSValue>
#if NET7_0_OR_GREATER
, IJSValue<JSIterable>
#endif
public readonly partial struct JSIterable : IJSValue<JSIterable>, IEnumerable<JSValue>
{
private readonly JSValue _value;

public static implicit operator JSValue(JSIterable value) => value.AsJSValue();
public static explicit operator JSIterable?(JSValue value) => value.As<JSIterable>();
public static explicit operator JSIterable(JSValue value)
=> value.As<JSIterable>() ?? throw new InvalidCastException("JSValue is not an Iterable.");
public static explicit operator JSIterable(JSValue value) => value.CastTo<JSIterable>();

public static explicit operator JSIterable(JSObject obj) => (JSIterable)(JSValue)obj;
public static implicit operator JSObject(JSIterable iterable) => (JSObject)iterable._value;
Expand All @@ -31,14 +27,18 @@ private JSIterable(JSValue value)
#region IJSValue<JSIterable> implementation

//TODO: (vmoroz) implement proper check using Symbol.iterator
public static bool CanBeConvertedFrom(JSValue value) => value.IsObject();

public static JSIterable CreateUnchecked(JSValue value) => new(value);
public static bool CanCreateFrom(JSValue value) => value.IsObject();

#endregion
#if NET7_0_OR_GREATER
static JSIterable IJSValue<JSIterable>.CreateUnchecked(JSValue value) => new(value);
#else
private static JSIterable CreateUnchecked(JSValue value) => new(value);
#endif

public JSValue AsJSValue() => _value;

#endregion

public Enumerator GetEnumerator() => new(_value);

IEnumerator<JSValue> IEnumerable<JSValue>.GetEnumerator() => GetEnumerator();
Expand Down
Loading

0 comments on commit 5c4e176

Please sign in to comment.