Skip to content

Proposal: Lualib override plugins #973

@Perryvw

Description

@Perryvw

In the last 2 weeks we received two requests for the ability to modify lualib output with plugins. One for supplying an environment-specific implementation of __TS__New, and another for a specialized ArrayForEach implementation for an environment's special tables.

Other use cases for overriding lualib functions might be using computation/memory/garbage optimized versions of lualib functions.

I think this is a 'quick win' as it seems relatively simple to implement this as follows:

Add a record to the plugin interface that allows supplying a string for a lualib feature:

export interface Plugin {
    /**
     * An augmentation to the map of visitors that transform TypeScript AST to Lua AST.
     *
     * Key is a `SyntaxKind` of a processed node.
     */
    visitors?: Visitors;

    /**
     * A function that converts Lua AST to a string.
     *
     * At most one custom printer can be provided across all plugins.
     */
    printer?: Printer;
+
+    /**
+     * Provide a custom string that will be emitted as implementation for a lualib feature.
+     */
+    lualib?: Partial<Record<LuaLibFeature, string>>
}

Then a plugin could look like this:

const plugin = {
    lualib: {
        [LuaLibFeature.Delete]: `
            function __TS__Delete(target, key)
                target[key] = nil
            end
        `
    }
}

Or even:

const plugin = {
    lualib: {
        ...garbageCollectorOptimizedLualibCollectionFromNpmPackage,
        ...lualibFunctionsForEnvironment
    }
}

We then pass these plugins to the printer and override the lualib methods it wants to emit.

What I'm not sure about yet is if these should be supplied as Lua string or something else (TS/Lua AST/TS AST). Also leaving in the function header like I did in the example could potentially lead to typos and other issues, although we should easily be able to put in a diagnostic for that.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions