Missing validation when casting an argument
pouwelsjochem opened this issue · comments
Environment
Name | Version |
---|---|
IDEA version | 2021 |
Luanalysis version | 1.3.0 |
OS | macOS 11.5 |
What are the steps to reproduce this issue?
---@shape shapeA
---@field fieldA string
local variableA = "A"
local function receiveAny(_any)
end
receiveAny(--[[---@type number]] "")
receiveAny(--[[---@type number]] {})
receiveAny(--[[---@type number]] variableA)
receiveAny(--[[---@type shapeA]] variableA)
What happens?
None of the arguments in the receiveAny
executions are validated, everything is accepted.
What were you expecting to happen?
All of the receiveAny
executions should fail.
receiveAny
will accept an argument of any
type, in which case it doesn't matter what type you pass it, any type is valid. No errors are expected.
However, you can verify that type checking is working as expected in the presence of type casts by restricting the accepted parameter type e.g.
---@shape shapeA
---@field fieldA string
local variableA = "A"
---@param value number
local function receiveNumber(value)
end
receiveNumber(--[[---@type number]] "")
receiveNumber(--[[---@type number]] {})
receiveNumber(--[[---@type number]] variableA)
receiveNumber(--[[---@type shapeA]] variableA)
You'll see that the first 3 are valid, and the last is not. This is expected because the type is cast to a number
, which is what the function wants.
Granted, casting a string literal (that doesn't represent a number) or object literal to a number
probably isn't a great idea, but that's the purpose of casting i.e. essentially it's the dev saying to the IDE, "I know better than you, and I take full responsibility."
@pouwelsjochem Feel free to jump into Discord https://discord.gg/xrqynr2 then the #luanalysis-ide
channel if you've any questions. Technically the Discord server is for Tabletop Simulator Lua development, but I run the server, so it's fine 😆
Thanks for the quick reply and server invitation! Definitely good to be in there :)
I see now that casting is meant to forcefully cast, understandable and useful!
The origin of my issue came from wanting to see validation on a @shape
I pass as an argument to a function of an external library without having to create a local variable.
Essentialy wanting to do this:
externalLibrary.sendData(--[[---@type shapeA]] {fieldA = "A"})
Instead of:
local shapeA = {fieldA = "A"} ---@type shapeA
externalLibrary.sendData({fieldA = "A"})
But I can solve my issue by writing wrapper functions which expect the right type as signature instead. (i.e. sendShapeA)
Assuming the external library doesn't already have types, you can provide your own types for the library. Here's an example for Tabletop Simulator:
https://github.com/Benjamin-Dobell/tts-types/tree/master/tts
Those .def.lua
files provide Lua definitions for functions/tables/userdata which are (mostly) implemented in C#. However, the same process ought to work for regular Lua libraries. Basically anywhere in your IntelliJ project you can provide a <module name>.def.lua
file that provides types. The only thing special about the .def.lua
extension is that irrelevant inspections are disabled.
Thanks! I was aware of the .def.lua
files indeed, used them to map out the parts of the Solar2D engine I use ^^
However I'm not a fan of adding game-specific shapes to that definition file, hence I'm more in favour of writing a wrapper :)