Skip to content

Incorrect Generated Code for Disposables #1584

@raincheque

Description

@raincheque

The following snippet in Typescript

class Scoped {
	action(): void {
		// some work
	}
	[Symbol.dispose]() {
		// cleanup code
	}
}

/** @noSelf */
function TestScoped(): void {
	using s = new Scoped();
	s.action();
}

Generates the following Lua code for TestScoped:

local function TestScoped()
    return __TS__Using(
        nil,
        function(s) -- accepting a single argument, which is the disposable
            s:action()
        end,
        __TS__New(Scoped)
    )
end

__TS_Using is defined as below in lualib_bundle.lua:

local function __TS__Using(self, cb, ...)
    local args = {...}
    local thrownError
    local ok, result = xpcall(
        function() return cb(
            nil,  -- the generated function expects the disposable as the first arg 
            __TS__Unpack(args) -- but the disposable lives here, in args[1]
        ) end,
        function(err)
            thrownError = err
            return thrownError
        end
    )
    local argArray = {__TS__Unpack(args)}
    do
        local i = #argArray - 1
        while i >= 0 do
            local ____self_0 = argArray[i + 1]
            ____self_0[Symbol.dispose](____self_0)
            i = i - 1
        end
    end
    if not ok then
        error(thrownError, 0)
    end
    return result
end

The problem is annotated above in comments. The disposable itself which the callback expects is not passed to the callback.

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