microsoft / node-api-dotnet

Advanced interoperability between .NET and JavaScript in the same process.
MIT License
426 stars 49 forks source link

Feature request: Mark whole assembly with JSExport #269

Closed alexeybut closed 2 months ago

alexeybut commented 2 months ago

If you have a project with hundreds classes you need to mark all the classes with JSExport to export them to JS module. I hope you'll find the next feature useful:

  1. Ability to mark whole assembly with JSExport to export all public classes.
  2. Add a parameter like this JSExport(exportReferencedClasses = true) to export recursively all classes that the marked class uses.
jasongin commented 2 months ago

Ability to mark whole assembly with JSExport to export all public classes.

This is a reasonable request and should be easy to implement. The syntax would be:

[assembly: JSExport]

And it would export all public types in the assembly (but no types referenced in other assemblies).

Add a parameter like this JSExport(exportReferencedClasses = true) to export recursively all classes that the marked class uses.

That's more complicated, but maybe possible. An important consideration is whether it should follow references to types in other assemblies. That could be problematic if the other assemblies weren't designed for JS export, if they use some forms of generics which require runtime code-generation (not allowed with AOT), or if there are conflicts from types with the same name in different namespaces. To avoid such problems, maybe it should only follow references to types in other assemblies which are also explicitly exported to JS via type-level or assembly-level JSExport.

alexeybut commented 2 months ago

I suppose the JSExport assembly attribute is enough. But in this case something like JSIgnore or JSExport(ignore: true) can be useful also.

alexeybut commented 2 months ago

@jasongin JSIgnore or JSExport(ignore: true) looks very ussful from my point of view. For example, It allows ignoring some non-supported (or .NET specific) methods or properties while generating nodejs without using #ifdef-s in original C# code.

jasongin commented 2 months ago

JSIgnore or JSExport(ignore: true)

I'm thinking [JSExport(false)].

alexeybut commented 2 months ago

@jasongin Thanks for quick fix. But I have found several issues:

  1. Wrong comment for JSExportAttribute. You didn't add JSExcludeAttribute. Misprint publci. /// When applied to an assembly, all public types in the assembly are exported, unless excluded /// by another . When applied to a publci type, all public members
  2. Some issues in IsExported(ISymbol symbol) method. Please test the code:

    [assembly: JSExport]
    namespace Aspose.Words
    {
    // Raises an exception.
    internal class Class1
    {
    }
    
    public class Class2
    {
        // Is exported.
        [JSExport(false)]
        public void ExportFalse()
        {
        }
        [JSExport(true)]
        public void ExportTrue()
        {
        }
    }
    }