diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2020-10-21 18:03:04 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2020-10-21 18:03:04 +0800 |
commit | 57dd96177c217611de4aced4efde94106ee389d3 (patch) | |
tree | 56f2ea84f24b5e9354aeddaef1099767c1140dbd /script-beta/parser | |
parent | d93af8f2d23cace5716aa842901bdfc70a4b429c (diff) | |
download | lua-language-server-57dd96177c217611de4aced4efde94106ee389d3.zip |
泛型的类型推断
Diffstat (limited to 'script-beta/parser')
-rw-r--r-- | script-beta/parser/guide.lua | 51 | ||||
-rw-r--r-- | script-beta/parser/luadoc.lua | 13 |
2 files changed, 54 insertions, 10 deletions
diff --git a/script-beta/parser/guide.lua b/script-beta/parser/guide.lua index fa07c3dc..1787bdbb 100644 --- a/script-beta/parser/guide.lua +++ b/script-beta/parser/guide.lua @@ -21,6 +21,10 @@ local DEVELOP = _G.DEVELOP local log = log local debug = debug +local function logWarn(...) + log.warn(...) +end + _ENV = nil local m = {} @@ -2203,7 +2207,7 @@ function m.searchRefs(status, obj, mode) error('status.depth overflow') elseif DEVELOP then --log.warn(debug.traceback('status.depth overflow')) - log.warn('status.depth overflow') + logWarn('status.depth overflow') end end @@ -2462,17 +2466,60 @@ function m.inferCheckLibrary(status, source) return true end +local function getDocTypeUnitName(unit) + local typeName + if unit.type == 'doc.type.name' then + typeName = unit[1] + elseif unit.type == 'doc.type.function' then + typeName = 'function' + end + if unit.array then + typeName = typeName .. '[]' + elseif unit.generic then + typeName = ('%s<%s, %s>'):format( + typeName, + m.viewInferType(m.getDocTypeNames(unit.key)), + m.viewInferType(m.getDocTypeNames(unit.value)) + ) + end + return typeName +end + +function m.getDocTypeNames(doc) + local results = {} + for _, unit in ipairs(doc.types) do + local typeName = getDocTypeUnitName(unit) + results[#results+1] = { + type = typeName, + source = unit, + } + end + for _, enum in ipairs(doc.enums) do + results[#results+1] = { + type = enum[1], + source = enum, + } + end + return results +end + function m.inferByDoc(status, source) local binds = source.bindDocs if not binds then return end + status.results = {} for _, doc in ipairs(binds) do if doc.type == 'doc.class' then - status.results = m.allocInfer { + status.results[#status.results+1] = { type = doc.class[1], source = doc, } + elseif doc.type == 'doc.type' then + local results = m.getDocTypeNames(doc) + for _, res in ipairs(results) do + status.results[#status.results+1] = res + end end end end diff --git a/script-beta/parser/luadoc.lua b/script-beta/parser/luadoc.lua index e2aa950d..b0cea88d 100644 --- a/script-beta/parser/luadoc.lua +++ b/script-beta/parser/luadoc.lua @@ -229,14 +229,10 @@ local function nextSymbolOrError(symbol) return false end -local function parseTypeUnitTable() +local function parseTypeUnitGeneric(typeUnit) if not checkToken('symbol', '<', 1) then return nil end - local typeUnit = { - type = 'doc.type.table', - start = getStart(), - } if not nextSymbolOrError('<') then return nil end @@ -249,6 +245,7 @@ local function parseTypeUnitTable() return nil end nextSymbolOrError('>') + typeUnit.generic= true typeUnit.key = key typeUnit.value = value typeUnit.finish = getFinish() @@ -324,9 +321,7 @@ end local function parseTypeUnit(parent, content) local typeUnit - if content == 'table' then - typeUnit = parseTypeUnitTable() - elseif content == 'fun' then + if content == 'fun' then typeUnit = parseTypeUnitFunction() end if not typeUnit then @@ -345,6 +340,8 @@ local function parseTypeUnit(parent, content) nextToken() typeUnit.array = true typeUnit.finish = getFinish() + else + parseTypeUnitGeneric(typeUnit) end return typeUnit end |