Skip to content

Commit fbb028f

Browse files
committed
fix optional
1 parent 103d77b commit fbb028f

File tree

8 files changed

+64
-67
lines changed

8 files changed

+64
-67
lines changed

script/core/hover/return.lua

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,9 @@ local function asFunction(source)
6565
local rtn = vm.getReturnOfFunction(source, i)
6666
local doc = docs[i]
6767
local name = doc and doc.name and doc.name[1] and (doc.name[1] .. ': ')
68-
local text = ('%s%s%s'):format(
68+
local text = ('%s%s'):format(
6969
name or '',
70-
infer.getInfer(rtn):view(),
71-
doc and doc.optional and '?' or ''
70+
infer.getInfer(rtn):view()
7271
)
7372
if i == 1 then
7473
returns[i] = (' -> %s'):format(text)
@@ -86,10 +85,7 @@ local function asDocFunction(source)
8685
end
8786
local returns = {}
8887
for i, rtn in ipairs(source.returns) do
89-
local rtnText = ('%s%s'):format(
90-
infer.getInfer(rtn):view(),
91-
rtn.optional and '?' or ''
92-
)
88+
local rtnText = infer.getInfer(rtn):view()
9389
if i == 1 then
9490
returns[#returns+1] = (' -> %s'):format(rtnText)
9591
else

script/vm/compiler.lua

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,9 @@ local function getReturn(func, index, args)
455455
result:merge(rnode)
456456
end
457457
end
458+
if result and returnNode:isOptional() then
459+
result:addOptional()
460+
end
458461
end
459462
end
460463
end
@@ -1115,6 +1118,9 @@ local compilerSwitch = util.switch()
11151118
for _, typeUnit in ipairs(source.types) do
11161119
vm.setNode(source, vm.compileNode(typeUnit))
11171120
end
1121+
if source.optional then
1122+
vm.getNode(source):addOptional()
1123+
end
11181124
end)
11191125
: case 'doc.type.integer'
11201126
: case 'doc.type.string'
@@ -1220,6 +1226,9 @@ local compilerSwitch = util.switch()
12201226
else
12211227
vm.setNode(source, globalMgr.getGlobal('type', 'any'))
12221228
end
1229+
if source.optional then
1230+
vm.getNode(source):addOptional()
1231+
end
12231232
end)
12241233
: case 'generic'
12251234
: call(function (source)

script/vm/infer.lua

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -144,37 +144,45 @@ local viewNodeSwitch = util.switch()
144144
local argView = ''
145145
local regView = ''
146146
for i, arg in ipairs(source.args) do
147+
local argNode = vm.compileNode(arg)
148+
local isOptional = argNode:isOptional()
149+
if isOptional then
150+
argNode = argNode:copy()
151+
argNode:removeOptional()
152+
end
147153
args[i] = string.format('%s%s: %s'
148154
, arg.name[1]
149-
, arg.optional and '?' or ''
150-
, m.getInfer(arg):view()
155+
, isOptional and '?' or ''
156+
, m.getInfer(argNode):view()
151157
)
152158
end
153159
if #args > 0 then
154160
argView = table.concat(args, ', ')
155161
end
156162
for i, ret in ipairs(source.returns) do
157-
rets[i] = string.format('%s%s'
158-
, m.getInfer(ret):view()
159-
, ret.optional and '?' or ''
160-
)
163+
rets[i] = m.getInfer(ret):view()
161164
end
162165
if #rets > 0 then
163166
regView = ':' .. table.concat(rets, ', ')
164167
end
165168
return ('fun(%s)%s'):format(argView, regView)
166169
end)
167170

168-
---@param source parser.object
171+
---@param source parser.object | vm.node
169172
---@return vm.infer
170173
function m.getInfer(source)
171-
local node = vm.compileNode(source)
174+
local node
175+
if source.type == 'vm.node' then
176+
node = source
177+
else
178+
node = vm.compileNode(source)
179+
end
172180
if node.lastInfer then
173181
return node.lastInfer
174182
end
175183
local infer = setmetatable({
176184
node = node,
177-
uri = guide.getUri(source),
185+
uri = source.type ~= 'vm.node' and guide.getUri(source),
178186
}, mt)
179187
node.lastInfer = infer
180188

