summaryrefslogtreecommitdiff
path: root/script-beta/parser
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2020-10-21 18:03:04 +0800
committer最萌小汐 <sumneko@hotmail.com>2020-10-21 18:03:04 +0800
commit57dd96177c217611de4aced4efde94106ee389d3 (patch)
tree56f2ea84f24b5e9354aeddaef1099767c1140dbd /script-beta/parser
parentd93af8f2d23cace5716aa842901bdfc70a4b429c (diff)
downloadlua-language-server-57dd96177c217611de4aced4efde94106ee389d3.zip
泛型的类型推断
Diffstat (limited to 'script-beta/parser')
-rw-r--r--script-beta/parser/guide.lua51
-rw-r--r--script-beta/parser/luadoc.lua13
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