summaryrefslogtreecommitdiff
path: root/server/src/core/hover.lua
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/core/hover.lua')
-rw-r--r--server/src/core/hover.lua133
1 files changed, 70 insertions, 63 deletions
diff --git a/server/src/core/hover.lua b/server/src/core/hover.lua
index 06e95379..a18ba00b 100644
--- a/server/src/core/hover.lua
+++ b/server/src/core/hover.lua
@@ -209,42 +209,54 @@ local function getFunctionHoverAsLib(name, lib, oo, select)
}
end
-local function findClass(result)
- -- 查找meta表的 __name 字段
- local name = result.value:getMeta('__name', result.source)
- -- 值必须是字符串
- if name and name.value and type(name.value:getValue()) == 'string' then
- return name.value:getValue()
+local function findClass(value)
+ -- 检查对象元表
+ local metaValue = value:getMetaTable()
+ if not metaValue then
+ return nil
end
- -- 查找meta表 __index 里的字段
- local index = result.value:getMeta('__index', result.source)
- if index and index.value then
- return index.value:eachField(function (key, field)
- -- 键值类型必须均为字符串
- if type(key) ~= 'string' then
- goto CONTINUE
- end
- if not field.value or type(field.value:getValue()) ~= 'string' then
- goto CONTINUE
- end
- local lKey = key:lower()
- if lKey == 'type' or lKey == 'name' or lKey == 'class' then
- -- 必须只有过一次赋值
- local hasSet = false
- for _, info in ipairs(field) do
- if info.type == 'set' then
- if hasSet then
- goto CONTINUE
- end
+ -- 检查元表中的 __name
+ local metaName = metaValue:rawGet('__name')
+ if metaName and type(metaName:getLiteral()) == 'string' then
+ return metaName:getLiteral()
+ end
+ -- 检查元表的 __index
+ local indexValue = metaValue:rawGet('__index')
+ if not indexValue then
+ return nil
+ end
+ -- 查找index方法中的以下字段: type name class
+ -- 允许多重继承
+ return indexValue:eachChild(function (k, v)
+ -- 键值类型必须均为字符串
+ if type(k) ~= 'string' then
+ return
+ end
+ if type(v:getLiteral()) ~= 'string' then
+ return
+ end
+ local lKey = k:lower()
+ if lKey == 'type'
+ or lKey == 'name'
+ or lKey == 'class'
+ then
+ -- 必须只有过一次赋值
+ local hasSet = false
+ local ok = v:eachInfo(function (info)
+ if info.type == 'set' then
+ if hasSet then
+ return false
+ else
hasSet = true
end
end
- return field.value:getValue()
+ end)
+ if ok == false then
+ return false
end
- ::CONTINUE::
- end)
- end
- return nil
+ return v:getLiteral()
+ end
+ end)
end
local function unpackTable(result)
@@ -291,46 +303,53 @@ local function unpackTable(result)
return table.concat(lines, '\r\n')
end
-local function getValueHover(name, valueType, result, lib)
+local function getValueHover(source, name, value, lib)
+ local valueType = value:getType()
+
if not lib then
- local class = findClass(result)
+ local class = findClass(value)
if class then
valueType = class
end
end
- if type(valueType) == 'table' then
- valueType = valueType[1]
- end
-
if not OriginTypes[valueType] then
valueType = '*' .. valueType
end
- local value
local tip
+ local literal
if lib then
- value = lib.code or (lib.value and ('%q'):format(lib.value))
- tip = lib.description
+ --value = lib.code or (lib.value and ('%q'):format(lib.value))
+ --tip = lib.description
else
- value = result.value:getValue() and ('%q'):format(result.value:getValue())
+ literal = value:getLiteral() and ('%q'):format(value:getLiteral())
end
- local tp = result.type
- if tp == 'field' then
- if result.GLOBAL then
+ local tp
+ if source:bindLocal() then
+ tp = 'local'
+ elseif source:get 'global' then
+ tp = 'global'
+ elseif source:get 'simple' then
+ local simple = source:get 'simple'
+ if simple[1]:get 'global' then
tp = 'global'
+ else
+ tp = 'field'
end
+ else
+ tp = 'field'
end
local text
if valueType == 'table' then
- text = ('%s %s: %s'):format(tp, name, unpackTable(result))
+ text = ('%s %s: %s'):format(tp, name, unpackTable(value))
else
- if value == nil then
+ if literal == nil then
text = ('%s %s: %s'):format(tp, name, valueType)
else
- text = ('%s %s: %s = %s'):format(tp, name, valueType, value)
+ text = ('%s %s: %s = %s'):format(tp, name, valueType, literal)
end
end
return {
@@ -353,7 +372,7 @@ local function getStringHover(result, lsp)
end
local function hoverAsValue(source, lsp, select)
- local lib, fullkey, isObject = findLib(source)
+ local lib, fullkey = findLib(source)
local value = source:bindValue()
local name = fullkey or buildValueName(source)
@@ -361,9 +380,10 @@ local function hoverAsValue(source, lsp, select)
if value:getType() == 'function' then
if lib then
else
- hover = getFunctionHover(name, value:getFunction(), source:getFlag 'object', select)
+ hover = getFunctionHover(name, value:getFunction(), source:get 'object', select)
end
else
+ hover = getValueHover(source, name, value, lib)
end
if not hover then
@@ -374,20 +394,7 @@ local function hoverAsValue(source, lsp, select)
end
local function hoverAsVar(result, source, lsp, select)
- if not result.value then
- return
- end
-
- if result.key == '' then
- return
- end
-
-
- if result.type ~= 'local' and result.type ~= 'field' then
- return
- end
-
- local lib, fullKey, oo = findLib(result)
+ local lib, fullKey = findLib(result)
local valueType = lib and lib.type
if valueType then
if type(valueType) == 'table' then