Procházet zdrojové kódy

Make own properties for declared only method and properties configurable (#1948)

Marko Lahma před 11 měsíci
rodič
revize
780e01fef0

+ 21 - 20
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 @@ namespace Shapes
             {
                 _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 @@ namespace Shapes
 
         public override double Perimeter()
         {
-            return Math.PI*Math.Pow(Radius, 2);
+            return Math.PI * Math.Pow(Radius, 2);
         }
     }
 }

+ 16 - 0
Jint.Tests/Runtime/InteropTests.cs

@@ -3585,4 +3585,20 @@ try {
         
         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}");
+    }
 }

+ 7 - 0
Jint/Options.cs

@@ -371,6 +371,13 @@ public class Options
         /// All other values are ignored.
         /// </summary>
         public MemberTypes ObjectWrapperReportedMemberTypes { get; set; } = MemberTypes.Field | MemberTypes.Property | MemberTypes.Method;
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <remarks>This configuration does not affect methods, only methods declared in type itself will be reported.</remarks>
+        public bool ObjectWrapperReportOnlyDeclaredMembers { get; set; }
     }
 
     public class ConstraintOptions

+ 13 - 7
Jint/Runtime/Interop/ObjectWrapper.cs

@@ -253,12 +253,18 @@ public class ObjectWrapper : ObjectInstance, IObjectWrapper, IEquatable<ObjectWr
         }
         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 @@ public class ObjectWrapper : ObjectInstance, IObjectWrapper, IEquatable<ObjectWr
                 }
             }
 
-            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)
                     {