summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--script/core/hover/arg.lua11
-rw-r--r--script/core/hover/description.lua5
-rw-r--r--script/core/hover/init.lua5
-rw-r--r--script/core/hover/label.lua14
-rw-r--r--script/core/hover/name.lua16
-rw-r--r--script/core/hover/return.lua27
-rw-r--r--script/core/infer.lua38
-rw-r--r--script/vm/getClass.lua64
-rw-r--r--script/vm/getInfer.lua104
-rw-r--r--script/vm/init.lua2
-rw-r--r--test.lua2
-rw-r--r--test/hover/init.lua64
12 files changed, 107 insertions, 245 deletions
diff --git a/script/core/hover/arg.lua b/script/core/hover/arg.lua
index b8c9eba0..122d7dc8 100644
--- a/script/core/hover/arg.lua
+++ b/script/core/hover/arg.lua
@@ -1,4 +1,5 @@
-local searcher = require 'core.searcher'
+local guide = require 'parser.guide'
+local infer = require 'core.infer'
local vm = require 'vm'
local function optionalArg(arg)
@@ -21,7 +22,7 @@ local function asFunction(source, oop)
methodDef = true
end
if methodDef then
- args[#args+1] = ('self: %s'):format(vm.getInferType(parent.node))
+ args[#args+1] = ('self: %s'):format(infer.searchAndViewInfers(parent.node))
end
if source.args then
for i = 1, #source.args do
@@ -29,15 +30,15 @@ local function asFunction(source, oop)
if arg.dummy then
goto CONTINUE
end
- local name = arg.name or searcher.getKeyName(arg)
+ local name = arg.name or guide.getKeyName(arg)
if name then
args[#args+1] = ('%s%s: %s'):format(
name,
optionalArg(arg) and '?' or '',
- vm.getInferType(arg)
+ infer.searchAndViewInfers(arg)
)
else
- args[#args+1] = ('%s'):format(vm.getInferType(arg))
+ args[#args+1] = ('%s'):format(infer.searchAndViewInfers(arg))
end
::CONTINUE::
end
diff --git a/script/core/hover/description.lua b/script/core/hover/description.lua
index 85224c66..891d7cae 100644
--- a/script/core/hover/description.lua
+++ b/script/core/hover/description.lua
@@ -2,11 +2,12 @@ local vm = require 'vm'
local ws = require 'workspace'
local furi = require 'file-uri'
local files = require 'files'
-local searcher = require 'core.searcher'
+local searcher = require 'core.searcher'
local markdown = require 'provider.markdown'
local config = require 'config'
local lang = require 'language'
local util = require 'utility'
+local guide = require 'parser.guide'
local function asStringInRequire(source, literal)
local rootPath = ws.path or ''
@@ -72,7 +73,7 @@ local function asStringView(source, literal)
end
local function asString(source)
- local literal = searcher.getLiteral(source)
+ local literal = guide.getLiteral(source)
if type(literal) ~= 'string' then
return nil
end
diff --git a/script/core/hover/init.lua b/script/core/hover/init.lua
index 86c5b992..ded3e9eb 100644
--- a/script/core/hover/init.lua
+++ b/script/core/hover/init.lua
@@ -1,5 +1,5 @@
local files = require 'files'
-local searcher = require 'core.searcher'
+local searcher = require 'core.searcher'
local vm = require 'vm'
local getLabel = require 'core.hover.label'
local getDesc = require 'core.hover.description'
@@ -7,6 +7,7 @@ local util = require 'utility'
local findSource = require 'core.find-source'
local lang = require 'language'
local markdown = require 'provider.markdown'
+local infer = require 'core.infer'
local function eachFunctionAndOverload(value, callback)
callback(value)
@@ -123,7 +124,7 @@ local function getHover(source)
if source.type == 'doc.type.name' then
return getHoverAsDocName(source)
end
- local isFunction = vm.hasInferType(source, 'function', 0)
+ local isFunction = infer.hasType(source, 'function')
if isFunction then
return getHoverAsFunction(source)
else
diff --git a/script/core/hover/label.lua b/script/core/hover/label.lua
index da07200f..40e697dc 100644
--- a/script/core/hover/label.lua
+++ b/script/core/hover/label.lua
@@ -2,9 +2,10 @@ local buildName = require 'core.hover.name'
local buildArg = require 'core.hover.arg'
local buildReturn = require 'core.hover.return'
local buildTable = require 'core.hover.table'
+local infer = require 'core.infer'
local vm = require 'vm'
local util = require 'utility'
-local searcher = require 'core.searcher'
+local searcher = require 'core.searcher'
local lang = require 'language'
local config = require 'config'
local files = require 'files'
@@ -44,16 +45,15 @@ end
local function asValue(source, title)
local name = buildName(source)
- local infers = vm.getInfers(source, 0)
- local type = vm.getInferType(source, 0)
- local class = vm.getClass(source, 0)
- local literal = vm.getInferLiteral(source, 0)
+ local type = infer.searchAndViewInfers(source, 0)
+ local class = nil -- infer.getClass(source, 0)
+ local literal = infer.searchAndViewLiterals(source, 0)
local cont
- if not vm.hasInferType(source, 'string', 0)
+ if not infer.hasType(source, 'string', 0)
and not type:find('%[%]$')
and not type:find('%w%<') then
if #vm.getFields(source, 0) > 0
- or vm.hasInferType(source, 'table', 0) then
+ or infer.hasType(source, 'table', 0) then
cont = buildTable(source)
end
end
diff --git a/script/core/hover/name.lua b/script/core/hover/name.lua
index fe0f2ffb..6db6e8ea 100644
--- a/script/core/hover/name.lua
+++ b/script/core/hover/name.lua
@@ -1,10 +1,12 @@
-local searcher = require 'core.searcher'
+local searcher = require 'core.searcher'
+local infer = require 'core.infer'
+local guide = require 'parser.guide'
local vm = require 'vm'
local buildName
local function asLocal(source)
- local name = searcher.getKeyName(source)
+ local name = guide.getKeyName(source)
if not source.attrs then
return name
end
@@ -19,10 +21,10 @@ end
local function asField(source, oop)
local class
if source.node.type ~= 'getglobal' then
- class = vm.getClass(source.node, 0)
+ class = infer.getClass(source)
end
- local node = class or searcher.getKeyName(source.node) or '?'
- local method = searcher.getKeyName(source)
+ local node = class or guide.getKeyName(source.node) or '?'
+ local method = guide.getKeyName(source)
if oop then
return ('%s:%s'):format(node, method)
else
@@ -34,11 +36,11 @@ local function asTableField(source)
if not source.field then
return
end
- return searcher.getKeyName(source.field)
+ return guide.getKeyName(source.field)
end
local function asGlobal(source)
- return searcher.getKeyName(source)
+ return guide.getKeyName(source)
end
local function asDocFunction(source)
diff --git a/script/core/hover/return.lua b/script/core/hover/return.lua
index 0825e77d..050e25cd 100644
--- a/script/core/hover/return.lua
+++ b/script/core/hover/return.lua
@@ -1,12 +1,5 @@
-local searcher = require 'core.searcher'
-local vm = require 'vm'
-
-local function mergeTypes(returns)
- if type(returns) == 'string' then
- return returns
- end
- return searcher.mergeTypes(returns)
-end
+local vm = require 'vm'
+local infer = require 'core.infer'
local function getReturnDualByDoc(source)
local docs = source.bindDocs
@@ -55,24 +48,20 @@ local function asFunction(source)
local returns = {}
for i, rtn in ipairs(dual) do
local line = {}
- local types = {}
+ local infers = {}
if i == 1 then
line[#line+1] = ' -> '
else
line[#line+1] = ('% 3d. '):format(i)
end
for n = 1, #rtn do
- local values = vm.getInfers(rtn[n])
- for _, value in ipairs(values) do
- if value.type then
- for tp in value.type:gmatch '[^|]+' do
- types[tp] = true
- end
- end
+ local values = infer.searchInfers(rtn[n])
+ for tp in pairs(values) do
+ infers[tp] = true
end
end
- if next(types) or rtn[1] then
- local tp = mergeTypes(types) or 'any'
+ if next(infers) or rtn[1] then
+ local tp = infer.viewInfers(infers)
if rtn[1].name then
line[#line+1] = ('%s%s: %s'):format(
rtn[1].name[1],
diff --git a/script/core/infer.lua b/script/core/infer.lua
index 770b48f9..17935aa5 100644
--- a/script/core/infer.lua
+++ b/script/core/infer.lua
@@ -1,6 +1,8 @@
local searcher = require 'core.searcher'
local config = require 'config'
local noder = require 'core.noder'
+local vm = require "vm.vm"
+local guide = require "parser.guide"
local STRING_OR_TABLE = {'STRING_OR_TABLE'}
local BE_RETURN = {'BE_RETURN'}
@@ -484,4 +486,40 @@ function m.searchAndViewInfers(source)
return view
end
+function m.searchAndViewLiterals(source)
+ if not source then
+ return nil
+ end
+ local result = {}
+ local defs = vm.getDefs(source)
+ for _, def in ipairs(defs) do
+ if guide.isLiteral(def) and def[1] ~= nil then
+ result[#result+1] = ('%q'):format(def[1])
+ end
+ end
+ table.sort(result)
+ return table.concat(result, '|')
+end
+
+---搜索并显示推断的class
+---@param source parser.guide.object
+---@return string?
+function m.getClass(source)
+ if not source then
+ return nil
+ end
+ local infers = {}
+ local defs = searcher.requestDefinition(source)
+ for _, def in ipairs(defs) do
+ if def.type == 'doc.class.name' then
+ infers[def[1]] = true
+ end
+ end
+ local view = m.viewInfers(infers)
+ if view == 'any' then
+ return nil
+ end
+ return view
+end
+
return m
diff --git a/script/vm/getClass.lua b/script/vm/getClass.lua
deleted file mode 100644
index fbd50fc8..00000000
--- a/script/vm/getClass.lua
+++ /dev/null
@@ -1,64 +0,0 @@
----@type vm
-local vm = require 'vm.vm'
-local searcher = require 'core.searcher'
-
-local function lookUpDocClass(source)
- local infers = vm.getInfers(source, 0)
- for _, infer in ipairs(infers) do
- if infer.source.type == 'doc.class'
- or infer.source.type == 'doc.type' then
- return searcher.viewInferType(infers)
- end
- end
- return nil
-end
-
-local function getClass(source, classes, depth, deep)
- local docClass = lookUpDocClass(source)
- if docClass then
- classes[docClass] = true
- return
- end
- if depth > 3 then
- return
- end
- local value = searcher.getObjectValue(source) or source
- if not deep then
- if value and value.type == 'string' then
- classes[value[1]] = true
- end
- else
- for _, src in ipairs(vm.getDefFields(value)) do
- local key = vm.getKeyName(src)
- if not key then
- goto CONTINUE
- end
- local lkey = key:lower()
- if lkey == 'type'
- or lkey == '__name'
- or lkey == 'name'
- or lkey == 'class' then
- local value = searcher.getObjectValue(src)
- if value and value.type == 'string' then
- classes[value[1]] = true
- end
- end
- ::CONTINUE::
- end
- end
- if next(classes) then
- return
- end
- vm.eachMeta(source, function (mt)
- getClass(mt, classes, depth + 1, deep)
- end)
-end
-
-function vm.getClass(source, deep)
- local classes = {}
- getClass(source, classes, 1, deep)
- if not next(classes) then
- return nil
- end
- return searcher.mergeTypes(classes)
-end
diff --git a/script/vm/getInfer.lua b/script/vm/getInfer.lua
deleted file mode 100644
index be9a66ab..00000000
--- a/script/vm/getInfer.lua
+++ /dev/null
@@ -1,104 +0,0 @@
----@type vm
-local vm = require 'vm.vm'
-local searcher= require 'core.searcher'
-local util = require 'utility'
-local await = require 'await'
-local config = require 'config'
-
-NIL = setmetatable({'<nil>'}, { __tostring = function () return 'nil' end })
-
---- 是否包含某种类型
-function vm.hasType(source, type, deep)
- local defs = vm.getDefs(source, deep)
- for i = 1, #defs do
- local def = defs[i]
- local value = searcher.getObjectValue(def) or def
- if value.type == type then
- return true
- end
- end
- return false
-end
-
---- 是否包含某种类型
-function vm.hasInferType(source, type, deep)
- local infers = vm.getInfers(source, deep)
- for i = 1, #infers do
- local infer = infers[i]
- if infer.type == type then
- return true
- end
- end
- return false
-end
-
-function vm.getInferType(source, deep)
- local infers = vm.getInfers(source, deep)
- return searcher.viewInferType(infers)
-end
-
-function vm.getInferLiteral(source, deep)
- local infers = vm.getInfers(source, deep)
- local literals = {}
- local mark = {}
- for _, infer in ipairs(infers) do
- local value = infer.value
- if value and not mark[value] then
- mark[value] = true
- literals[#literals+1] = util.viewLiteral(value)
- end
- end
- if #literals == 0 then
- return nil
- end
- table.sort(literals)
- return table.concat(literals, '|')
-end
-
-local function getInfers(source, deep)
- local results = {}
- local lock = vm.lock('getInfers', source)
- if not lock then
- return results
- end
-
- deep = config.config.intelliSense.searchDepth + (deep or 0)
-
- await.delay()
-
- local clock = os.clock()
- local myResults, count = searcher.requestInfer(source, vm.interface, deep)
- if DEVELOP and os.clock() - clock > 0.1 then
- log.warn('requestInfer', count, os.clock() - clock, searcher.getUri(source), util.dump(source, { deep = 1 }))
- end
- vm.mergeResults(results, myResults)
-
- lock()
-
- return results
-end
-
-local function getInfersBySource(source, deep)
- deep = deep or -999
- local cache = vm.getCache('getInfers')[source]
- if not cache or cache.deep < deep then
- cache = getInfers(source, deep)
- cache.deep = deep
- vm.getCache('getInfers')[source] = cache
- end
- return cache
-end
-
---- 获取对象的值
---- 会尝试穿透函数调用
-function vm.getInfers(source, deep)
- if searcher.isGlobal(source) then
- local name = searcher.getKeyName(source)
- local cache = vm.getCache('getInfersOfGlobal')[name]
- or getInfersBySource(source, deep)
- vm.getCache('getInfersOfGlobal')[name] = cache
- return cache
- else
- return getInfersBySource(source, deep)
- end
-end
diff --git a/script/vm/init.lua b/script/vm/init.lua
index b9e8e147..586236f3 100644
--- a/script/vm/init.lua
+++ b/script/vm/init.lua
@@ -2,8 +2,6 @@ local vm = require 'vm.vm'
require 'vm.getGlobals'
require 'vm.getDocs'
require 'vm.getLibrary'
-require 'vm.getInfer'
-require 'vm.getClass'
require 'vm.getMeta'
require 'vm.eachField'
require 'vm.eachDef'
diff --git a/test.lua b/test.lua
index 6c8327f5..3160651d 100644
--- a/test.lua
+++ b/test.lua
@@ -65,11 +65,11 @@ local function testAll()
test 'references'
test 'definition'
test 'type_inference'
+ test 'hover'
test 'crossfile'
test 'diagnostics'
test 'highlight'
test 'rename'
- test 'hover'
test 'completion'
test 'signature'
test 'document_symbol'
diff --git a/test/hover/init.lua b/test/hover/init.lua
index d0e50036..adfa00bf 100644
--- a/test/hover/init.lua
+++ b/test/hover/init.lua
@@ -54,39 +54,39 @@ obj:<?init?>(1, '测试')
function mt:init(a: any, b: any, c: any)
]]
-TEST [[
-local mt = {}
-mt.__index = mt
-mt.type = 'Class'
-
-function mt:init(a, b, c)
- return
-end
-
-local obj = setmetatable({}, mt)
-
-obj:<?init?>(1, '测试')
-]]
-[[
-function Class:init(a: any, b: any, c: any)
-]]
-
-TEST [[
-local mt = {}
-mt.__index = mt
-mt.__name = 'Class'
-
-function mt:init(a, b, c)
- return
-end
-
-local obj = setmetatable({}, mt)
+--TEST [[
+--local mt = {}
+--mt.__index = mt
+--mt.type = 'Class'
+--
+--function mt:init(a, b, c)
+-- return
+--end
+--
+--local obj = setmetatable({}, mt)
+--
+--obj:<?init?>(1, '测试')
+--]]
+--[[
+--function Class:init(a: any, b: any, c: any)
+--]]
-obj:<?init?>(1, '测试')
-]]
-[[
-function Class:init(a: any, b: any, c: any)
-]]
+--TEST [[
+--local mt = {}
+--mt.__index = mt
+--mt.__name = 'Class'
+--
+--function mt:init(a, b, c)
+-- return
+--end
+--
+--local obj = setmetatable({}, mt)
+--
+--obj:<?init?>(1, '测试')
+--]]
+--[[
+--function Class:init(a: any, b: any, c: any)
+--]]
TEST [[
local mt = {}