Skip to content

How to implement automatic derivation of function parameter types #2479

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
fesily opened this issue Jan 15, 2024 · 4 comments
Open

How to implement automatic derivation of function parameter types #2479

fesily opened this issue Jan 15, 2024 · 4 comments

Comments

@fesily
Copy link
Contributor

fesily commented Jan 15, 2024

local function t(a)
  a? --unkown
end
t({A=1})

This feature is not available in the current language server.
I would like to add it as a feature and have no clue where to start changing it.
The primary target is a function that is called only once

@fesily
Copy link
Contributor Author

fesily commented Jan 15, 2024

script/vm/compiler.lua compileLocal

    if source.parent.type == 'funcargs' and not hasMarkDoc and not hasMarkParam then
        local func = source.parent.parent
        -- local call ---@type fun(f: fun(x: number));call(function (x) end) --> x -> number
        local funcNode = vm.compileNode(func)
        local hasDocArg
        for n in funcNode:eachObject() do
            if n.type == 'doc.type.function' then
                for index, arg in ipairs(n.args) do
                    if func.args[index] == source then
                        local argNode = vm.compileNode(arg)
                        for an in argNode:eachObject() do
                            if an.type ~= 'doc.generic.name' then
                                vm.setNode(source, an)
                            end
                        end
                        hasDocArg = true
                    end
                end
            end
        end
        if not hasDocArg then
            local refs = vm.getRefs(source.parent.parent)
            local findCall
            if refs then
                for i, ref in ipairs(refs) do
                    if ref.parent.type == 'call' then
                        findCall = ref.parent
                        break
                    end
                end
            end
            if findCall then
                local index
                for i, arg in ipairs(source.parent) do
                    if arg == source then
                        index = i
                        break
                    end
                end
                if index then
                    hasDocArg = true
                    local callerArg = findCall.args[index]
                    vm.setNode(source, vm.compileNode(callerArg))
                end
            end
        end
        if not hasDocArg then
            vm.setNode(source, vm.declareGlobal('type', 'any'))
        end
    end

It's worked

@sumneko
Copy link
Collaborator

sumneko commented Jan 16, 2024

vm.getRefs may very slow

@fesily
Copy link
Contributor Author

fesily commented Jan 16, 2024

It is indeed slow, so one should limit the search in which way.
I think first just find the first valid function call.

@fesily
Copy link
Contributor Author

fesily commented Jan 16, 2024

Limiting types to local variables,maybe better

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants