Browse Source

Support creating NamespaceReference against empty namespace (#1888)

Marko Lahma 1 year ago
parent
commit
5d91655e1e

+ 5 - 0
Jint.Tests/Runtime/Domain/Shape.cs

@@ -1,5 +1,10 @@
 using Jint.Tests.Runtime.Domain;
 
+public class ShapeWithoutNameSpace : Shapes.Shape
+{
+    public override double Perimeter() => 42;
+}
+
 namespace Shapes
 {
     public abstract class Shape

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

@@ -1301,6 +1301,22 @@ namespace Jint.Tests.Runtime
             ");
         }
 
+        [Fact]
+        public void ShouldImportEmptyNamespace()
+        {
+            RunTest("""
+                var nullSpace = importNamespace(null);
+                var c1 = new nullSpace.ShapeWithoutNameSpace();
+                assert(c1.Perimeter() === 42);
+                var undefinedSpace = importNamespace(undefined);
+                var c2 = new undefinedSpace.ShapeWithoutNameSpace();
+                assert(c2.Perimeter() === 42);
+                var defaultSpace = importNamespace();
+                var c3 = new defaultSpace.ShapeWithoutNameSpace();
+                assert(c3.Perimeter() === 42);
+            """);
+        }
+
         [Fact]
         public void ShouldConstructReferenceTypeWithParameters()
         {

+ 1 - 2
Jint/Options.cs

@@ -126,8 +126,7 @@ public class Options
             engine.Realm.GlobalObject.SetProperty("importNamespace", new PropertyDescriptor(new ClrFunction(
                     engine,
                     "importNamespace",
-                    (thisObj, arguments) =>
-                        new NamespaceReference(engine, TypeConverter.ToString(arguments.At(0)))),
+                    (_, arguments) => new NamespaceReference(engine, arguments.At(0).IsNullOrUndefined() ? null : TypeConverter.ToString(arguments.At(0)))),
                 PropertyFlag.AllForbidden));
 
             engine.Realm.GlobalObject.SetProperty("clrHelper", new PropertyDescriptor(ObjectWrapper.Create(engine, new ClrHelper(Interop)), PropertyFlag.AllForbidden));

+ 10 - 5
Jint/Runtime/Interop/NamespaceReference.cs

@@ -18,9 +18,9 @@ namespace Jint.Runtime.Interop
     [RequiresUnreferencedCode("Dynamic loading")]
     public class NamespaceReference : ObjectInstance, ICallable
     {
-        private readonly string _path;
+        private readonly string? _path;
 
-        public NamespaceReference(Engine engine, string path) : base(engine)
+        public NamespaceReference(Engine engine, string? path) : base(engine)
         {
             _path = path;
         }
@@ -75,7 +75,9 @@ namespace Jint.Runtime.Interop
 
         public override JsValue Get(JsValue property, JsValue receiver)
         {
-            var newPath = _path + "." + property;
+            var newPath = string.IsNullOrEmpty(_path)
+                ? property.ToString()
+                : $"{_path}.{property}";
 
             return GetPath(newPath);
         }
@@ -123,8 +125,11 @@ namespace Jint.Runtime.Interop
                 }
 
                 var lastPeriodPos = path.LastIndexOf('.');
-                var trimPath = path.Substring(0, lastPeriodPos);
-                type = GetType(assembly, trimPath);
+                if (lastPeriodPos != -1)
+                {
+                    var trimPath = path.Substring(0, lastPeriodPos);
+                    type = GetType(assembly, trimPath);
+                }
                 if (type != null)
                 {
                     foreach (Type nType in GetAllNestedTypes(type))