diff options
Diffstat (limited to 'server-beta/src')
-rw-r--r-- | server-beta/src/core/definition.lua | 14 | ||||
-rw-r--r-- | server-beta/src/doctor.lua | 210 | ||||
-rw-r--r-- | server-beta/src/files.lua | 1 | ||||
-rw-r--r-- | server-beta/src/parser/compile.lua | 6 | ||||
-rw-r--r-- | server-beta/src/parser/guide.lua | 12 | ||||
-rw-r--r-- | server-beta/src/searcher/eachField.lua | 2 |
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 { |