diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2020-08-16 18:33:17 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2020-08-16 18:33:17 +0800 |
commit | a02d1537bbf7829c8117ce481a9bbcff7efa8dd7 (patch) | |
tree | ac7928fe0e44c4fd2476833320bbce86d0f45297 /script-beta/parser | |
parent | 8d2199b3ec3d7b7a72c6e230f9d40c18f8c7477d (diff) | |
download | lua-language-server-a02d1537bbf7829c8117ce481a9bbcff7efa8dd7.zip |
更新类型推测
Diffstat (limited to 'script-beta/parser')
-rw-r--r-- | script-beta/parser/guide.lua | 87 |
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) |