summaryrefslogtreecommitdiff
path: root/script-beta/parser
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2020-08-16 18:33:17 +0800
committer最萌小汐 <sumneko@hotmail.com>2020-08-16 18:33:17 +0800
commita02d1537bbf7829c8117ce481a9bbcff7efa8dd7 (patch)
treeac7928fe0e44c4fd2476833320bbce86d0f45297 /script-beta/parser
parent8d2199b3ec3d7b7a72c6e230f9d40c18f8c7477d (diff)
downloadlua-language-server-a02d1537bbf7829c8117ce481a9bbcff7efa8dd7.zip
更新类型推测
Diffstat (limited to 'script-beta/parser')
-rw-r--r--script-beta/parser/guide.lua87
1 files changed, 78 insertions, 9 deletions
diff --git a/script-beta/parser/guide.lua b/script-beta/parser/guide.lua
index 3462dbae..37ab8088 100644
--- a/script-beta/parser/guide.lua
+++ b/script-beta/parser/guide.lua
@@ -2470,6 +2470,9 @@ function m.inferCheckLibraryReturn(status, source)
end
function m.inferByDef(status, obj)
+ if status.index > 1 then
+ return
+ end
local newStatus = m.status(status)
m.searchRefs(newStatus, obj, 'def')
for _, src in ipairs(newStatus.results) do
@@ -2481,6 +2484,33 @@ function m.inferByDef(status, obj)
end
end
+local function inferBySetOfLocal(status, source)
+ if source.ref then
+ local newStatus = m.status(status)
+ for _, ref in ipairs(source.ref) do
+ if ref.type == 'setlocal' then
+ break
+ end
+ m.searchInfer(newStatus, ref)
+ end
+ for _, infer in ipairs(newStatus.results) do
+ status.results[#status.results+1] = infer
+ end
+ end
+end
+
+function m.inferBySet(status, source)
+ if #status.results ~= 0 then
+ return
+ end
+ if source.type == 'local' then
+ inferBySetOfLocal(status, source)
+ elseif source.type == 'setlocal'
+ or source.type == 'getlocal' then
+ inferBySetOfLocal(status, source.node)
+ end
+end
+
function m.inferByCall(status, source)
if #status.results ~= 0 then
return
@@ -2552,6 +2582,48 @@ function m.inferByUnary(status, source)
end
end
+function m.inferByBinary(status, source)
+ if #status.results ~= 0 then
+ return
+ end
+ local parent = source.parent
+ if not parent or parent.type ~= 'binary' then
+ return
+ end
+ local op = parent.op
+ if op.type == '<='
+ or op.type == '>='
+ or op.type == '<'
+ or op.type == '>'
+ or op.type == '^'
+ or op.type == '/'
+ or op.type == '+'
+ or op.type == '-'
+ or op.type == '*'
+ or op.type == '%' then
+ status.results[#status.results+1] = {
+ type = 'number',
+ source = source,
+ }
+ elseif op.type == '|'
+ or op.type == '~'
+ or op.type == '&'
+ or op.type == '<<'
+ or op.type == '>>'
+ -- 整数的可能性比较高
+ or op.type == '//' then
+ status.results[#status.results+1] = {
+ type = 'integer',
+ source = source,
+ }
+ elseif op.type == '..' then
+ status.results[#status.results+1] = {
+ type = 'string',
+ source = source,
+ }
+ end
+end
+
local function mergeFunctionReturns(status, source, index)
local returns = source.returns
if not returns then
@@ -2590,12 +2662,13 @@ end
function m.cleanInfers(infers)
local mark = {}
for i = 1, #infers do
- local source = infers[i].source
- if mark[source] then
+ local infer = infers[i]
+ local key = ('%s|%p'):format(infer.type, infer.source)
+ if mark[key] then
infers[i] = infers[#infers]
infers[#infers] = nil
else
- mark[source] = true
+ mark[key] = true
end
end
end
@@ -2632,17 +2705,13 @@ function m.searchInfer(status, obj)
return
end
- if status.index > 1 then
- return
- end
-
--m.inferByLibraryArg(status, obj)
m.inferByDef(status, obj)
- --m.inferBySet(status, obj)
+ m.inferBySet(status, obj)
m.inferByCall(status, obj)
m.inferByGetTable(status, obj)
m.inferByUnary(status, obj)
- --m.inferByBinary(status, obj)
+ m.inferByBinary(status, obj)
m.inferByCallReturn(status, obj)
--m.inferByPCallReturn(status, obj)
m.cleanInfers(status.results)