summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2018-12-12 21:40:46 +0800
committer最萌小汐 <sumneko@hotmail.com>2018-12-12 21:40:46 +0800
commit6ac49a2eed8563c26d46456ab97952afad809d1d (patch)
tree9e9140745b926e65a8239533c50fee5c5aa81f78
parent81bbbb5ae95c727cc8021a7b7f9fb2487c26281a (diff)
downloadlua-language-server-6ac49a2eed8563c26d46456ab97952afad809d1d.zip
hover搜索class
-rw-r--r--server/src/matcher/hover.lua57
-rw-r--r--server/src/matcher/vm.lua1
-rw-r--r--server/test/hover/init.lua35
3 files changed, 89 insertions, 4 deletions
diff --git a/server/src/matcher/hover.lua b/server/src/matcher/hover.lua
index 7b4fd033..aba25268 100644
--- a/server/src/matcher/hover.lua
+++ b/server/src/matcher/hover.lua
@@ -270,11 +270,60 @@ local function buildValueFunctionHover(result, source)
]]):format(title)
end
+local function findClass(result)
+ -- 根据部分字段尝试找出自定义类型
+ local metatable = result.value.metatable
+ if not metatable or not metatable.child then
+ return nil
+ end
+ -- 查找meta表的 __name 字段
+ local name = metatable.child['__name']
+ -- 值必须是字符串
+ if name and name.value and type(name.value.value) == 'string' then
+ return '*' .. name.value.value
+ end
+ -- 查找meta表 __index 里的字段
+ local index = metatable.child['__index']
+ if index and index.value and index.value.child then
+ for key, field in pairs(index.value.child) do
+ -- 键值类型必须均为字符串
+ if type(key) ~= 'string' then
+ goto CONTINUE
+ end
+ if not field.value or type(field.value.value) ~= '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
+ hasSet = true
+ end
+ end
+ return '*' .. field.value.value
+ end
+ ::CONTINUE::
+ end
+ end
+ return nil
+end
+
local function buildValueSimpleHover(result, source)
- local type = result.value.type
- if type == 'nil' then
- type = 'any'
+ local valueType = result.value.type
+ if valueType == 'nil' then
+ valueType = 'any'
end
+
+ local class = findClass(result)
+ if class then
+ valueType = class
+ end
+
local resType = result.type
if resType == 'field' then
local field = result
@@ -297,7 +346,7 @@ local function buildValueSimpleHover(result, source)
```lua
%s: %s
```
-]]):format(resType, type)
+]]):format(resType, valueType)
end
local function getValueHover(result, source)
diff --git a/server/src/matcher/vm.lua b/server/src/matcher/vm.lua
index 4936fc0f..1ccd8b3a 100644
--- a/server/src/matcher/vm.lua
+++ b/server/src/matcher/vm.lua
@@ -362,6 +362,7 @@ function mt:callSetMetaTable(func, values)
end
self:setFunctionReturn(func, 1, values[1])
+ values[1].metatable = values[2]
-- 检查 __index
self:checkMetaIndex(values[1], values[2])
end
diff --git a/server/test/hover/init.lua b/server/test/hover/init.lua
index e3ad7be2..8c4e916d 100644
--- a/server/test/hover/init.lua
+++ b/server/test/hover/init.lua
@@ -102,3 +102,38 @@ t = {}
t.<?x?> = 1
]]
"global field: number"
+
+TEST [[
+local mt = {}
+mt.__name = 'class'
+
+local <?obj?> = setmetatable({}, mt)
+]]
+"local: *class"
+
+TEST [[
+local mt = {}
+mt.name = 'class'
+mt.__index = mt
+
+local <?obj?> = setmetatable({}, mt)
+]]
+"local: *class"
+
+TEST [[
+local mt = {}
+mt.TYPE = 'class'
+mt.__index = mt
+
+local <?obj?> = setmetatable({}, mt)
+]]
+"local: *class"
+
+TEST [[
+local mt = {}
+mt.Class = 'class'
+mt.__index = mt
+
+local <?obj?> = setmetatable({}, mt)
+]]
+"local: *class"