summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changelog.md1
-rw-r--r--script/vm/operator.lua9
-rw-r--r--test/type_inference/common.lua236
3 files changed, 246 insertions, 0 deletions
diff --git a/changelog.md b/changelog.md
index edf91439..56f3286b 100644
--- a/changelog.md
+++ b/changelog.md
@@ -2,6 +2,7 @@
## Unreleased
<!-- Add all new changes here. They will be moved under a version at release -->
+* `NEW` Add support for binary metamethod on right operand [#2777](https://github.com/LuaLS/lua-language-server/pull/2777)
## 3.10.1
`2024-8-2`
diff --git a/script/vm/operator.lua b/script/vm/operator.lua
index 7ce2b30d..07ce19eb 100644
--- a/script/vm/operator.lua
+++ b/script/vm/operator.lua
@@ -261,6 +261,9 @@ vm.binarySwitch = util.switch()
})
else
local node = vm.runOperator(binaryMap[op], source[1], source[2])
+ if not node then
+ node = vm.runOperator(binaryMap[op], source[2], source[1])
+ end
if node then
vm.setNode(source, node)
end
@@ -300,6 +303,9 @@ vm.binarySwitch = util.switch()
})
else
local node = vm.runOperator(binaryMap[op], source[1], source[2])
+ if not node then
+ node = vm.runOperator(binaryMap[op], source[2], source[1])
+ end
if node then
vm.setNode(source, node)
return
@@ -396,6 +402,9 @@ vm.binarySwitch = util.switch()
return
end
local node = vm.runOperator(binaryMap[source.op.type], source[1], source[2])
+ if not node then
+ node = vm.runOperator(binaryMap[source.op.type], source[2], source[1])
+ end
if node then
vm.setNode(source, node)
end
diff --git a/test/type_inference/common.lua b/test/type_inference/common.lua
index 5922832b..5fcec805 100644
--- a/test/type_inference/common.lua
+++ b/test/type_inference/common.lua
@@ -4192,3 +4192,239 @@ TEST 'boolean|number' [[
---@type A
local <?x?>
]]
+
+--reverse binary operator tests
+
+TEST 'A' [[
+---@class A
+---@operator add(number): A
+
+---@type A
+local x
+local <?y?> = x + 1
+]]
+
+TEST 'A' [[
+---@class A
+---@operator add(number): A
+
+---@type A
+local x
+local <?y?> = 1 + x
+]]
+
+TEST 'A' [[
+---@class A
+---@operator sub(number): A
+
+---@type A
+local x
+local <?y?> = x - 1
+]]
+
+TEST 'A' [[
+---@class A
+---@operator sub(number): A
+
+---@type A
+local x
+local <?y?> = 1 - x
+]]
+
+TEST 'A' [[
+---@class A
+---@operator mul(number): A
+
+---@type A
+local x
+local <?y?> = x * 1
+]]
+
+TEST 'A' [[
+---@class A
+---@operator mul(number): A
+
+---@type A
+local x
+local <?y?> = 1 * x
+]]
+
+TEST 'A' [[
+---@class A
+---@operator div(number): A
+
+---@type A
+local x
+local <?y?> = x / 1
+]]
+
+TEST 'A' [[
+---@class A
+---@operator div(number): A
+
+---@type A
+local x
+local <?y?> = 1 / x
+]]
+
+TEST 'A' [[
+---@class A
+---@operator idiv(number): A
+
+---@type A
+local x
+local <?y?> = x // 1
+]]
+
+TEST 'A' [[
+---@class A
+---@operator idiv(number): A
+
+---@type A
+local x
+local <?y?> = 1 // x
+]]
+
+TEST 'A' [[
+---@class A
+---@operator mod(number): A
+
+---@type A
+local x
+local <?y?> = x % 1
+]]
+
+TEST 'A' [[
+---@class A
+---@operator mod(number): A
+
+---@type A
+local x
+local <?y?> = 1 % x
+]]
+
+TEST 'A' [[
+---@class A
+---@operator pow(number): A
+
+---@type A
+local x
+local <?y?> = x ^ 1
+]]
+
+TEST 'A' [[
+---@class A
+---@operator pow(number): A
+
+---@type A
+local x
+local <?y?> = 1 ^ x
+]]
+
+TEST 'A' [[
+---@class A
+---@operator concat(number): A
+
+---@type A
+local x
+local <?y?> = x .. 1
+]]
+
+TEST 'A' [[
+---@class A
+---@operator concat(number): A
+
+---@type A
+local x
+local <?y?> = 1 .. x
+]]
+
+TEST 'A' [[
+---@class A
+---@operator band(number): A
+
+---@type A
+local x
+local <?y?> = x & 1
+]]
+
+TEST 'A' [[
+---@class A
+---@operator band(number): A
+
+---@type A
+local x
+local <?y?> = 1 & x
+]]
+
+TEST 'A' [[
+---@class A
+---@operator bor(number): A
+
+---@type A
+local x
+local <?y?> = x | 1
+]]
+
+TEST 'A' [[
+---@class A
+---@operator bor(number): A
+
+---@type A
+local x
+local <?y?> = 1 | x
+]]
+
+TEST 'A' [[
+---@class A
+---@operator bxor(number): A
+
+---@type A
+local x
+local <?y?> = x ~ 1
+]]
+
+TEST 'A' [[
+---@class A
+---@operator bxor(number): A
+
+---@type A
+local x
+local <?y?> = 1 ~ x
+]]
+
+TEST 'A' [[
+---@class A
+---@operator shl(number): A
+
+---@type A
+local x
+local <?y?> = x << 1
+]]
+
+TEST 'A' [[
+---@class A
+---@operator shl(number): A
+
+---@type A
+local x
+local <?y?> = 1 << x
+]]
+
+TEST 'A' [[
+---@class A
+---@operator shr(number): A
+
+---@type A
+local x
+local <?y?> = x >> 1
+]]
+
+TEST 'A' [[
+---@class A
+---@operator shr(number): A
+
+---@type A
+local x
+local <?y?> = 1 >> x
+]]