diff --git a/Jint.Tests/Runtime/Domain/Shape.cs b/Jint.Tests/Runtime/Domain/Shape.cs
index 2c053bbe8..08314bdd6 100644
--- a/Jint.Tests/Runtime/Domain/Shape.cs
+++ b/Jint.Tests/Runtime/Domain/Shape.cs
@@ -9,9 +9,9 @@ namespace Shapes
{
public abstract class Shape
{
+ public int Id = 123;
public abstract double Perimeter();
public Colors Color { get; set; }
-
}
public class Circle : Shape
@@ -22,33 +22,34 @@ public Meta()
{
_description = "descp";
}
- private string _description;
- public string Description
- {
- get
+ private string _description;
+
+ public string Description
{
- return _description;
+ get
+ {
+ return _description;
+ }
+ set
+ {
+ _description = value;
+ }
}
- set
+
+ public enum Usage
{
- _description = value;
+ Public,
+ Private,
+ Internal = 11
}
- }
-
- public enum Usage
- {
- Public,
- Private,
- Internal = 11
- }
}
public enum Kind
{
- Unit,
- Ellipse,
- Round = 5
+ Unit,
+ Ellipse,
+ Round = 5
}
public Circle()
@@ -64,7 +65,7 @@ public Circle(double radius)
public override double Perimeter()
{
- return Math.PI*Math.Pow(Radius, 2);
+ return Math.PI * Math.Pow(Radius, 2);
}
}
}
diff --git a/Jint.Tests/Runtime/InteropTests.cs b/Jint.Tests/Runtime/InteropTests.cs
index 7054c1d0f..43fcc01ab 100644
--- a/Jint.Tests/Runtime/InteropTests.cs
+++ b/Jint.Tests/Runtime/InteropTests.cs
@@ -3585,4 +3585,20 @@ public void ShouldNotThrowOnInspectingClrClassFunction()
decl.Should().BeNull();
}
+
+ [Fact]
+ public void StringifyShouldIncludeInheritedFieldsAndProperties()
+ {
+ var engine = new Engine();
+ engine.SetValue("c", new Circle(12.34));
+ engine.Evaluate("JSON.stringify(c)").ToString().Should().Be("{\"Radius\":12.34,\"Color\":0,\"Id\":123}");
+
+
+ engine = new Engine(options =>
+ {
+ options.Interop.ObjectWrapperReportOnlyDeclaredMembers = true;
+ });
+ engine.SetValue("c", new Circle(12.34));
+ engine.Evaluate("JSON.stringify(c)").ToString().Should().Be("{\"Radius\":12.34}");
+ }
}
diff --git a/Jint/Options.cs b/Jint/Options.cs
index 1cee53c6c..613bf3de9 100644
--- a/Jint/Options.cs
+++ b/Jint/Options.cs
@@ -371,6 +371,13 @@ public class InteropOptions
/// All other values are ignored.
///
public MemberTypes ObjectWrapperReportedMemberTypes { get; set; } = MemberTypes.Field | MemberTypes.Property | MemberTypes.Method;
+
+ ///
+ /// Whether object wrapper should only report members that are declared on the object type itself, not inherited members. Defaults to false.
+ /// This is different from JS logic where only object's own members are reported and not prototypes.
+ ///
+ /// This configuration does not affect methods, only methods declared in type itself will be reported.
+ public bool ObjectWrapperReportOnlyDeclaredMembers { get; set; }
}
public class ConstraintOptions
diff --git a/Jint/Runtime/Interop/ObjectWrapper.cs b/Jint/Runtime/Interop/ObjectWrapper.cs
index d19b58973..4328a39f0 100644
--- a/Jint/Runtime/Interop/ObjectWrapper.cs
+++ b/Jint/Runtime/Interop/ObjectWrapper.cs
@@ -253,12 +253,18 @@ private IEnumerable EnumerateOwnPropertyKeys(Types types)
}
else if (includeStrings)
{
+ var interopOptions = _engine.Options.Interop;
+
// we take public properties, fields and methods
- const BindingFlags BindingFlags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public;
+ var bindingFlags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public;
+ if (interopOptions.ObjectWrapperReportOnlyDeclaredMembers)
+ {
+ bindingFlags |= BindingFlags.DeclaredOnly;
+ }
- if ((_engine.Options.Interop.ObjectWrapperReportedMemberTypes & MemberTypes.Property) == MemberTypes.Property)
+ if ((interopOptions.ObjectWrapperReportedMemberTypes & MemberTypes.Property) == MemberTypes.Property)
{
- foreach (var p in ClrType.GetProperties(BindingFlags))
+ foreach (var p in ClrType.GetProperties(bindingFlags))
{
var indexParameters = p.GetIndexParameters();
if (indexParameters.Length == 0)
@@ -268,17 +274,17 @@ private IEnumerable EnumerateOwnPropertyKeys(Types types)
}
}
- if ((_engine.Options.Interop.ObjectWrapperReportedMemberTypes & MemberTypes.Field) == MemberTypes.Field)
+ if ((interopOptions.ObjectWrapperReportedMemberTypes & MemberTypes.Field) == MemberTypes.Field)
{
- foreach (var f in ClrType.GetFields(BindingFlags | BindingFlags.DeclaredOnly))
+ foreach (var f in ClrType.GetFields(bindingFlags))
{
yield return JsString.Create(f.Name);
}
}
- if ((_engine.Options.Interop.ObjectWrapperReportedMemberTypes & MemberTypes.Method) == MemberTypes.Method)
+ if ((interopOptions.ObjectWrapperReportedMemberTypes & MemberTypes.Method) == MemberTypes.Method)
{
- foreach (var m in ClrType.GetMethods(BindingFlags | BindingFlags.DeclaredOnly))
+ foreach (var m in ClrType.GetMethods(bindingFlags | BindingFlags.DeclaredOnly))
{
if (m.IsSpecialName)
{