Browse Source

Fix generic method return type handling under interop (#1743)

Marko Lahma 1 year ago
parent
commit
f4f257c360
2 changed files with 31 additions and 11 deletions
  1. 27 0
      Jint.Tests/Runtime/InteropTests.cs
  2. 4 11
      Jint/Runtime/Interop/MethodInfoFunction.cs

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

@@ -3421,5 +3421,32 @@ try {
             var result = engine.Evaluate("test.metadata['abc']");
             Assert.Equal("from-wrapper", result);
         }
+
+        [Fact]
+        public void ShouldSomethingFoo()
+        {
+            var engine = new Engine(opt =>
+            {
+                opt.AddExtensionMethods(typeof(Enumerable)); // Allow LINQ extension methods.
+            });
+
+            var result = new List<string>();
+            void Debug(object? o)
+            {
+                result.Add($"{o?.GetType().Name ?? "null"}: {o ?? "null"}");
+            }
+
+            engine.SetValue("debug", Debug);
+            engine.SetValue("dict", new Dictionary<string, string> { ["test"] = "val" });
+
+            engine.Execute("var t = dict.last(kvp => { debug(kvp); debug(kvp.key); return kvp.key != null; } );");
+            engine.Execute("debug(t); debug(t.key);");
+
+            Assert.Equal(4, result.Count);
+            Assert.Equal("KeyValuePair`2: [test, val]", result[0]);
+            Assert.Equal("String: test", result[1]);
+            Assert.Equal("KeyValuePair`2: [test, val]", result[2]);
+            Assert.Equal("String: test", result[3]);
+        }
     }
 }

+ 4 - 11
Jint/Runtime/Interop/MethodInfoFunction.cs

@@ -226,23 +226,16 @@ namespace Jint.Runtime.Interop
                     continue;
                 }
 
-                Type? returnType = null;
-                if (method.Method is MethodInfo methodInfo)
-                {
-                    returnType = methodInfo.ReturnType;
-                }
-
                 // todo: cache method info
                 try
                 {
-                    if (method.Method.IsGenericMethodDefinition && method.Method is MethodInfo)
+                    if (method.Method is MethodInfo { IsGenericMethodDefinition: true })
                     {
-                        var genericMethodInfo = resolvedMethod;
-                        var result = genericMethodInfo.Invoke(thisObj, parameters);
-                        return FromObjectWithType(Engine, result, returnType);
+                        var result = resolvedMethod.Invoke(thisObj, parameters);
+                        return FromObjectWithType(Engine, result, type: (resolvedMethod as MethodInfo)?.ReturnType);
                     }
 
-                    return FromObjectWithType(Engine, method.Method.Invoke(thisObj, parameters), returnType);
+                    return FromObjectWithType(Engine, method.Method.Invoke(thisObj, parameters), type: (method.Method as MethodInfo)?.ReturnType);
                 }
                 catch (TargetInvocationException exception)
                 {