diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2022-10-17 16:38:44 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2022-10-17 16:38:44 +0800 |
commit | bfb576d3eba9f12bb582a9f7e942c5eac387fe2b (patch) | |
tree | d5e3790aeca21994d4b9558453f40657383fcf63 /script | |
parent | 3bdd74aa30a6175f1bbf973559241f99eb563dfe (diff) | |
download | lua-language-server-bfb576d3eba9f12bb582a9f7e942c5eac387fe2b.zip |
use `state` instead of `uri` for converter
The state may have changed when responding, so we need to use the state when requesting.
Try not to get the state on the spot.
Diffstat (limited to 'script')
-rw-r--r-- | script/client.lua | 8 | ||||
-rw-r--r-- | script/core/code-action.lua | 22 | ||||
-rw-r--r-- | script/core/command/jsonToLua.lua | 4 | ||||
-rw-r--r-- | script/core/command/removeSpace.lua | 2 | ||||
-rw-r--r-- | script/core/command/solve.lua | 4 | ||||
-rw-r--r-- | script/core/diagnostics/codestyle-check.lua | 9 | ||||
-rw-r--r-- | script/core/diagnostics/spell-check.lua | 9 | ||||
-rw-r--r-- | script/core/rangeformatting.lua | 10 | ||||
-rw-r--r-- | script/core/semantic-tokens.lua | 10 | ||||
-rw-r--r-- | script/core/type-formatting.lua | 10 | ||||
-rw-r--r-- | script/core/view/psi-select.lua | 2 | ||||
-rw-r--r-- | script/core/view/psi-view.lua | 4 | ||||
-rw-r--r-- | script/files.lua | 43 | ||||
-rw-r--r-- | script/parser/compile.lua | 1 | ||||
-rw-r--r-- | script/proto/converter.lua | 113 | ||||
-rw-r--r-- | script/provider/diagnostic.lua | 29 | ||||
-rw-r--r-- | script/provider/provider.lua | 269 |
17 files changed, 340 insertions, 209 deletions
diff --git a/script/client.lua b/script/client.lua index 7432e60b..1e4689a8 100644 --- a/script/client.lua +++ b/script/client.lua @@ -382,10 +382,14 @@ end ---@param uri uri ---@param edits textEditor[] function m.editText(uri, edits) - local files = require 'files' + local files = require 'files' + local state = files.getState(uri) + if not state then + return + end local textEdits = {} for i, edit in ipairs(edits) do - textEdits[i] = converter.textEdit(converter.packRange(uri, edit.start, edit.finish), edit.text) + textEdits[i] = converter.textEdit(converter.packRange(state, edit.start, edit.finish), edit.text) end proto.request('workspace/applyEdit', { edit = { diff --git a/script/core/code-action.lua b/script/core/code-action.lua index 1e19d466..4f15b335 100644 --- a/script/core/code-action.lua +++ b/script/core/code-action.lua @@ -135,7 +135,7 @@ local function solveUndefinedGlobal(uri, diag, results) if not state then return end - local start = converter.unpackRange(uri, diag.range) + local start = converter.unpackRange(state, diag.range) guide.eachSourceContain(state.ast, start, function (source) if source.type ~= 'getglobal' then return @@ -157,7 +157,7 @@ local function solveLowercaseGlobal(uri, diag, results) if not state then return end - local start = converter.unpackRange(uri, diag.range) + local start = converter.unpackRange(state, diag.range) guide.eachSourceContain(state.ast, start, function (source) if source.type ~= 'setglobal' then return @@ -175,7 +175,7 @@ local function findSyntax(uri, diag) end for _, err in ipairs(state.errs) do if err.type:lower():gsub('_', '-') == diag.code then - local range = converter.packRange(uri, err.start, err.finish) + local range = converter.packRange(state, err.start, err.finish) if util.equal(range, diag.range) then return err end @@ -276,7 +276,11 @@ local function solveSyntax(uri, diag, results) end local function solveNewlineCall(uri, diag, results) - local start = converter.unpackRange(uri, diag.range) + local state = files.getState(uri) + if not state then + return + end + local start = converter.unpackRange(state, diag.range) results[#results+1] = { title = lang.script.ACTION_ADD_SEMICOLON, kind = 'quickfix', @@ -333,7 +337,7 @@ local function solveAwaitInSync(uri, diag, results) if not state then return end - local start, finish = converter.unpackRange(uri, diag.range) + local start, finish = converter.unpackRange(state, diag.range) local parentFunction guide.eachSourceType(state.ast, 'function', function (source) if source.start > finish @@ -369,6 +373,10 @@ local function solveAwaitInSync(uri, diag, results) end local function solveSpell(uri, diag, results) + local state = files.getState(uri) + if not state then + return + end local spell = require 'provider.spell' local word = diag.data if word == nil then @@ -401,8 +409,8 @@ local function solveSpell(uri, diag, results) changes = { [uri] = { { - start = converter.unpackPosition(uri, diag.range.start), - finish = converter.unpackPosition(uri, diag.range["end"]), + start = converter.unpackPosition(state, diag.range.start), + finish = converter.unpackPosition(state, diag.range["end"]), newText = suggest } } diff --git a/script/core/command/jsonToLua.lua b/script/core/command/jsonToLua.lua index 8d9e8ba1..da1aeb4b 100644 --- a/script/core/command/jsonToLua.lua +++ b/script/core/command/jsonToLua.lua @@ -11,7 +11,7 @@ local guide = require 'parser.guide' return function (data) local state = files.getState(data.uri) local text = files.getText(data.uri) - if not text then + if not text or not state then return end local start = guide.positionToOffset(state, data.start) @@ -43,7 +43,7 @@ return function (data) changes = { [data.uri] = { { - range = converter.packRange(data.uri, data.start, data.finish), + range = converter.packRange(state, data.start, data.finish), newText = luaStr, } } diff --git a/script/core/command/removeSpace.lua b/script/core/command/removeSpace.lua index 992a0705..87d11fff 100644 --- a/script/core/command/removeSpace.lua +++ b/script/core/command/removeSpace.lua @@ -38,7 +38,7 @@ return function (data) end local firstPos = guide.offsetToPosition(state, firstOffset) - 1 textEdit[#textEdit+1] = { - range = converter.packRange(uri, firstPos, lastPos), + range = converter.packRange(state, firstPos, lastPos), newText = '', } diff --git a/script/core/command/solve.lua b/script/core/command/solve.lua index 98ceaa58..ca1458aa 100644 --- a/script/core/command/solve.lua +++ b/script/core/command/solve.lua @@ -36,7 +36,7 @@ return function (data) return end - local start, finish = converter.unpackRange(uri, data.range) + local start, finish = converter.unpackRange(state, data.range) local result = guide.eachSourceContain(state.ast, start, function (source) if source.start ~= start @@ -86,7 +86,7 @@ return function (data) changes = { [uri] = { { - range = converter.packRange(uri, result.start, result.finish), + range = converter.packRange(state, result.start, result.finish), newText = ('(%s)'):format(text:sub( guide.positionToOffset(state, result.start + 1), guide.positionToOffset(state, result.finish) diff --git a/script/core/diagnostics/codestyle-check.lua b/script/core/diagnostics/codestyle-check.lua index 6448979d..6d22597b 100644 --- a/script/core/diagnostics/codestyle-check.lua +++ b/script/core/diagnostics/codestyle-check.lua @@ -6,10 +6,11 @@ local pformatting = require 'provider.formatting' ---@async return function(uri, callback) - local text = files.getOriginText(uri) - if not text then + local state = files.getState(uri) + if not state then return end + local text = state.originText local suc, codeFormat = pcall(require, 'code_format') if not suc then @@ -31,8 +32,8 @@ return function(uri, callback) if diagnosticInfos then for _, diagnosticInfo in ipairs(diagnosticInfos) do callback { - start = converter.unpackPosition(uri, diagnosticInfo.range.start), - finish = converter.unpackPosition(uri, diagnosticInfo.range["end"]), + start = converter.unpackPosition(state, diagnosticInfo.range.start), + finish = converter.unpackPosition(state, diagnosticInfo.range["end"]), message = diagnosticInfo.message } end diff --git a/script/core/diagnostics/spell-check.lua b/script/core/diagnostics/spell-check.lua index 7369a235..a4cb87be 100644 --- a/script/core/diagnostics/spell-check.lua +++ b/script/core/diagnostics/spell-check.lua @@ -6,10 +6,11 @@ local spell = require 'provider.spell' ---@async return function(uri, callback) - local text = files.getOriginText(uri) - if not text then + local state = files.getState(uri) + if not state then return end + local text = state.originText local status, diagnosticInfos = spell.spellCheck(uri, text) @@ -24,8 +25,8 @@ return function(uri, callback) if diagnosticInfos then for _, diagnosticInfo in ipairs(diagnosticInfos) do callback { - start = converter.unpackPosition(uri, diagnosticInfo.range.start), - finish = converter.unpackPosition(uri, diagnosticInfo.range["end"]), + start = converter.unpackPosition(state, diagnosticInfo.range.start), + finish = converter.unpackPosition(state, diagnosticInfo.range["end"]), message = diagnosticInfo.message, data = diagnosticInfo.data } diff --git a/script/core/rangeformatting.lua b/script/core/rangeformatting.lua index 04a61bd9..7c3953e6 100644 --- a/script/core/rangeformatting.lua +++ b/script/core/rangeformatting.lua @@ -3,11 +3,15 @@ local log = require("log") local converter = require("proto.converter") return function(uri, range, options) + local state = files.getState(uri) + if not state then + return + end local suc, codeFormat = pcall(require, "code_format") if not suc then return end - local text = files.getOriginText(uri) + local text = state.originText local status, formattedText, startLine, endLine = codeFormat.range_format( uri, text, range.start.line, range["end"].line, options) @@ -21,8 +25,8 @@ return function(uri, range, options) return { { - start = converter.unpackPosition(uri, { line = startLine, character = 0 }), - finish = converter.unpackPosition(uri, { line = endLine + 1, character = 0 }), + start = converter.unpackPosition(state, { line = startLine, character = 0 }), + finish = converter.unpackPosition(state, { line = endLine + 1, character = 0 }), text = formattedText, } } diff --git a/script/core/semantic-tokens.lua b/script/core/semantic-tokens.lua index bc9bf8af..610b3061 100644 --- a/script/core/semantic-tokens.lua +++ b/script/core/semantic-tokens.lua @@ -699,13 +699,15 @@ local Care = util.switch() } end) -local function buildTokens(uri, results) +---@param state table +---@param results table +local function buildTokens(state, results) local tokens = {} local lastLine = 0 local lastStartChar = 0 for i, source in ipairs(results) do - local startPos = converter.packPosition(uri, source.start) - local finishPos = converter.packPosition(uri, source.finish) + local startPos = converter.packPosition(state, source.start) + local finishPos = converter.packPosition(state, source.finish) local line = startPos.line local startChar = startPos.character local deltaLine = line - lastLine @@ -881,7 +883,7 @@ return function (uri, start, finish) results = solveMultilineAndOverlapping(state, results) - local tokens = buildTokens(uri, results) + local tokens = buildTokens(state, results) return tokens end diff --git a/script/core/type-formatting.lua b/script/core/type-formatting.lua index 94edc71b..419cb56b 100644 --- a/script/core/type-formatting.lua +++ b/script/core/type-formatting.lua @@ -199,22 +199,22 @@ local function typeFormat(results, uri, position, ch, options) return end local converter = require("proto.converter") - local pos = converter.packPosition(uri, position) + local pos = converter.packPosition(state, position) local typeFormatOptions = config.get(uri, 'Lua.typeFormat.config') local success, result = codeFormat.type_format(uri, text, pos.line, pos.character, options, typeFormatOptions) if success then local range = result.range results[#results+1] = { text = result.newText, - start = converter.unpackPosition(uri, { line = range.start.line, character = range.start.character }), - finish = converter.unpackPosition(uri, { line = range["end"].line, character = range["end"].character }), + start = converter.unpackPosition(state, { line = range.start.line, character = range.start.character }), + finish = converter.unpackPosition(state, { line = range["end"].line, character = range["end"].character }), } end end return function (uri, position, ch, options) - local ast = files.getState(uri) - if not ast then + local state = files.getState(uri) + if not state then return nil end diff --git a/script/core/view/psi-select.lua b/script/core/view/psi-select.lua index b6733aa5..40642039 100644 --- a/script/core/view/psi-select.lua +++ b/script/core/view/psi-select.lua @@ -8,6 +8,6 @@ return function(uri, position) return end - local pos = converter.unpackPosition(uri, position) + local pos = converter.unpackPosition(state, position) return { data = guide.positionToOffset(state, pos) } end diff --git a/script/core/view/psi-view.lua b/script/core/view/psi-view.lua index 86ed1403..640d1c4c 100644 --- a/script/core/view/psi-view.lua +++ b/script/core/view/psi-view.lua @@ -27,8 +27,8 @@ local function toPsiNode(astNode, state) local startOffset = guide.positionToOffset(state, astNode.start) local finishOffset = guide.positionToOffset(state, astNode.finish) - local startPosition = converter.packPosition(state.uri, astNode.start) - local finishPosition = converter.packPosition(state.uri, astNode.finish) + local startPosition = converter.packPosition(state, astNode.start) + local finishPosition = converter.packPosition(state, astNode.finish) return { name = string.format("%s@[%d:%d .. %d:%d]", astNode.type, diff --git a/script/files.lua b/script/files.lua index 545c6735..d7a7b16b 100644 --- a/script/files.lua +++ b/script/files.lua @@ -593,9 +593,14 @@ function m.compileState(uri, text) end end +---@class parser.state +---@field _diffInfo? table[] +---@field originLines? integer[] +---@field originText string + --- 获取文件语法树 ---@param uri uri ----@return table? state +---@return parser.state? state function m.getState(uri) local file = m.fileMap[uri] if not file then @@ -606,6 +611,9 @@ function m.getState(uri) state = m.compileState(uri, file.text) m.astMap[uri] = state file.state = state + state._diffInfo = file._diffInfo + state.originLines = file.originLines + state.originText = file.originText --await.delay() end file.cacheActiveTime = timer.clock() @@ -637,43 +645,32 @@ local function isNameChar(text) end --- 将应用差异前的offset转换为应用差异后的offset ----@param uri uri +---@param state parser.state ---@param offset integer ---@return integer start ---@return integer finish -function m.diffedOffset(uri, offset) - local file = m.getFile(uri) - if not file then +function m.diffedOffset(state, offset) + if not state._diffInfo then return offset, offset end - if not file._diffInfo then - return offset, offset - end - return smerger.getOffset(file._diffInfo, offset) + return smerger.getOffset(state._diffInfo, offset) end --- 将应用差异后的offset转换为应用差异前的offset ----@param uri uri +---@param state parser.state ---@param offset integer ---@return integer start ---@return integer finish -function m.diffedOffsetBack(uri, offset) - local file = m.getFile(uri) - if not file then +function m.diffedOffsetBack(state, offset) + if not state._diffInfo then return offset, offset end - if not file._diffInfo then - return offset, offset - end - return smerger.getOffsetBack(file._diffInfo, offset) + return smerger.getOffsetBack(state._diffInfo, offset) end -function m.hasDiffed(uri) - local file = m.getFile(uri) - if not file then - return false - end - return file._diffInfo ~= nil +---@param state parser.state +function m.hasDiffed(state) + return state._diffInfo ~= nil end --- 获取文件的自定义缓存信息(在文件内容更新后自动失效) diff --git a/script/parser/compile.lua b/script/parser/compile.lua index 45678976..12d80f7e 100644 --- a/script/parser/compile.lua +++ b/script/parser/compile.lua @@ -3818,6 +3818,7 @@ local function initState(lua, version, options) Index = 1 ---@class parser.state ---@field uri uri + ---@field lines integer[] local state = { version = version, lua = lua, diff --git a/script/proto/converter.lua b/script/proto/converter.lua index 56b45c1f..d761042c 100644 --- a/script/proto/converter.lua +++ b/script/proto/converter.lua @@ -8,11 +8,23 @@ local m = {} ---@alias position {line: integer, character: integer} -local function rawPackPosition(uri, pos) +---@param row integer +---@param col integer +---@return position +function m.position(row, col) + return { + line = row, + character = col, + } +end + +---@param state parser.state +---@param pos integer +---@return position +local function rawPackPosition(state, pos) local row, col = guide.rowColOf(pos) if col > 0 then - local state = files.getState(uri) - local text = files.getText(uri) + local text = state.lua if state and text then local lineOffset = state.lines[row] if lineOffset then @@ -32,17 +44,18 @@ local function rawPackPosition(uri, pos) } end -local function diffedPackPosition(uri, pos) - local state = files.getState(uri) +---@param state parser.state +---@param pos integer +---@return position +local function diffedPackPosition(state, pos) local offset = guide.positionToOffset(state, pos) - local originOffset = files.diffedOffsetBack(uri, offset) - local originLines = files.getOriginLines(uri) - local originPos = guide.offsetToPositionByLines(originLines, originOffset) + local originOffset = files.diffedOffsetBack(state, offset) + local originPos = guide.offsetToPositionByLines(state.originLines, originOffset) local row, col = guide.rowColOf(originPos) if col > 0 then - local text = files.getOriginText(uri) + local text = state.originText if text then - local lineOffset = originLines[row] + local lineOffset = state.originLines[row] local finalOffset = math.min(lineOffset + col - 1, #text + 1) col = encoder.len(offsetEncoding, text, lineOffset, finalOffset) end @@ -53,22 +66,24 @@ local function diffedPackPosition(uri, pos) } end ----@param uri uri +---@param state parser.state ---@param pos integer ---@return position -function m.packPosition(uri, pos) - if files.hasDiffed(uri) then - return diffedPackPosition(uri, pos) +function m.packPosition(state, pos) + if files.hasDiffed(state) then + return diffedPackPosition(state, pos) else - return rawPackPosition(uri, pos) + return rawPackPosition(state, pos) end end -local function rawUnpackPosition(uri, position) +---@param state parser.state +---@param position position +---@return integer +local function rawUnpackPosition(state, position) local row, col = position.line, position.character if col > 0 then - local state = files.getState(uri) - local text = files.getText(uri) + local text = state.lua if state and text then local lineOffset = state.lines[row] local textOffset = encoder.offset(offsetEncoding, text, col + 1, lineOffset) @@ -81,61 +96,69 @@ local function rawUnpackPosition(uri, position) return pos end -local function diffedUnpackPosition(uri, position) - local row, col = position.line, position.character - local originLines = files.getOriginLines(uri) +---@param state parser.state +---@param position position +---@return integer +local function diffedUnpackPosition(state, position) + local row, col = position.line, position.character if col > 0 then - local text = files.getOriginText(uri) - if text then - local lineOffset = originLines[row] - if lineOffset then - local textOffset = encoder.offset(offsetEncoding, text, col + 1, lineOffset) - if textOffset and lineOffset then - col = textOffset - lineOffset - end + local lineOffset = state.originLines[row] + if lineOffset then + local textOffset = encoder.offset(offsetEncoding, state.originText, col + 1, lineOffset) + if textOffset and lineOffset then + col = textOffset - lineOffset end end end - local state = files.getState(uri) local originPos = guide.positionOf(row, col) - local originOffset = guide.positionToOffsetByLines(originLines, originPos) - local offset = files.diffedOffset(uri, originOffset) + local originOffset = guide.positionToOffsetByLines(state.originLines, originPos) + local offset = files.diffedOffset(state, originOffset) local pos = guide.offsetToPosition(state, offset) return pos end ----@param uri uri +---@param state parser.state ---@param position position ---@return integer -function m.unpackPosition(uri, position) - if files.hasDiffed(uri) then - return diffedUnpackPosition(uri, position) +function m.unpackPosition(state, position) + if files.hasDiffed(state) then + return diffedUnpackPosition(state, position) else - return rawUnpackPosition(uri, position) + return rawUnpackPosition(state, position) end end ---@alias range {start: position, end: position} ----@param uri uri +---@param state parser.state ---@param start integer ---@param finish integer ---@return range -function m.packRange(uri, start, finish) +function m.packRange(state, start, finish) local range = { - start = m.packPosition(uri, start), - ['end'] = m.packPosition(uri, finish), + start = m.packPosition(state, start), + ['end'] = m.packPosition(state, finish), } return range end ----@param uri uri +---@param start position +---@param finish position +---@return range +function m.range(start, finish) + return { + start = start, + ['end'] = finish, + } +end + +---@param state parser.state ---@param range range ---@return integer start ---@return integer finish -function m.unpackRange(uri, range) - local start = m.unpackPosition(uri, range.start) - local finish = m.unpackPosition(uri, range['end']) +function m.unpackRange(state, range) + local start = m.unpackPosition(state, range.start) + local finish = m.unpackPosition(state, range['end']) return start, finish end diff --git a/script/provider/diagnostic.lua b/script/provider/diagnostic.lua index 58179514..149e409f 100644 --- a/script/provider/diagnostic.lua +++ b/script/provider/diagnostic.lua @@ -32,8 +32,9 @@ local function concat(t, sep) end local function buildSyntaxError(uri, err) - local text = files.getText(uri) - if not text then + local state = files.getState(uri) + local text = files.getText(uri) + if not text or not state then return end local message = lang.script('PARSER_' .. err.type, err.info) @@ -58,16 +59,19 @@ local function buildSyntaxError(uri, err) rmessage = text:sub(rel.start, rel.finish) end local relUri = rel.uri or uri - relatedInformation[#relatedInformation+1] = { - message = rmessage, - location = converter.location(relUri, converter.packRange(relUri, rel.start, rel.finish)), - } + local relState = files.getState(relUri) + if relState then + relatedInformation[#relatedInformation+1] = { + message = rmessage, + location = converter.location(relUri, converter.packRange(relState, rel.start, rel.finish)), + } + end end end return { code = err.type:lower():gsub('_', '-'), - range = converter.packRange(uri, err.start, err.finish), + range = converter.packRange(state, err.start, err.finish), severity = define.DiagnosticSeverity[err.level], source = lang.script.DIAG_SYNTAX_CHECK, message = message, @@ -78,7 +82,8 @@ local function buildSyntaxError(uri, err) end local function buildDiagnostic(uri, diag) - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return end @@ -90,16 +95,20 @@ local function buildDiagnostic(uri, diag) if not rtext then goto CONTINUE end + local relState = files.getState(rel.uri) + if not relState then + goto CONTINUE + end relatedInformation[#relatedInformation+1] = { message = rel.message or rtext:sub(rel.start, rel.finish), - location = converter.location(rel.uri, converter.packRange(rel.uri, rel.start, rel.finish)) + location = converter.location(rel.uri, converter.packRange(relState, rel.start, rel.finish)) } ::CONTINUE:: end end return { - range = converter.packRange(uri, diag.start, diag.finish), + range = converter.packRange(state, diag.start, diag.finish), source = lang.script.DIAG_DIAGNOSTICS, severity = diag.level, message = diag.message, diff --git a/script/provider/provider.lua b/script/provider/provider.lua index 517ef54e..fb16c2c6 100644 --- a/script/provider/provider.lua +++ b/script/provider/provider.lua @@ -335,10 +335,11 @@ m.register 'textDocument/hover' { end local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_HOVER, 0.5) local core = require 'core.hover' - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local hover, source = core.byUri(uri, pos) if not hover or not source then return nil @@ -348,7 +349,7 @@ m.register 'textDocument/hover' { value = tostring(hover), kind = 'markdown', }, - range = converter.packRange(uri, source.start, source.finish), + range = converter.packRange(state, source.start, source.finish), } end } @@ -362,29 +363,42 @@ m.register 'textDocument/definition' { function (params) local uri = files.getRealUri(params.textDocument.uri) workspace.awaitReady(uri) - if not files.exists(uri) then + local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_DEFINITION, 0.5) + local state = files.getState(uri) + if not state then return nil end - local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_DEFINITION, 0.5) local core = require 'core.definition' - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local result = core(uri, pos) if not result then return nil end local response = {} for i, info in ipairs(result) do + ---@type uri local targetUri = info.uri if targetUri then - if client.getAbility 'textDocument.definition.linkSupport' then - response[i] = converter.locationLink(targetUri - , converter.packRange(targetUri, info.target.start, info.target.finish) - , converter.packRange(targetUri, info.target.start, info.target.finish) - , converter.packRange(uri, info.source.start, info.source.finish) - ) + local targetState = files.getState(targetUri) + if targetState then + if client.getAbility 'textDocument.definition.linkSupport' then + response[i] = converter.locationLink(targetUri + , converter.packRange(targetState, info.target.start, info.target.finish) + , converter.packRange(targetState, info.target.start, info.target.finish) + , converter.packRange(state, info.source.start, info.source.finish) + ) + else + response[i] = converter.location(targetUri + , converter.packRange(targetState, info.target.start, info.target.finish) + ) + end else - response[i] = converter.location(targetUri - , converter.packRange(targetUri, info.target.start, info.target.finish) + response[i] = converter.location( + targetUri, + converter.range( + converter.position(guide.rowColOf(info.target.start)), + converter.position(guide.rowColOf(info.target.finish)) + ) ) end end @@ -402,30 +416,35 @@ m.register 'textDocument/typeDefinition' { function (params) local uri = files.getRealUri(params.textDocument.uri) workspace.awaitReady(uri) - if not files.exists(uri) then - return nil - end local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_TYPE_DEFINITION, 0.5) + local state = files.getState(uri) + if not state then + return + end local core = require 'core.type-definition' - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local result = core(uri, pos) if not result then return nil end local response = {} for i, info in ipairs(result) do + ---@type uri local targetUri = info.uri if targetUri then - if client.getAbility 'textDocument.typeDefinition.linkSupport' then - response[i] = converter.locationLink(targetUri - , converter.packRange(targetUri, info.target.start, info.target.finish) - , converter.packRange(targetUri, info.target.start, info.target.finish) - , converter.packRange(uri, info.source.start, info.source.finish) - ) - else - response[i] = converter.location(targetUri - , converter.packRange(targetUri, info.target.start, info.target.finish) - ) + local targetState = files.getState(targetUri) + if targetState then + if client.getAbility 'textDocument.typeDefinition.linkSupport' then + response[i] = converter.locationLink(targetUri + , converter.packRange(targetState, info.target.start, info.target.finish) + , converter.packRange(targetState, info.target.start, info.target.finish) + , converter.packRange(state, info.source.start, info.source.finish) + ) + else + response[i] = converter.location(targetUri + , converter.packRange(targetState, info.target.start, info.target.finish) + ) + end end end end @@ -442,22 +461,27 @@ m.register 'textDocument/references' { function (params) local uri = files.getRealUri(params.textDocument.uri) workspace.awaitReady(uri) - if not files.exists(uri) then + local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_REFERENCE, 0.5) + local state = files.getState(uri) + if not state then return nil end - local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_REFERENCE, 0.5) local core = require 'core.reference' - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local result = core(uri, pos) if not result then return nil end local response = {} for i, info in ipairs(result) do + ---@type uri local targetUri = info.uri - response[i] = converter.location(targetUri - , converter.packRange(targetUri, info.target.start, info.target.finish) - ) + local targetState = files.getState(targetUri) + if targetState then + response[#response+1] = converter.location(targetUri + , converter.packRange(targetState, info.target.start, info.target.finish) + ) + end end return response end @@ -472,10 +496,11 @@ m.register 'textDocument/documentHighlight' { local core = require 'core.highlight' local uri = files.getRealUri(params.textDocument.uri) workspace.awaitReady(uri) - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local result = core(uri, pos) if not result then return nil @@ -483,7 +508,7 @@ m.register 'textDocument/documentHighlight' { local response = {} for _, info in ipairs(result) do response[#response+1] = { - range = converter.packRange(uri, info.start, info.finish), + range = converter.packRange(state, info.start, info.finish), kind = info.kind, } end @@ -502,12 +527,13 @@ m.register 'textDocument/rename' { function (params) local uri = files.getRealUri(params.textDocument.uri) workspace.awaitReady(uri) - if not files.exists(uri) then + local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_RENAME, 0.5) + local state = files.getState(uri) + if not state then return nil end - local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_RENAME, 0.5) local core = require 'core.rename' - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local result = core.rename(uri, pos, params.newName) if not result then return nil @@ -516,12 +542,16 @@ m.register 'textDocument/rename' { changes = {}, } for _, info in ipairs(result) do - local ruri = info.uri - if not workspaceEdit.changes[ruri] then - workspaceEdit.changes[ruri] = {} + ---@type uri + local ruri = info.uri + local rstate = files.getState(ruri) + if rstate then + if not workspaceEdit.changes[ruri] then + workspaceEdit.changes[ruri] = {} + end + local textEdit = converter.textEdit(converter.packRange(rstate, info.start, info.finish), info.text) + workspaceEdit.changes[ruri][#workspaceEdit.changes[ruri]+1] = textEdit end - local textEdit = converter.textEdit(converter.packRange(ruri, info.start, info.finish), info.text) - workspaceEdit.changes[ruri][#workspaceEdit.changes[ruri]+1] = textEdit end return workspaceEdit end @@ -532,16 +562,17 @@ m.register 'textDocument/prepareRename' { function (params) local core = require 'core.rename' local uri = files.getRealUri(params.textDocument.uri) - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local result = core.prepareRename(uri, pos) if not result then return nil end return { - range = converter.packRange(uri, result.start, result.finish), + range = converter.packRange(state, result.start, result.finish), placeholder = result.text, } end @@ -571,8 +602,9 @@ m.register 'textDocument/completion' { local core = require 'core.completion' --log.debug('textDocument/completion') --log.debug('completion:', params.context and params.context.triggerKind, params.context and params.context.triggerCharacter) - if not files.exists(uri) then - return nil + local state = files.getState(uri) + if not state then + return end local triggerCharacter = params.context and params.context.triggerCharacter if config.get(uri, 'editor.acceptSuggestionOnEnter') ~= 'off' then @@ -584,7 +616,7 @@ m.register 'textDocument/completion' { end --await.setPriority(1000) local clock = os.clock() - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local result = core.completion(uri, pos, triggerCharacter) local passed = os.clock() - clock if passed > 0.1 then @@ -611,7 +643,7 @@ m.register 'textDocument/completion' { command = res.command, textEdit = res.textEdit and { range = converter.packRange( - uri, + state, res.textEdit.start, res.textEdit.finish ), @@ -622,7 +654,7 @@ m.register 'textDocument/completion' { for j, edit in ipairs(res.additionalTextEdits) do t[j] = { range = converter.packRange( - uri, + state, edit.start, edit.finish ), @@ -676,6 +708,10 @@ m.register 'completionItem/resolve' { local id = item.data.id local uri = item.data.uri --await.setPriority(1000) + local state = files.getState(uri) + if not state then + return nil + end local resolved = core.resolve(id) if not resolved then return nil @@ -690,7 +726,7 @@ m.register 'completionItem/resolve' { for j, edit in ipairs(resolved.additionalTextEdits) do t[j] = { range = converter.packRange( - uri, + state, edit.start, edit.finish ), @@ -717,11 +753,12 @@ m.register 'textDocument/signatureHelp' { return nil end workspace.awaitReady(uri) - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_SIGNATURE, 0.5) - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local core = require 'core.signature' local results = core(uri, pos) if not results then @@ -764,7 +801,10 @@ m.register 'textDocument/documentSymbol' { local uri = files.getRealUri(params.textDocument.uri) workspace.awaitReady(uri) local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_SYMBOL, 0.5) - + local state = files.getState(uri) + if not state then + return nil + end local core = require 'core.document-symbol' local symbols = core(uri) if not symbols then @@ -775,12 +815,12 @@ m.register 'textDocument/documentSymbol' { local function convert(symbol) await.delay() symbol.range = converter.packRange( - uri, + state, symbol.range[1], symbol.range[2] ) symbol.selectionRange = converter.packRange( - uri, + state, symbol.selectionRange[1], symbol.selectionRange[2] ) @@ -821,11 +861,13 @@ m.register 'textDocument/codeAction' { local uri = files.getRealUri(params.textDocument.uri) local range = params.range local diagnostics = params.context.diagnostics - if not files.exists(uri) then + + local state = files.getState(uri) + if not state then return nil end - local start, finish = converter.unpackRange(uri, range) + local start, finish = converter.unpackRange(state, range) local results = core(uri, start, finish, diagnostics) if not results or #results == 0 then @@ -834,11 +876,15 @@ m.register 'textDocument/codeAction' { for _, res in ipairs(results) do if res.edit then + ---@param turi uri for turi, changes in pairs(res.edit.changes) do - for _, change in ipairs(changes) do - change.range = converter.packRange(turi, change.start, change.finish) - change.start = nil - change.finish = nil + local tstate = files.getState(turi) + if tstate then + for _, change in ipairs(changes) do + change.range = converter.packRange(tstate, change.start, change.finish) + change.start = nil + change.finish = nil + end end end end @@ -898,22 +944,31 @@ m.register 'workspace/symbol' { end local function convert(symbol) - symbol.location = converter.location( - symbol.uri, - converter.packRange( + local state = files.getState(symbol.uri) + if not state then + return nil + end + return { + name = symbol.name, + kind = symbol.kind, + location = converter.location( symbol.uri, - symbol.range[1], - symbol.range[2] + converter.packRange( + state, + symbol.range[1], + symbol.range[2] + ) ) - ) - symbol.uri = nil + } end + local results = {} + for _, symbol in ipairs(symbols) do - convert(symbol) + results[#results+1] = convert(symbol) end - return symbols + return results end } @@ -978,8 +1033,12 @@ m.register 'textDocument/semanticTokens/range' { workspace.awaitReady(uri) local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_SEMANTIC_RANGE, 0.5) await.sleep(0.0) + local state = files.getState(uri) + if not state then + return nil + end local core = require 'core.semantic-tokens' - local start, finish = converter.unpackRange(uri, params.range) + local start, finish = converter.unpackRange(state, params.range) local results = core(uri, start, finish) return { data = results @@ -999,6 +1058,10 @@ m.register 'textDocument/foldingRange' { if not files.exists(uri) then return nil end + local state = files.getState(uri) + if not state then + return nil + end local regions = core(uri) if not regions then return nil @@ -1006,8 +1069,8 @@ m.register 'textDocument/foldingRange' { local results = {} for _, region in ipairs(regions) do - local startLine = converter.packPosition(uri, region.start).line - local endLine = converter.packPosition(uri, region.finish).line + local startLine = converter.packPosition(state, region.start).line + local endLine = converter.packPosition(state, region.finish).line if not region.hideLastLine then endLine = endLine - 1 end @@ -1033,7 +1096,8 @@ m.register 'textDocument/documentColor' { local color = require 'core.color' local uri = files.getRealUri(params.textDocument.uri) workspace.awaitReady(uri) - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end local colors = color.colors(uri) @@ -1043,7 +1107,7 @@ m.register 'textDocument/documentColor' { local results = {} for _, colorValue in ipairs(colors) do results[#results+1] = { - range = converter.packRange(uri, colorValue.start, colorValue.finish), + range = converter.packRange(state, colorValue.start, colorValue.finish), color = colorValue.color } end @@ -1103,7 +1167,8 @@ m.register 'textDocument/formatting' { function(params) local uri = files.getRealUri(params.textDocument.uri) - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end @@ -1123,7 +1188,7 @@ m.register 'textDocument/formatting' { local results = {} for i, edit in ipairs(edits) do results[i] = { - range = converter.packRange(uri, edit.start, edit.finish), + range = converter.packRange(state, edit.start, edit.finish), newText = edit.text, } end @@ -1140,7 +1205,8 @@ m.register 'textDocument/rangeFormatting' { function(params) local uri = files.getRealUri(params.textDocument.uri) - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end @@ -1160,7 +1226,7 @@ m.register 'textDocument/rangeFormatting' { local results = {} for i, edit in ipairs(edits) do results[i] = { - range = converter.packRange(uri, edit.start, edit.finish), + range = converter.packRange(state, edit.start, edit.finish), newText = edit.text, } end @@ -1183,11 +1249,12 @@ m.register 'textDocument/onTypeFormatting' { workspace.awaitReady(uri) local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_TYPE_FORMATTING, 0.5) local ch = params.ch - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end local core = require 'core.type-formatting' - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local edits = core(uri, pos, ch, params.options) if not edits or #edits == 0 then return nil @@ -1199,7 +1266,7 @@ m.register 'textDocument/onTypeFormatting' { local results = {} for i, edit in ipairs(edits) do results[i] = { - range = converter.packRange(uri, edit.start, edit.finish), + range = converter.packRange(state, edit.start, edit.finish), newText = edit.text:gsub('\t', tab), } end @@ -1221,14 +1288,18 @@ m.register '$/requestHint' { return end workspace.awaitReady(uri) + local state = files.getState(uri) + if not state then + return + end local core = require 'core.hint' - local start, finish = converter.unpackRange(uri, params.range) + local start, finish = converter.unpackRange(state, params.range) local results = core(uri, start, finish) local hintResults = {} for i, res in ipairs(results) do hintResults[i] = { text = res.text, - pos = converter.packPosition(uri, res.offset), + pos = converter.packPosition(state, res.offset), kind = res.kind, } end @@ -1246,34 +1317,44 @@ m.register 'textDocument/inlayHint' { function (params) local uri = files.getRealUri(params.textDocument.uri) if not config.get(uri, 'Lua.hint.enable') then - return + return nil end workspace.awaitReady(uri) local core = require 'core.hint' - local start, finish = converter.unpackRange(uri, params.range) + local state = files.getState(uri) + if not state then + return nil + end + local start, finish = converter.unpackRange(state, params.range) local results = core(uri, start, finish) local hintResults = {} for i, res in ipairs(results) do - hintResults[i] = { + local luri = guide.getUri(res.source) + local lstate = files.getState(luri) + if not lstate then + goto CONTINUE + end + hintResults[#hintResults+1] = { label = { { value = res.text, tooltip = res.tooltip, location = res.source and converter.location( - guide.getUri(res.source), + luri, converter.packRange( - guide.getUri(res.source), + lstate, res.source.start, res.source.finish ) ), }, }, - position = converter.packPosition(uri, res.offset), + position = converter.packPosition(lstate, res.offset), kind = res.kind, paddingLeft = true, paddingRight = true, } + ::CONTINUE:: end return hintResults end |