summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--script/core/completion/completion.lua8
-rw-r--r--script/core/diagnostics/duplicate-set-field.lua2
-rw-r--r--script/core/hover/description.lua2
-rw-r--r--script/core/signature.lua2
-rw-r--r--script/core/type-definition.lua2
-rw-r--r--script/vm/compiler.lua19
-rw-r--r--script/vm/field.lua22
-rw-r--r--script/vm/local-id.lua29
-rw-r--r--script/vm/vm.lua12
-rw-r--r--test/hover/init.lua2
10 files changed, 64 insertions, 36 deletions
diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua
index 6a979af9..76dd6480 100644
--- a/script/core/completion/completion.lua
+++ b/script/core/completion/completion.lua
@@ -183,7 +183,7 @@ local function getSnip(source)
end
local defs = vm.getRefs(source)
for _, def in ipairs(defs) do
- def = searcher.getObjectValue(def) or def
+ def = vm.getObjectValue(def) or def
if def ~= source and def.type == 'function' then
local uri = guide.getUri(def)
local text = files.getText(uri)
@@ -458,7 +458,7 @@ local function checkFieldFromFieldToIndex(state, name, src, parent, word, startP
end
local function checkFieldThen(state, name, src, word, startPos, position, parent, oop, results)
- local value = searcher.getObjectValue(src) or src
+ local value = vm.getObjectValue(src) or src
local kind = define.CompletionItemKind.Field
if value.type == 'function'
or value.type == 'doc.type.function' then
@@ -537,7 +537,7 @@ local function checkFieldOfRefs(refs, state, word, startPos, position, parent, o
end
local funcLabel
if config.get(state.uri, 'Lua.completion.showParams') then
- local value = searcher.getObjectValue(src) or src
+ local value = vm.getObjectValue(src) or src
if value.type == 'function'
or value.type == 'doc.type.function' then
funcLabel = name .. getParams(value, oop)
@@ -1494,7 +1494,7 @@ local function tryCallArg(state, position, results)
end
local defs = vm.getDefs(call.node)
for _, def in ipairs(defs) do
- def = searcher.getObjectValue(def) or def
+ def = vm.getObjectValue(def) or def
local enums = getCallEnumsAndFuncs(def, argIndex, oop, call)
if enums then
mergeEnums(myResults, enums, arg)
diff --git a/script/core/diagnostics/duplicate-set-field.lua b/script/core/diagnostics/duplicate-set-field.lua
index f8201309..96abe37c 100644
--- a/script/core/diagnostics/duplicate-set-field.lua
+++ b/script/core/diagnostics/duplicate-set-field.lua
@@ -29,7 +29,7 @@ return function (uri, callback)
if not name then
goto CONTINUE
end
- local value = searcher.getObjectValue(nxt)
+ local value = vm.getObjectValue(nxt)
if not value or value.type ~= 'function' then
goto CONTINUE
end
diff --git a/script/core/hover/description.lua b/script/core/hover/description.lua
index 741d7cbd..83f4bcca 100644
--- a/script/core/hover/description.lua
+++ b/script/core/hover/description.lua
@@ -201,7 +201,7 @@ local function isFunction(source)
if source.type == 'function' then
return true
end
- local value = searcher.getObjectValue(source)
+ local value = vm.getObjectValue(source)
if not value then
return false
end
diff --git a/script/core/signature.lua b/script/core/signature.lua
index e136bce9..449f1c8c 100644
--- a/script/core/signature.lua
+++ b/script/core/signature.lua
@@ -125,7 +125,7 @@ local function makeSignatures(text, call, pos)
local defs = vm.getDefs(node)
local mark = {}
for _, src in ipairs(defs) do
- src = searcher.getObjectValue(src) or src
+ src = vm.getObjectValue(src) or src
if src.type == 'function'
or src.type == 'doc.type.function' then
if not mark[src] then
diff --git a/script/core/type-definition.lua b/script/core/type-definition.lua
index 6bee7193..f45cb352 100644
--- a/script/core/type-definition.lua
+++ b/script/core/type-definition.lua
@@ -134,7 +134,7 @@ return function (uri, offset)
local defs = vm.getDefs(source)
local values = {}
for _, src in ipairs(defs) do
- local value = searcher.getObjectValue(src)
+ local value = vm.getObjectValue(src)
if value and value ~= src and guide.isLiteral(value) then
values[value] = true
end
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index d1f8c601..058f80ec 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -21,7 +21,8 @@ local searchFieldSwitch = util.switch()
for _, field in ipairs(node) do
if field.type == 'tablefield'
or field.type == 'tableindex' then
- if guide.getKeyName(field) == key then
+ if not key
+ or key == guide.getKeyName(field) then
pushResult(field)
end
end
@@ -48,9 +49,9 @@ local searchFieldSwitch = util.switch()
end)
: case 'local'
: call(function (node, key, pushResult)
- local sources = localID.getSources(node, key)
- if sources then
- for _, src in ipairs(sources) do
+ local fields = key and localID.getSources(node, key) or localID.getFields(node)
+ if fields then
+ for _, src in ipairs(fields) do
pushResult(src)
end
end
@@ -71,7 +72,8 @@ local searchFieldSwitch = util.switch()
local fieldNode = m.compileNode(fieldKey)
for fn in nodeMgr.eachNode(fieldNode) do
if fn.type == 'global' and fn.cate == 'type' then
- if fn.name == 'any'
+ if not key
+ or fn.name == 'any'
or (fn.name == 'boolean' and type(key) == 'boolean')
or (fn.name == 'number' and type(key) == 'number')
or (fn.name == 'integer' and math.tointeger(key))
@@ -82,7 +84,7 @@ local searchFieldSwitch = util.switch()
end
end
if fieldKey.type == 'doc.field.name' then
- if fieldKey[1] == key then
+ if not key or fieldKey[1] == key then
pushResult(field.extends)
end
end
@@ -103,7 +105,8 @@ function m.getClassFields(node, key, pushResult)
-- check ---@field
local hasFounded
for _, field in ipairs(set.fields) do
- if guide.getKeyName(field) == key then
+ if not key
+ or guide.getKeyName(field) == key then
hasFounded = true
pushResult(field)
end
@@ -341,7 +344,7 @@ local function compileByLocalID(source)
end
---@param source vm.node
----@param key any
+---@param key? any
---@param pushResult fun(source: parser.object)
function m.compileByParentNode(source, key, pushResult)
local parentNode = m.compileNode(source)
diff --git a/script/vm/field.lua b/script/vm/field.lua
index c30e112d..52c56e7f 100644
--- a/script/vm/field.lua
+++ b/script/vm/field.lua
@@ -7,26 +7,10 @@ local localID = require 'vm.local-id'
local globalMgr = require 'vm.global-manager'
local nodeMgr = require 'vm.node'
-local searchNodeSwitch = util.switch()
- : case 'table'
- : call(function (node, pushResult)
- for _, field in ipairs(node) do
- if field.type == 'tablefield'
- or field.type == 'tableindex' then
- pushResult(field)
- end
- end
- end)
-
local function searchByNode(source, pushResult)
- local node = compiler.compileNode(source)
- if not node then
- return
- end
-
- for n in nodeMgr.eachNode(node) do
- searchNodeSwitch(n.type, n, pushResult)
- end
+ compiler.compileByParentNode(source, nil, function (field)
+ pushResult(field)
+ end)
end
---@param source parser.object
diff --git a/script/vm/local-id.lua b/script/vm/local-id.lua
index 4c9da197..8d530beb 100644
--- a/script/vm/local-id.lua
+++ b/script/vm/local-id.lua
@@ -109,6 +109,9 @@ function m.compileLocalID(source)
return
end
compileSwitch(source.type, source)
+ if not source._localID then
+ return
+ end
local root = guide.getRoot(source)
if not root._localIDs then
root._localIDs = util.multiTable(2)
@@ -153,4 +156,30 @@ function m.getSources(source, key)
return root._localIDs[id]
end
+---@param source parser.object
+---@return parser.object[]
+function m.getFields(source)
+ local id = m.getID(source)
+ if not id then
+ return nil
+ end
+ local root = guide.getRoot(source)
+ if not root._localIDs then
+ return nil
+ end
+ -- TODOļ¼šoptimize
+ local fields = {}
+ for lid, sources in pairs(root._localIDs) do
+ if lid ~= id
+ and util.stringStartWith(lid, id)
+ -- only one field
+ and not lid:find(m.ID_SPLITE, #id + 2) then
+ for _, src in ipairs(sources) do
+ fields[#fields+1] = src
+ end
+ end
+ end
+ return fields
+end
+
return m
diff --git a/script/vm/vm.lua b/script/vm/vm.lua
index e524589c..d370de0d 100644
--- a/script/vm/vm.lua
+++ b/script/vm/vm.lua
@@ -49,6 +49,18 @@ function m.getKeyType(source)
return guide.getKeyType(source)
end
+---@param source parser.object
+---@return parser.object?
+function m.getObjectValue(source)
+ if source.value then
+ return source.value
+ end
+ if source.special == 'rawset' then
+ return source.args and source.args[3]
+ end
+ return nil
+end
+
m.cacheTracker = setmetatable({}, weakMT)
function m.flushCache()
diff --git a/test/hover/init.lua b/test/hover/init.lua
index 1493dfd9..fe8b0e3f 100644
--- a/test/hover/init.lua
+++ b/test/hover/init.lua
@@ -414,7 +414,7 @@ t.a = true
]]
[[
local t: {
- a: boolean|integer = 1|true,
+ a: boolean|integer = 1,
}
]]