IntelliJ-Luanalysis icon indicating copy to clipboard operation
IntelliJ-Luanalysis copied to clipboard

Smart cast expressions

Open pouwelsjochem opened this issue 3 years ago • 1 comments

Environment

name version
IDEA version IC2020.3
Luanalysis version 1.2.2
OS MacOS Big Sur

What are the steps to reproduce this issue?

This is not really an issue, more like a stretch goal / idea. Making an issue so the idea is documented.

As of now, the usage of nil-able types are not really encouraged because everything has to be casted to --[[---@not nil]]. It would be nice if expressions would be able to detect certain conditions and automatically do the cast / type removal on params and variables. Such as Kotlin's smart casts.

Such as regular if statements looking for non nil objects:

---@param _paramTable nil|{a:number, b:fun()}
local function testSmartNil(_paramTable)
    local a = _paramTable and _paramTable.a -- currently gives an error and disabled autoComplete on _paramTable
    if _paramTable then
         _paramTable.b()-- currently gives an error and disabled autoComplete on _paramTable
    else
         -- here it could show only the type 'nil'
    end
end

Usage of the type() function. And maybe even let the user define their own cast functions as well?

---@param _numberOrStringParam string|number
local function testSmartType(_numberOrStringParam)
    if type(_numberOrStringParam) == "string" then
        string.upper(_numberOrStringParam) -- currently gives an error string.upper doesn't accept number | string
    else
        math.random(_numberOrStringParam) -- currently gives an error math.random doesn't accept number | string
    end
end

Or maybe the ability to use annotations on conditions, probably not doable with variables though since we'd need the reference to its name

---@param _param string|MyObject
local function testSmartCast(_param)
     if isMyObject(_param) then ---@cast _numberOrStringParam MyObject
         wantsMyObject(_param)
     end

     local variable = getMyObjectOrItsSubclass()
     if isSubclassOfMyObject(variable) then ---@cast variable MySubclass
         wantsSubclass(variable)
     end
end

pouwelsjochem avatar Mar 10 '21 15:03 pouwelsjochem

There's an issue for nil #4.

However, seems as you've mentioned types as well, it's worth keeping this open. You can probably remove the stuff about nil specifically and just reference #4 though.

Benjamin-Dobell avatar Mar 10 '21 15:03 Benjamin-Dobell