diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2019-06-21 16:24:10 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2019-06-21 16:24:10 +0800 |
commit | dc0a3791060a6236bac4251a27eb7d7f2de3cb89 (patch) | |
tree | a936d23cca9e70cd995c563bec37d47136910a6c | |
parent | 8c9fef46b8592ed5cd043b8b922a40ab414d3598 (diff) | |
download | lua-language-server-dc0a3791060a6236bac4251a27eb7d7f2de3cb89.zip |
当要加载的文件恰好处于编译协程中时,快进协程而不是抛弃协程
-rw-r--r-- | server/src/service.lua | 39 | ||||
-rw-r--r-- | server/src/task.lua | 64 |
2 files changed, 83 insertions, 20 deletions
diff --git a/server/src/service.lua b/server/src/service.lua index ee2965a9..945cd939 100644 --- a/server/src/service.lua +++ b/server/src/service.lua @@ -16,6 +16,7 @@ local functionMgr= require 'vm.function' local listMgr = require 'vm.list' local emmyMgr = require 'emmy.manager' local config = require 'config' +local task = require 'task' local ErrorCodes = { -- Defined by JSON RPC @@ -353,7 +354,14 @@ function mt:loadVM(uri) if uri ~= self._lastLoadedVM then self:needCompile(uri) end - self:compileVM(uri) + if self._compileTask + and not self._compileTask:isRemoved() + and self._compileTask:get 'uri' == uri + then + self._compileTask:fastForward() + else + self:compileVM(uri) + end if obj.vm then self._lastLoadedVM = uri end @@ -638,12 +646,12 @@ function mt:_createCompileTask() message = lang.script.MWS_COMPLETE, }) end - return end - self._compileTask = coroutine.create(function () + self._compileTask = task(function () self:doDiagnostics(self._lastLoadedVM) local uri = self._needCompile[1] if uri then + self._compileTask:set('uri', uri) pcall(function () self:compileVM(uri) end) else uri = next(self._needDiagnostics) @@ -655,29 +663,20 @@ function mt:_createCompileTask() end function mt:_doCompileTask() - if not self._compileTask then + if not self._compileTask or self._compileTask:isRemoved() then self:_createCompileTask() end - if not self._compileTask then - return - end - while self._compileTask do - local suc, res = coroutine.resume(self._compileTask) - if not suc then - self._compileTask = nil - return - end + while true do + local res = self._compileTask:step() if res == 'stop' then - self._compileTask = nil - return + self._compileTask:remove() + break end - if coroutine.status(self._compileTask) == 'suspended' then - self:_loadProto() - else - self._compileTask = nil - return + if self._compileTask:isRemoved() then + break end end + self:_loadProto() end function mt:_loadProto() diff --git a/server/src/task.lua b/server/src/task.lua new file mode 100644 index 00000000..a1ed37de --- /dev/null +++ b/server/src/task.lua @@ -0,0 +1,64 @@ +local mt = {} +mt.__index = mt +mt.type = 'task' + +function mt:remove() + if self._removed then + return + end + self._removed = true +end + +function mt:isRemoved() + return self._removed +end + +function mt:step() + if self._removed then + return + end + local suc, res = coroutine.resume(self.task) + if not suc then + self:remove() + log.error(debug.traceback(self.task, res)) + return + end + if coroutine.status(self.task) == 'dead' then + self:remove() + end + return res +end + +function mt:fastForward() + if self._removed then + return + end + while true do + local suc = coroutine.resume(self.task) + if not suc then + self:remove() + break + end + if coroutine.status(self.task) == 'dead' then + self:remove() + break + end + end +end + +function mt:set(key, value) + self.data[key] = value +end + +function mt:get(key) + return self.data[key] +end + +return function (callback) + local self = setmetatable({ + callback = callback, + data = {}, + task = coroutine.create(callback), + }, mt) + return self +end |