summaryrefslogtreecommitdiff
path: root/server-beta/src
diff options
context:
space:
mode:
Diffstat (limited to 'server-beta/src')
-rw-r--r--server-beta/src/core/definition.lua14
-rw-r--r--server-beta/src/doctor.lua210
-rw-r--r--server-beta/src/files.lua1
-rw-r--r--server-beta/src/parser/compile.lua6
-rw-r--r--server-beta/src/parser/guide.lua12
-rw-r--r--server-beta/src/searcher/eachField.lua2
6 files changed, 149 insertions, 96 deletions
diff --git a/server-beta/src/core/definition.lua b/server-beta/src/core/definition.lua
index 30ce5dec..1c2adf3e 100644
--- a/server-beta/src/core/definition.lua
+++ b/server-beta/src/core/definition.lua
@@ -3,7 +3,7 @@ local workspace = require 'workspace'
local files = require 'files'
local searcher = require 'searcher'
-local function findDef(sch, source, callback)
+local function findDef(source, callback)
if source.type ~= 'local'
and source.type ~= 'getlocal'
and source.type ~= 'setlocal'
@@ -21,8 +21,9 @@ local function findDef(sch, source, callback)
if info.mode == 'declare'
or info.mode == 'set'
or info.mode == 'return' then
- local src = info.source
- local uri = info.uri
+ local src = info.source
+ local root = guide.getRoot(src)
+ local uri = root.uri
if src.type == 'setfield'
or src.type == 'getfield'
or src.type == 'tablefield' then
@@ -41,8 +42,7 @@ local function findDef(sch, source, callback)
end)
end
----@param sch searcher
-local function checkRequire(sch, source, offset, callback)
+local function checkRequire(source, offset, callback)
if source.type ~= 'call' then
return
end
@@ -80,7 +80,7 @@ return function (uri, offset)
end
local results = {}
guide.eachSourceContain(ast.ast, offset, function (source)
- checkRequire(searcher, source, offset, function (uri)
+ checkRequire(source, offset, function (uri)
results[#results+1] = {
uri = files.getOriginUri(uri),
source = source,
@@ -90,7 +90,7 @@ return function (uri, offset)
}
}
end)
- findDef(searcher, source, function (target, uri)
+ findDef(source, function (target, uri)
results[#results+1] = {
target = target,
uri = files.getOriginUri(uri),
diff --git a/server-beta/src/doctor.lua b/server-beta/src/doctor.lua
index 48c3ebbe..08ec69cf 100644
--- a/server-beta/src/doctor.lua
+++ b/server-beta/src/doctor.lua
@@ -1,10 +1,8 @@
-local ac = ac
local type = type
local next = next
local ipairs = ipairs
local rawget = rawget
local pcall = pcall
-local collectgarbage = collectgarbage
local getregistry = debug.getregistry
local getmetatable = debug.getmetatable
local getupvalue = debug.getupvalue
@@ -16,101 +14,102 @@ local mathType = math.type
local tableConcat = table.concat
local _G = _G
local registry = getregistry()
+local tableSort = table.sort
_ENV = nil
local m = {}
---- 内存快照
----@return table
-function m.snapshot()
- local mark = {}
- local find
+local function getTostring(obj)
+ local mt = getmetatable(obj)
+ if not mt then
+ return nil
+ end
+ local toString = rawget(mt, '__tostring')
+ if not toString then
+ return nil
+ end
+ local suc, str = pcall(toString, obj)
+ if not suc then
+ return nil
+ end
+ if type(str) ~= 'string' then
+ return nil
+ end
+ return str
+end
- local function getTostring(obj)
- local mt = getmetatable(obj)
- if not mt then
- return nil
+local function formatName(obj)
+ local tp = type(obj)
+ if tp == 'nil' then
+ return 'nil:nil'
+ elseif tp == 'boolean' then
+ if obj == true then
+ return 'boolean:true'
+ else
+ return 'boolean:false'
end
- local toString = rawget(mt, '__tostring')
- if not toString then
- return nil
+ elseif tp == 'number' then
+ if mathType(obj) == 'integer' then
+ return ('number:%d'):format(obj)
+ else
+ -- 如果浮点数可以完全表示为整数,那么就转换为整数
+ local str = ('%.10f'):format(obj):gsub('%.?[0]+$', '')
+ if str:find('.', 1, true) then
+ -- 如果浮点数不能表示为整数,那么再加上它的精确表示法
+ str = ('%s(%q)'):format(str, obj)
+ end
+ return 'number:' .. str
end
- local suc, str = pcall(toString, obj)
- if not suc then
- return nil
+ elseif tp == 'string' then
+ local str = ('%q'):format(obj)
+ if #str > 100 then
+ local new = ('%s...(len=%d)'):format(str:sub(1, 100), #str)
+ if #new < #str then
+ str = new
+ end
end
- if type(str) ~= 'string' then
- return nil
+ return 'string:' .. str
+ elseif tp == 'function' then
+ local info = getinfo(obj, 'S')
+ if info.what == 'c' then
+ return ('function:%p(C)'):format(obj)
+ elseif info.what == 'main' then
+ return ('function:%p(main)'):format(obj)
+ else
+ return ('function:%p(%s:%d-%d)'):format(obj, info.source, info.linedefined, info.lastlinedefined)
end
- return str
- end
-
- local function formatName(obj)
- local tp = type(obj)
- if tp == 'nil' then
- return 'nil:nil'
- elseif tp == 'boolean' then
- if obj == true then
- return 'boolean:true'
- else
- return 'boolean:false'
- end
- elseif tp == 'number' then
- if mathType(obj) == 'integer' then
- return ('number:%d'):format(obj)
- else
- -- 如果浮点数可以完全表示为整数,那么就转换为整数
- local str = ('%.10f'):format(obj):gsub('%.?[0]+$', '')
- if str:find('.', 1, true) then
- -- 如果浮点数不能表示为整数,那么再加上它的精确表示法
- str = ('%s(%q)'):format(str, obj)
- end
- return 'number:' .. str
- end
- elseif tp == 'string' then
- local str = ('%q'):format(obj)
- if #str > 100 then
- local new = ('%s...(len=%d)'):format(str:sub(1, 100), #str)
- if #new < #str then
- str = new
- end
- end
- return 'string:' .. str
- elseif tp == 'function' then
- local info = getinfo(obj, 'S')
- if info.what == 'c' then
- return ('function:%p(C)'):format(obj)
- elseif info.what == 'main' then
- return ('function:%p(main)'):format(obj)
- else
- return ('function:%p(%s:%d-%d)'):format(obj, info.source, info.linedefined, info.lastlinedefined)
- end
- elseif tp == 'table' then
- local id = getTostring(obj)
- if not id then
- if obj == _G then
- id = '_G'
- elseif obj == registry then
- id = 'registry'
- end
- end
- if id then
- return ('table:%p(%s)'):format(obj, id)
- else
- return ('table:%p'):format(obj)
- end
- elseif tp == 'userdata' then
- local id = getTostring(obj)
- if id then
- return ('userdata:%p(%s)'):format(obj, id)
- else
- return ('userdata:%p'):format(obj)
+ elseif tp == 'table' then
+ local id = getTostring(obj)
+ if not id then
+ if obj == _G then
+ id = '_G'
+ elseif obj == registry then
+ id = 'registry'
end
+ end
+ if id then
+ return ('table:%p(%s)'):format(obj, id)
else
- return ('%s:%p'):format(tp, obj)
+ return ('table:%p'):format(obj)
end
+ elseif tp == 'userdata' then
+ local id = getTostring(obj)
+ if id then
+ return ('userdata:%p(%s)'):format(obj, id)
+ else
+ return ('userdata:%p'):format(obj)
+ end
+ else
+ return ('%s:%p'):format(tp, obj)
end
+end
+
+--- 内存快照
+---@return table
+function m.snapshot()
+ local mark = {}
+ local find
local function findTable(t, result)
result = result or {}
@@ -333,4 +332,49 @@ function m.catch(...)
return result
end
+--- 生成一个报告
+---@return string
+function m.report()
+ local snapshot = m.snapshot()
+ local cache = {}
+ local mark = {}
+
+ local function scan(t)
+ local obj = t.info.object
+ local tp = type(obj)
+ if tp == 'table'
+ or tp == 'userdata'
+ or tp == 'function'
+ or tp == 'string'
+ or tp == 'thread' then
+ local point = ('%p'):format(obj)
+ if not cache[point] then
+ cache[point] = {
+ point = point,
+ count = 0,
+ name = formatName(obj),
+ }
+ end
+ cache[point].count = cache[point].count + 1
+ end
+ if not mark[t.info] then
+ mark[t.info] = true
+ for _, child in ipairs(t.info) do
+ scan(child)
+ end
+ end
+ end
+
+ scan(snapshot)
+
+ local list = {}
+ for _, info in next, cache do
+ list[#list+1] = info
+ end
+ tableSort(list, function (a, b)
+ return a.name < b.name
+ end)
+ return list
+end
+
return m
diff --git a/server-beta/src/files.lua b/server-beta/src/files.lua
index c3b33122..bc940e0f 100644
--- a/server-beta/src/files.lua
+++ b/server-beta/src/files.lua
@@ -129,6 +129,7 @@ function m.getAst(uri)
local state, err = parser:compile(file.text, 'lua', config.config.runtime.version)
if state then
state.uri = file.uri
+ state.ast.uri = file.uri
file.ast = state
else
log.error(err)
diff --git a/server-beta/src/parser/compile.lua b/server-beta/src/parser/compile.lua
index 51803753..9f92fb53 100644
--- a/server-beta/src/parser/compile.lua
+++ b/server-beta/src/parser/compile.lua
@@ -3,7 +3,7 @@ local type = type
_ENV = nil
-local pushError, Compile, CompileBlock, Cache, Block, GoToTag, Version, ENVMode, Compiled, ValueID
+local pushError, Compile, CompileBlock, Block, GoToTag, ENVMode, Compiled
local function addRef(node, obj)
if not node.ref then
@@ -425,21 +425,17 @@ return function (self, lua, mode, version)
return nil, err
end
pushError = state.pushError
- Version = version
if version == 'Lua 5.1' or version == 'LuaJIT' then
ENVMode = 'fenv'
else
ENVMode = '_ENV'
end
- Cache = {}
Compiled = {}
GoToTag = {}
- ValueID = 0
if type(state.ast) == 'table' then
Compile(state.ast)
end
PostCompile()
- Cache = nil
Compiled = nil
GoToTag = nil
return state
diff --git a/server-beta/src/parser/guide.lua b/server-beta/src/parser/guide.lua
index f8330438..f0634025 100644
--- a/server-beta/src/parser/guide.lua
+++ b/server-beta/src/parser/guide.lua
@@ -164,6 +164,18 @@ function m.getBreakBlock(obj)
error('guide.getBreakBlock overstack')
end
+--- 寻找根区块
+function m.getRoot(obj)
+ for _ = 1, 1000 do
+ local parent = obj.parent
+ if not parent then
+ return obj
+ end
+ obj = parent
+ end
+ error('guide.getRoot overstack')
+end
+
--- 寻找函数的不定参数,返回不定参在第几个参数上,以及该参数对象。
--- 如果函数是主函数,则返回`0, nil`。
---@return table
diff --git a/server-beta/src/searcher/eachField.lua b/server-beta/src/searcher/eachField.lua
index 71b6e45b..11ec2be2 100644
--- a/server-beta/src/searcher/eachField.lua
+++ b/server-beta/src/searcher/eachField.lua
@@ -47,7 +47,7 @@ local function ofSpecialArg(source, callback)
local args = source.parent
local call = args.parent
local func = call.node
- local name = searcher:getSpecialName(func)
+ local name = searcher.getSpecialName(func)
if name == 'rawset' then
if args[1] == source and args[2] then
callback {