@@ -298,22 +306,26 @@ function mt:view(default, uri)
298306
local max = #array
299307
local limit = config.get(uri or self.uri, 'Lua.hover.enumsLimit')
300308

309+
local view
301310
if max > limit then
302-
local view = string.format('%s...(+%d)'
311+
view = string.format('%s...(+%d)'
303312
, table.concat(array, '|', 1, limit)
304313
, max - limit
305314
)
306-
307-
self.cachedView = view
308-
309-
return view
310315
else
311-
local view = table.concat(array, '|')
312-
313-
self.cachedView = view
316+
view = table.concat(array, '|')
317+
end
314318

315-
return view
319+
if self.node:isOptional() then
320+
if max > 1 then
321+
view = '(' .. view .. ')?'
322+
else
323+
view = view .. '?'
324+
end
316325
end
326+
self.cachedView = view
327+
328+
return view
317329
end
318330

319331
function mt:eachView()

script/vm/node.lua

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -146,43 +146,30 @@ function mt:getData(k)
146146
end
147147

148148
function mt:addOptional()
149-
if self:isOptional() then
150-
return self
151-
end
152149
self.optional = true
153150
end
154151

155152
function mt:removeOptional()
156-
if not self:isOptional() then
157-
return self
158-
end
159-
self:_expand()
160-
for i = #self, 1, -1 do
161-
local n = self[i]
162-
if n.type == 'nil'
163-
or (n.type == 'boolean' and n[1] == false)
164-
or (n.type == 'doc.type.boolean' and n[1] == false) then
165-
self[i] = self[#self]
166-
self[#self] = nil
167-
end
168-
end
153+
self.optional = false
169154
end
170155

171156
---@return boolean
172157
function mt:isOptional()
173-
if self.optional ~= nil then
174-
return self.optional
158+
return self.optional == true
159+
end
160+
161+
---@return boolean
162+
function mt:isFalsy()
163+
if self.optional then
164+
return true
175165
end
176-
self:_expand()
177166
for _, c in ipairs(self) do
178167
if c.type == 'nil'
179168
or (c.type == 'boolean' and c[1] == false)
180169
or (c.type == 'doc.type.boolean' and c[1] == false) then
181-
self.optional = true
182170
return true
183171
end
184172
end
185-
self.optional = false
186173
return false
187174
end
188175

@@ -196,6 +183,11 @@ function mt:eachObject()
196183
end
197184
end
198185

186+
---@return vm.node
187+
function mt:copy()
188+
return vm.createNode(self)
189+
end
190+
199191
---@param source parser.object | vm.generic
200192
---@param node vm.node | vm.object
201193
---@param cover? boolean

script/vm/sign.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ function mt:resolve(uri, args)
114114
local function buildArgNode(argNode, knownTypes)
115115
local newArgNode = vm.createNode()
116116
for n in argNode:eachObject() do
117-
if argNode:isOptional() and vm.isFalsy(n) then
117+
if argNode:isFalsy() then
118118
goto CONTINUE
119119
end
120120
local view = infer.viewObject(n)

script/vm/value.lua

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -41,28 +41,9 @@ function vm.test(source)
4141
end
4242
end
4343

44-
---@param source parser.object
45-
---@return boolean
46-
function vm.isFalsy(source)
47-
if source.type == 'nil' then
48-
return true
49-
end
50-
if source.type == 'boolean'
51-
or source.type == 'doc.type.boolean' then
52-
return source[1] == false
53-
end
54-
return false
55-
end
56-
5744
---@param v vm.object
5845
---@return string?
5946
local function getUnique(v)
60-
if v.type == 'local' then
61-
return ('loc:%s@%d'):format(guide.getUri(v), v.start)
62-
end
63-
if v.type == 'global' then
64-
return ('%s:%s'):format(v.cate, v.name)
65-
end
6647
if v.type == 'boolean' then
6748
if v[1] == nil then
6849
return false

test/hover/init.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ local <?t?> = {
772772
]]
773773
[[
774774
local t: {
775-
f: file*,
775+
f: file*?,
776776
}
777777
]]
778778

test/type_inference/init.lua

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,3 +1482,10 @@ function mt:f()
14821482
print(<?self?>)
14831483
end
14841484
]]
1485+
1486+
TEST 'string?' [[
1487+
---@return string?
1488+
local function f() end
1489+
1490+
local <?x?> = f()
1491+
]]

0 commit comments

Comments
 (0)