Skip to content

Commit

Permalink
Fix for types derived from un-namespaced types. (#261)
Browse files Browse the repository at this point in the history
  • Loading branch information
DmitriySft authored Apr 8, 2024
1 parent dbdbf87 commit 5d321c9
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 3 deletions.
11 changes: 8 additions & 3 deletions src/NodeApi.DotNetHost/TypeExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ private void RegisterDerivedType(TypeProxy derivedType, Type? baseOrInterfaceTyp
{
string baseOrInterfaceTypeName = TypeProxy.GetTypeProxyName(baseOrInterfaceType);

NamespaceProxy? ns = GetNamespaceProxy(baseOrInterfaceType.Namespace!);
NamespaceProxy? ns = GetNamespaceProxy(baseOrInterfaceType.Namespace);
if (ns == null)
{
Trace(
Expand Down Expand Up @@ -246,7 +246,7 @@ private void ExportExtensionMethod(MethodInfo extensionMethod)
// Target namespaces and types should be already loaded because either they are in the
// current assembly (where types are loaded before extension methods) or in an assembly
// this one depends on which would have been loaded already.
NamespaceProxy? targetTypeNamespace = GetNamespaceProxy(targetType.Namespace!);
NamespaceProxy? targetTypeNamespace = GetNamespaceProxy(targetType.Namespace);
if (targetTypeNamespace == null)
{
Trace(
Expand Down Expand Up @@ -308,8 +308,13 @@ private static bool IsExtensionTargetTypeSupported(Type targetType, string exten
return true;
}

internal NamespaceProxy? GetNamespaceProxy(string ns)
internal NamespaceProxy? GetNamespaceProxy(string? ns)
{
if (ns is null)
{
return null;
}

string[] namespaceParts = ns.Split('.');
if (!_exportedNamespaces.TryGetValue(
namespaceParts[0], out NamespaceProxy? namespaceProxy))
Expand Down
66 changes: 66 additions & 0 deletions test/TestCases/napi-dotnet/NoNamespaceTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Collections;
using System.Collections.Generic;

#pragma warning disable IDE0060 // Remove unused parameter
#pragma warning disable CA1050 // Declare types in namespaces
#pragma warning disable CA1822 // Mark members as static

public class NoNamespaceType
{
}

public interface INoNamespaceInterface
{
}

public class NoNamespaceCollection : ICollection<string>
{
public IEnumerator<string> GetEnumerator() => throw new System.NotImplementedException();

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public void Add(string item) => throw new System.NotImplementedException();

public void Clear() => throw new System.NotImplementedException();

public bool Contains(string item) => throw new System.NotImplementedException();

public void CopyTo(string[] array, int arrayIndex) => throw new System.NotImplementedException();

public bool Remove(string item) => throw new System.NotImplementedException();

public int Count { get; }
public bool IsReadOnly { get; }
}

public delegate void NoNamespaceDelegate();

namespace Microsoft.JavaScript.NodeApi.TestCases
{
public class NoNamespaceInterfaceImpl : INoNamespaceInterface
{
}

public class NoNamespaceTypeImpl : NoNamespaceType
{
}

public class NoNamespaceContainer
{
public static NoNamespaceDelegate DelegateProperty { get; set; }

Check warning on line 53 in test/TestCases/napi-dotnet/NoNamespaceTypes.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

Non-nullable property 'DelegateProperty' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 53 in test/TestCases/napi-dotnet/NoNamespaceTypes.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

Non-nullable property 'DelegateProperty' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

public List<NoNamespaceType>? GetList(INoNamespaceInterface arg)
{
return null;
}

public T GetList<T>()
where T : List<NoNamespaceType>, INoNamespaceInterface
{
return default!;
}
}
}
19 changes: 19 additions & 0 deletions test/TestCases/napi-dotnet/dynamic_no_namespace_type.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

const assert = require('assert');

const dotnet = require('../common').dotnet;

// Load the test module using dynamic binding `load()` instead of static binding `require()`.
const assemblyPath = process.env.NODE_API_TEST_MODULE_PATH;
dotnet.load(assemblyPath);

// The unnamespaced type should be skipped.
assert.strictEqual(dotnet.NoNamespaceType, undefined);

assert.notStrictEqual(dotnet.Microsoft.JavaScript.NodeApi.TestCases.NoNamespaceInterfaceImpl, undefined)

assert.notStrictEqual(dotnet.Microsoft.JavaScript.NodeApi.TestCases.NoNamespaceTypeImpl, undefined)

assert.notStrictEqual(dotnet.Microsoft.JavaScript.NodeApi.TestCases.NoNamespaceContainer, undefined)

0 comments on commit 5d321c9

Please sign in to comment.