summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
Diffstat (limited to 'script')
-rw-r--r--script/core/diagnostics/undefined-field.lua2
-rw-r--r--script/parser/guide.lua63
-rw-r--r--script/vm/eachField.lua57
3 files changed, 105 insertions, 17 deletions
diff --git a/script/core/diagnostics/undefined-field.lua b/script/core/diagnostics/undefined-field.lua
index cc873ab2..31bd9008 100644
--- a/script/core/diagnostics/undefined-field.lua
+++ b/script/core/diagnostics/undefined-field.lua
@@ -55,7 +55,7 @@ return function (uri, callback)
local fields = {}
local empty = true
for _, docClass in ipairs(allDocClass) do
- local refs = vm.getFieldsOfDocClassAnyNotGet(docClass)
+ local refs = vm.getDefFields(docClass)
for _, ref in ipairs(refs) do
local name = vm.getKeyName(ref)
diff --git a/script/parser/guide.lua b/script/parser/guide.lua
index 4c89a09c..a6149dd7 100644
--- a/script/parser/guide.lua
+++ b/script/parser/guide.lua
@@ -29,9 +29,7 @@ end
local m = {}
-m.ANY = {"ANY"}
-
-m.ANYNOTGET = {"ANYNOTGET"}
+m.ANY = {"<ANY>"}
local blockTypes = {
['while'] = true,
@@ -1401,6 +1399,16 @@ function m.searchFields(status, obj, key)
m.cleanResults(status.results)
end
+function m.searchDefFields(status, obj, key)
+ local simple = m.getSimple(obj)
+ if not simple then
+ return
+ end
+ simple[#simple+1] = key or m.ANY
+ m.searchSameFields(status, simple, 'deffield')
+ m.cleanResults(status.results)
+end
+
function m.getObjectValue(obj)
while obj.type == 'paren' do
obj = obj.exp
@@ -1436,7 +1444,7 @@ end
function m.checkSameSimpleInValueInMetaTable(status, mt, start, pushQueue)
local newStatus = m.status(status)
- m.searchFields(newStatus, mt, '__index')
+ m.searchDefFields(newStatus, mt, '__index')
local refsStatus = m.status(status)
for i = 1, #newStatus.results do
local indexValue = m.getObjectValue(newStatus.results[i])
@@ -1684,7 +1692,8 @@ function m.checkSameSimpleByDoc(status, obj, start, pushQueue, mode)
end
return true
elseif obj.type == 'doc.field' then
- if mode ~= 'field' then
+ if mode ~= 'field'
+ and mode ~= 'deffield' then
return m.checkSameSimpleByDoc(status, obj.extends, start, pushQueue, mode)
end
elseif obj.type == 'doc.type.array' then
@@ -2309,6 +2318,30 @@ function m.pushResult(status, mode, ref, simple)
or ref.type == 'doc.field' then
results[#results+1] = ref
end
+ elseif mode == 'deffield' then
+ if ref.type == 'setfield'
+ or ref.type == 'tablefield' then
+ results[#results+1] = ref
+ elseif ref.type == 'setmethod' then
+ results[#results+1] = ref
+ elseif ref.type == 'setindex'
+ or ref.type == 'tableindex' then
+ results[#results+1] = ref
+ elseif ref.type == 'setglobal' then
+ results[#results+1] = ref
+ elseif ref.type == 'function' then
+ results[#results+1] = ref
+ elseif ref.type == 'table' then
+ results[#results+1] = ref
+ elseif ref.type == 'call' then
+ if ref.node.special == 'rawset' then
+ results[#results+1] = ref
+ end
+ elseif ref.type == 'doc.type.function'
+ or ref.type == 'doc.class.name'
+ or ref.type == 'doc.field' then
+ results[#results+1] = ref
+ end
end
end
@@ -2317,7 +2350,7 @@ function m.checkSameSimpleName(ref, sm)
return true
end
- if sm == m.ANYNOTGET and not m.isGet(ref) then
+ if sm == m.ANY_DEF and m.isSet(ref) then
return true
end
@@ -2663,13 +2696,16 @@ function m.searchRefs(status, obj, mode)
end
-- 检查单步引用
+ tracy.ZoneBeginN('searchRefs getStepRef')
local res = m.getStepRef(status, obj, mode)
if res then
for i = 1, #res do
status.results[#status.results+1] = res[i]
end
end
+ tracy.ZoneEnd()
-- 检查simple
+ tracy.ZoneBeginN('searchRefs searchSameFields')
if status.depth <= 100 then
local simple = m.getSimple(obj)
if simple then
@@ -2683,6 +2719,7 @@ function m.searchRefs(status, obj, mode)
logWarn('status.depth overflow')
end
end
+ tracy.ZoneEnd()
m.cleanResults(status.results)
@@ -4103,8 +4140,8 @@ function m.requestDefinition(obj, interface, deep)
return status.results, status.share.count
end
---- 请求对象的域
----@param filterKey nil|string|table nil表fields不做限制;string表fields必须同名;table取值为guild.ANYSET表fields必须满足isSet()
+--- 请求对象的字段
+---@param filterKey nil|string|table
function m.requestFields(obj, interface, deep, filterKey)
local status = m.status(nil, interface, deep)
@@ -4113,6 +4150,16 @@ function m.requestFields(obj, interface, deep, filterKey)
return status.results, status.share.count
end
+--- 请求对象的定义字段
+---@param filterKey nil|string|table
+function m.requestDefFields(obj, interface, deep, filterKey)
+ local status = m.status(nil, interface, deep)
+
+ m.searchDefFields(status, obj, filterKey)
+
+ return status.results, status.share.count
+end
+
--- 请求对象的类型推测
function m.requestInfer(obj, interface, deep)
local status = m.status(nil, interface, deep)
diff --git a/script/vm/eachField.lua b/script/vm/eachField.lua
index 7c5c98f8..690f6aa4 100644
--- a/script/vm/eachField.lua
+++ b/script/vm/eachField.lua
@@ -25,6 +25,27 @@ local function getFields(source, deep, filterKey)
return results
end
+local function getDefFields(source, deep, filterKey)
+ local unlock = vm.lock('eachDefField', source)
+ if not unlock then
+ return {}
+ end
+
+ while source.type == 'paren' do
+ source = source.exp
+ if not source then
+ return {}
+ end
+ end
+ deep = config.config.intelliSense.searchDepth + (deep or 0)
+
+ await.delay()
+ local results = guide.requestDefFields(source, vm.interface, deep, filterKey)
+
+ unlock()
+ return results
+end
+
local function getFieldsBySource(source, deep, filterKey)
deep = deep or -999
local cache = vm.getCache('eachField')[source]
@@ -38,6 +59,19 @@ local function getFieldsBySource(source, deep, filterKey)
return cache
end
+local function getDefFieldsBySource(source, deep, filterKey)
+ deep = deep or -999
+ local cache = vm.getCache('eachDefField')[source]
+ if not cache or cache.deep < deep then
+ cache = getDefFields(source, deep, filterKey)
+ cache.deep = deep
+ if not filterKey then
+ vm.getCache('eachDefField')[source] = cache
+ end
+ end
+ return cache
+end
+
function vm.getFields(source, deep)
if source.special == '_G' then
return vm.getGlobals '*'
@@ -56,13 +90,20 @@ function vm.getFields(source, deep)
end
end
-function vm.getFieldsOfDocClassAnyNotGet(source, deep)
- if not guide.isDocClass(source) then
- return {}
+function vm.getDefFields(source, deep)
+ if source.special == '_G' then
+ return vm.getGlobalSets '*'
+ end
+ if guide.isGlobal(source) then
+ local name = guide.getKeyName(source)
+ if not name then
+ return {}
+ end
+ local cache = vm.getCache('eachDefFieldOfGlobal')[name]
+ or getDefFieldsBySource(source, deep)
+ vm.getCache('eachDefFieldOfGlobal')[name] = cache
+ return cache
+ else
+ return getDefFieldsBySource(source, deep)
end
-
- local cache = vm.getCache('eachFieldOfDocClass')[source]
- or getFieldsBySource(source, deep, guide.ANYNOTGET)
- vm.getCache('eachFieldOfDocClass')[source] = cache
- return cache
end