diff options
-rw-r--r-- | .vscode/settings.json | 3 | ||||
-rw-r--r-- | server/src/async/scanfiles.lua | 5 | ||||
-rw-r--r-- | server/src/method/workspace/didChangeConfiguration.lua | 23 | ||||
-rw-r--r-- | server/src/service.lua | 57 | ||||
-rw-r--r-- | server/src/workspace.lua | 43 |
5 files changed, 93 insertions, 38 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json index 9b431017..3e0261e8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,7 @@ "Lua.diagnostics.globals": [ "TEST", "ERR", - "OUT" + "OUT", + "IN" ] } diff --git a/server/src/async/scanfiles.lua b/server/src/async/scanfiles.lua index 6783f97b..13a8f1c8 100644 --- a/server/src/async/scanfiles.lua +++ b/server/src/async/scanfiles.lua @@ -42,6 +42,11 @@ for _, name in ipairs(args.ignored) do end local filter = path_filter(ignore) for path in scan(fs.path(args.root), filter) do + local ok, msg = IN:pop() + if ok and msg == 'stop' then + OUT:push 'stop' + return + end if path:extension():string() == '.lua' then local buf = io.load(path) if buf then diff --git a/server/src/method/workspace/didChangeConfiguration.lua b/server/src/method/workspace/didChangeConfiguration.lua index c3b701be..7a00676d 100644 --- a/server/src/method/workspace/didChangeConfiguration.lua +++ b/server/src/method/workspace/didChangeConfiguration.lua @@ -29,6 +29,18 @@ local function eq(a, b) return a == b end +local function copyTable(a) + local t = {} + for k, v in pairs(a) do + if type(v) == 'table' then + t[k] = copyTable(v) + else + t[k] = v + end + end + return t +end + return function (lsp) -- 请求配置 rpc:request('workspace/configuration', { @@ -38,7 +50,16 @@ return function (lsp) }, }, }, function (configs) + local oldConfig = copyTable(config.config) config:setConfig(configs[1]) - lsp:reCompile() + local newConfig = config.config + if not eq(oldConfig.diagnostics, newConfig.diagnostics) then + log.debug('reDiagnostic') + lsp:reDiagnostic() + end + if not eq(oldConfig.workspace, newConfig.workspace) then + lsp:ClearAllFiles() + lsp.workspace:scanFiles() + end end) end diff --git a/server/src/service.lua b/server/src/service.lua index e867edaa..569f363f 100644 --- a/server/src/service.lua +++ b/server/src/service.lua @@ -57,6 +57,9 @@ function mt:_callMethod(name, params) name, dump )) log.error(res) + if res:find 'not enough memory' then + self:restartDueToMemoryLeak() + end return nil, { code = ErrorCodes.InternalError, message = r .. '\n' .. res, @@ -105,7 +108,7 @@ function mt:clearDiagnostics(uri) uri = uri, diagnostics = {}, }) - log.debug('清除诊断:', uri) + self._needDiagnostics[uri] = nil end function mt:read(mode) @@ -220,6 +223,19 @@ function mt:reCompile() self:_testMemory() end +function mt:reDiagnostic() + for uri in pairs(self._file) do + self._needDiagnostics[uri] = true + end +end + +function mt:ClearAllFiles() + for uri in pairs(self._file) do + self:clearDiagnostics(uri) + self:removeText(uri) + end +end + function mt:loadVM(uri) local obj = self._file[uri] if not obj then @@ -547,6 +563,23 @@ function mt:_loadProto() end end +function mt:restartDueToMemoryLeak() + rpc:requestWait('window/showMessageRequest', { + type = 3, + message = lang.script('DEBUG_MEMORY_LEAK', '[Lua]'), + actions = { + { + title = lang.script.DEBUG_RESTART_NOW, + } + } + }, function () + os.exit(true) + end) + ac.wait(5, function () + os.exit(true) + end) +end + function mt:_testMemory() local cachedVM = 0 local cachedSource = 0 @@ -593,28 +626,6 @@ function mt:_testMemory() alivedSource, deadSource )) - - -- 内存过高时暴力结束服务释放内存 - if mem > 1300000 then - collectgarbage() - mem = collectgarbage 'count' - if mem > 1300000 then - rpc:requestWait('window/showMessageRequest', { - type = 3, - message = lang.script('DEBUG_MEMORY_LEAK', '[Lua]'), - actions = { - { - title = lang.script.DEBUG_RESTART_NOW, - } - } - }, function () - os.exit(true) - end) - ac.wait(5, function () - os.exit(true) - end) - end - end end function mt:onTick() diff --git a/server/src/workspace.lua b/server/src/workspace.lua index 1000558e..74a674ed 100644 --- a/server/src/workspace.lua +++ b/server/src/workspace.lua @@ -68,15 +68,14 @@ function mt:uriEncode(path) return 'file:///' .. table.concat(names, '/') end -function mt:init(rootUri) - self.root = self:uriDecode(rootUri) - if not self.root then - return +function mt:scanFiles() + if self._scanRequest then + log.info('中断上次扫描文件任务') + self._scanRequest:push('stop') + self._scanRequest = nil + self._complete = false + self:reset() end - log.info('Workspace inited, root: ', self.root) - local logPath = ROOT / 'log' / (rootUri:gsub('[/:]+', '_') .. '.log') - log.info('Log path: ', logPath) - log.init(ROOT, logPath) local ignored = {'.git'} for path in pairs(config.config.workspace.ignoreDir) do @@ -86,7 +85,7 @@ function mt:init(rootUri) local buf = io.load(self.root / '.gitmodules') if buf then for path in buf:gmatch('path = ([^\r\n]+)') do - log.debug('忽略子模块:', path) + log.info('忽略子模块:', path) ignored[#ignored+1] = path end end @@ -100,16 +99,18 @@ function mt:init(rootUri) end end - log.debug('忽略文件:\r\n' .. table.concat(ignored, '\r\n')) - + log.info('忽略文件:\r\n' .. table.concat(ignored, '\r\n')) + log.info('开始扫描文件任务') local compiled = {} - async.run('scanfiles', { + self._scanRequest = async.run('scanfiles', { root = self.root:string(), ignored = ignored, }, function (mode, ...) if mode == 'ok' then - self:reset() + log.info('扫描文件任务完成') self._complete = true + self._scanRequest = nil + self:reset() return true elseif mode == 'log' then log.debug(...) @@ -120,10 +121,26 @@ function mt:init(rootUri) local uri = self:uriEncode(path) self.files[name] = uri self.lsp:readText(uri, path, file.buf, compiled) + elseif mode == 'stop' then + log.info('扫描文件任务中断') + return false end end) end +function mt:init(rootUri) + self.root = self:uriDecode(rootUri) + if not self.root then + return + end + log.info('Workspace inited, root: ', self.root) + local logPath = ROOT / 'log' / (rootUri:gsub('[/:]+', '_') .. '.log') + log.info('Log path: ', logPath) + log.init(ROOT, logPath) + + self:scanFiles() +end + function mt:isComplete() return not not self._complete end |