From 489fcbaa9da91ac8275a2ba5dadc6bd88b9cd5ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Fri, 22 Jan 2021 10:58:43 +0800 Subject: clean up code --- script/core/code-action.lua | 18 ++---- script/core/command/removeSpace.lua | 2 +- script/core/command/solve.lua | 6 +- script/files.lua | 112 ++++++++++++++++++++++++++++++++++++ script/proto/define.lua | 97 ------------------------------- script/provider/diagnostic.lua | 9 ++- script/provider/provider.lua | 110 ++++++++++++----------------------- 7 files changed, 162 insertions(+), 192 deletions(-) diff --git a/script/core/code-action.lua b/script/core/code-action.lua index 2a0d9907..dfd935c5 100644 --- a/script/core/code-action.lua +++ b/script/core/code-action.lua @@ -65,9 +65,7 @@ end local function solveUndefinedGlobal(uri, diag, results) local ast = files.getAst(uri) - local text = files.getText(uri) - local lines = files.getLines(uri) - local offset = define.offsetOfWord(lines, text, diag.range.start) + local offset = files.offsetOfWord(uri, diag.range.start) guide.eachSourceContain(ast.ast, offset, function (source) if source.type ~= 'getglobal' then return @@ -86,9 +84,7 @@ end local function solveLowercaseGlobal(uri, diag, results) local ast = files.getAst(uri) - local text = files.getText(uri) - local lines = files.getLines(uri) - local offset = define.offsetOfWord(lines, text, diag.range.start) + local offset = files.offsetOfWord(uri, diag.range.start) guide.eachSourceContain(ast.ast, offset, function (source) if source.type ~= 'setglobal' then return @@ -100,12 +96,10 @@ local function solveLowercaseGlobal(uri, diag, results) end local function findSyntax(uri, diag) - local ast = files.getAst(uri) - local text = files.getText(uri) - local lines = files.getLines(uri) + local ast = files.getAst(uri) for _, err in ipairs(ast.errs) do if err.type:lower():gsub('_', '-') == diag.code then - local range = define.range(lines, text, err.start, err.finish) + local range = files.range(uri, err.start, err.finish) if util.equal(range, diag.range) then return err end @@ -205,9 +199,7 @@ local function solveSyntax(uri, diag, results) end local function solveNewlineCall(uri, diag, results) - local text = files.getText(uri) - local lines = files.getLines(uri) - local start = define.unrange(lines, text, diag.range) + local start = files.unrange(uri, diag.range) results[#results+1] = { title = lang.script.ACTION_ADD_SEMICOLON, kind = 'quickfix', diff --git a/script/core/command/removeSpace.lua b/script/core/command/removeSpace.lua index e8b09932..29513951 100644 --- a/script/core/command/removeSpace.lua +++ b/script/core/command/removeSpace.lua @@ -32,7 +32,7 @@ return function (data) goto NEXT_LINE end textEdit[#textEdit+1] = { - range = define.range(lines, text, start, finish), + range = files.range(uri, start, finish), newText = '', } goto NEXT_LINE diff --git a/script/core/command/solve.lua b/script/core/command/solve.lua index d3b8f94e..ff14bf40 100644 --- a/script/core/command/solve.lua +++ b/script/core/command/solve.lua @@ -35,8 +35,8 @@ return function (data) return end - local start = define.offsetOfWord(lines, text, data.range.start) - local finish = define.offsetOfWord(lines, text, data.range['end']) + local start = files.offsetOfWord(uri, data.range.start) + local finish = files.offsetOfWord(uri, data.range['end']) local result = guide.eachSourceContain(ast.ast, start, function (source) if source.start ~= start @@ -86,7 +86,7 @@ return function (data) changes = { [uri] = { { - range = define.range(lines, text, result.start, result.finish), + range = files.range(uri, result.start, result.finish), newText = ('(%s)'):format(text:sub(result.start, result.finish)), } }, diff --git a/script/files.lua b/script/files.lua index 48a5b58b..d5ff5981 100644 --- a/script/files.lua +++ b/script/files.lua @@ -9,6 +9,7 @@ local await = require 'await' local timer = require 'timer' local plugin = require 'plugin' local util = require 'utility' +local guide = require 'parser.guide' local m = {} @@ -364,6 +365,117 @@ function m.getUri(uri) return uri end +---@alias position table + +--- 获取 position 对应的光标位置 +---@param uri uri +---@param position position +---@return integer +function m.offset(uri, position) + local lines = m.getLines(uri) + local text = m.getText(uri) + if not lines then + return 0 + end + local row = position.line + 1 + local start = guide.lineRange(lines, row) + if start <= 0 or start > #text then + return #text + 1 + end + local offset = utf8.offset(text, position.character + 1, start) or (#text + 1) + return offset - 1 +end + +--- 获取 position 对应的光标位置(根据附近的单词) +---@param uri uri +---@param position position +---@return integer +function m.offsetOfWord(uri, position) + local lines = m.getLines(uri) + local text = m.getText(uri) + if not lines then + return 0 + end + local row = position.line + 1 + local start = guide.lineRange(lines, row) + if start <= 0 or start > #text then + return #text + 1 + end + local offset = utf8.offset(text, position.character + 1, start) or (#text + 1) + if offset > #text + or text:sub(offset-1, offset):match '[%w_][^%w_]' then + offset = offset - 1 + end + return offset +end + +--- 将光标位置转化为 position +---@param uri uri +---@param offset integer +---@return position +function m.position(uri, offset) + local lines = m.getLines(uri) + local text = m.getText(uri) + if not lines then + return { + line = 0, + character = 0, + } + end + local row, col = guide.positionOf(lines, offset) + local start, finish = guide.lineRange(lines, row, true) + if start < 1 then + start = 1 + end + if col <= finish - start + 1 then + local ucol = util.utf8Len(text, start, start + col - 1) + if row < 1 then + row = 1 + end + return { + line = row - 1, + character = ucol, + } + elseif col == 1 then + return { + line = row - 1, + character = 0, + } + else + return { + line = row, + character = 0, + } + end +end + +--- 将起点与终点位置转化为 range +---@alias range table +---@param uri uri +---@param offset1 integer +---@param offset2 integer +function m.range(uri, offset1, offset2) + local range = { + start = m.position(uri, offset1), + ['end'] = m.position(uri, offset2), + } + if range.start.character > 0 then + range.start.character = range.start.character - 1 + end + return range +end + +--- convert `range` to `offsetStart` and `offsetFinish` +---@param uri table +---@param range table +---@return integer start +---@return integer finish +function m.unrange(uri, range) + local start = m.offset(uri, range.start) + local finish = m.offset(uri, range['end']) + return start, finish +end + --- 获取文件的自定义缓存信息(在文件内容更新后自动失效) function m.getCache(uri) uri = getUriKey(uri) diff --git a/script/proto/define.lua b/script/proto/define.lua index 920571af..c4cffe14 100644 --- a/script/proto/define.lua +++ b/script/proto/define.lua @@ -3,103 +3,6 @@ local util = require 'utility' local m = {} ---- 获取 position 对应的光标位置 ----@param lines table ----@param text string ----@param position position ----@return integer -function m.offset(lines, text, position) - local row = position.line + 1 - local start = guide.lineRange(lines, row) - if start <= 0 or start > #text then - return #text + 1 - end - local offset = utf8.offset(text, position.character + 1, start) or (#text + 1) - return offset - 1 -end - ---- 获取 position 对应的光标位置(根据附近的单词) ----@param lines table ----@param text string ----@param position position ----@return integer -function m.offsetOfWord(lines, text, position) - local row = position.line + 1 - local start = guide.lineRange(lines, row) - if start <= 0 or start > #text then - return #text + 1 - end - local offset = utf8.offset(text, position.character + 1, start) or (#text + 1) - if offset > #text - or text:sub(offset-1, offset):match '[%w_][^%w_]' then - offset = offset - 1 - end - return offset -end - ---- 将光标位置转化为 position ----@alias position table ----@param lines table ----@param text string ----@param offset integer ----@return position -function m.position(lines, text, offset) - local row, col = guide.positionOf(lines, offset) - local start, finish = guide.lineRange(lines, row, true) - if start < 1 then - start = 1 - end - if col <= finish - start + 1 then - local ucol = util.utf8Len(text, start, start + col - 1) - if row < 1 then - row = 1 - end - return { - line = row - 1, - character = ucol, - } - elseif col == 1 then - return { - line = row - 1, - character = 0, - } - else - return { - line = row, - character = 0, - } - end -end - ---- 将起点与终点位置转化为 range ----@alias range table ----@param lines table ----@param text string ----@param offset1 integer ----@param offset2 integer -function m.range(lines, text, offset1, offset2) - local range = { - start = m.position(lines, text, offset1), - ['end'] = m.position(lines, text, offset2), - } - if range.start.character > 0 then - range.start.character = range.start.character - 1 - end - return range -end - ---- convert `range` to `offsetStart` and `offsetFinish` ----@param lines table ----@param text string ----@param range table ----@return integer start ----@return integer finish -function m.unrange(lines, text, range) - local start = m.offset(lines, text, range.start) - local finish = m.offset(lines, text, range['end']) - return start, finish -end - ---@alias location table ---@param uri string ---@param range range diff --git a/script/provider/diagnostic.lua b/script/provider/diagnostic.lua index acea679a..9be9f87a 100644 --- a/script/provider/diagnostic.lua +++ b/script/provider/diagnostic.lua @@ -46,14 +46,14 @@ local function buildSyntaxError(uri, err) end relatedInformation[#relatedInformation+1] = { message = rmessage, - location = define.location(uri, define.range(lines, text, rel.start, rel.finish)), + location = define.location(uri, files.range(uri, rel.start, rel.finish)), } end end return { code = err.type:lower():gsub('_', '-'), - range = define.range(lines, text, err.start, err.finish), + range = files.range(uri, err.start, err.finish), severity = define.DiagnosticSeverity.Error, source = lang.script.DIAG_SYNTAX_CHECK, message = message, @@ -73,16 +73,15 @@ local function buildDiagnostic(uri, diag) relatedInformation = {} for _, rel in ipairs(diag.related) do local rtext = files.getText(rel.uri) - local rlines = files.getLines(rel.uri) relatedInformation[#relatedInformation+1] = { message = rel.message or rtext:sub(rel.start, rel.finish), - location = define.location(rel.uri, define.range(rlines, rtext, rel.start, rel.finish)) + location = define.location(rel.uri, files.range(rel.uri, rel.start, rel.finish)) } end end return { - range = define.range(lines, text, diag.start, diag.finish), + range = files.range(uri, 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 bc6694f4..ef300e02 100644 --- a/script/provider/provider.lua +++ b/script/provider/provider.lua @@ -191,8 +191,7 @@ proto.on('textDocument/didChange', function (params) local text = files.getOriginText(uri) or '' for _, change in ipairs(changes) do if change.range then - local lines = files.getLines(uri) - local start, finish = define.unrange(lines, text, change.range) + local start, finish = files.unrange(uri, change.range) text = text:sub(1, start) .. change.text .. text:sub(finish + 1) else text = change.text @@ -210,9 +209,7 @@ proto.on('textDocument/hover', function (params) if not files.exists(uri) then return nil end - local lines = files.getLines(uri) - local text = files.getText(uri) - local offset = define.offsetOfWord(lines, text, params.position) + local offset = files.offsetOfWord(uri, params.position) local hover = core.byUri(uri, offset) if not hover then return nil @@ -229,7 +226,7 @@ proto.on('textDocument/hover', function (params) value = md:string(), kind = 'markdown', }, - range = define.range(lines, text, hover.source.start, hover.source.finish), + range = files.range(uri, hover.source.start, hover.source.finish), } end) @@ -241,7 +238,7 @@ proto.on('textDocument/definition', function (params) end local lines = files.getLines(uri) local text = files.getText(uri) - local offset = define.offsetOfWord(lines, text, params.position) + local offset = files.offsetOfWord(uri, params.position) local result = core(uri, offset) if not result then return nil @@ -251,12 +248,11 @@ proto.on('textDocument/definition', function (params) local targetUri = info.uri if targetUri then local targetLines = files.getLines(targetUri) - local targetText = files.getText(targetUri) if targetLines then response[i] = define.locationLink(targetUri - , define.range(targetLines, targetText, info.target.start, info.target.finish) - , define.range(targetLines, targetText, info.target.start, info.target.finish) - , define.range(lines, text, info.source.start, info.source.finish) + , files.range(targetUri, info.target.start, info.target.finish) + , files.range(targetUri, info.target.start, info.target.finish) + , files.range(uri, info.source.start, info.source.finish) ) end end @@ -272,7 +268,7 @@ proto.on('textDocument/references', function (params) end local lines = files.getLines(uri) local text = files.getText(uri) - local offset = define.offsetOfWord(lines, text, params.position) + local offset = files.offsetOfWord(uri, params.position) local result = core(uri, offset) if not result then return nil @@ -280,10 +276,8 @@ proto.on('textDocument/references', function (params) local response = {} for i, info in ipairs(result) do local targetUri = info.uri - local targetLines = files.getLines(targetUri) - local targetText = files.getText(targetUri) response[i] = define.location(targetUri - , define.range(targetLines, targetText, info.target.start, info.target.finish) + , files.range(targetUri, info.target.start, info.target.finish) ) end return response @@ -295,9 +289,7 @@ proto.on('textDocument/documentHighlight', function (params) if not files.exists(uri) then return nil end - local lines = files.getLines(uri) - local text = files.getText(uri) - local offset = define.offsetOfWord(lines, text, params.position) + local offset = files.offsetOfWord(uri, params.position) local result = core(uri, offset) if not result then return nil @@ -305,7 +297,7 @@ proto.on('textDocument/documentHighlight', function (params) local response = {} for _, info in ipairs(result) do response[#response+1] = { - range = define.range(lines, text, info.start, info.finish), + range = files.range(uri, info.start, info.finish), kind = info.kind, } end @@ -318,9 +310,7 @@ proto.on('textDocument/rename', function (params) if not files.exists(uri) then return nil end - local lines = files.getLines(uri) - local text = files.getText(uri) - local offset = define.offsetOfWord(lines, text, params.position) + local offset = files.offsetOfWord(uri, params.position) local result = core.rename(uri, offset, params.newName) if not result then return nil @@ -330,12 +320,10 @@ proto.on('textDocument/rename', function (params) } for _, info in ipairs(result) do local ruri = info.uri - local rlines = files.getLines(ruri) - local rtext = files.getText(ruri) if not workspaceEdit.changes[ruri] then workspaceEdit.changes[ruri] = {} end - local textEdit = define.textEdit(define.range(rlines, rtext, info.start, info.finish), info.text) + local textEdit = define.textEdit(files.range(ruri, info.start, info.finish), info.text) workspaceEdit.changes[ruri][#workspaceEdit.changes[ruri]+1] = textEdit end return workspaceEdit @@ -347,15 +335,13 @@ proto.on('textDocument/prepareRename', function (params) if not files.exists(uri) then return nil end - local lines = files.getLines(uri) - local text = files.getText(uri) - local offset = define.offsetOfWord(lines, text, params.position) + local offset = files.offsetOfWord(uri, params.position) local result = core.prepareRename(uri, offset) if not result then return nil end return { - range = define.range(lines, text, result.start, result.finish), + range = files.range(uri, result.start, result.finish), placeholder = result.text, } end) @@ -371,9 +357,7 @@ proto.on('textDocument/completion', function (params) end await.setPriority(1000) local clock = os.clock() - local lines = files.getLines(uri) - local text = files.getText(uri) - local offset = define.offset(lines, text, params.position) + local offset = files.offsetOfWord(uri, params.position) local result = core.completion(uri, offset) local passed = os.clock() - clock if passed > 0.1 then @@ -396,9 +380,8 @@ proto.on('textDocument/completion', function (params) commitCharacters = res.commitCharacters, command = res.command, textEdit = res.textEdit and { - range = define.range( - lines, - text, + range = files.range( + uri, res.textEdit.start, res.textEdit.finish ), @@ -408,9 +391,8 @@ proto.on('textDocument/completion', function (params) local t = {} for j, edit in ipairs(res.additionalTextEdits) do t[j] = { - range = define.range( - lines, - text, + range = files.range( + uri, edit.start, edit.finish ), @@ -467,8 +449,6 @@ proto.on('completionItem/resolve', function (item) if not resolved then return nil end - local lines = files.getLines(uri) - local text = files.getText(uri) item.detail = resolved.detail item.documentation = resolved.description and { value = resolved.description, @@ -478,9 +458,8 @@ proto.on('completionItem/resolve', function (item) local t = {} for j, edit in ipairs(resolved.additionalTextEdits) do t[j] = { - range = define.range( - lines, - text, + range = files.range( + uri, edit.start, edit.finish ), @@ -502,9 +481,7 @@ proto.on('textDocument/signatureHelp', function (params) end await.close('signatureHelp') await.setID('signatureHelp') - local lines = files.getLines(uri) - local text = files.getText(uri) - local offset = define.offset(lines, text, params.position) + local offset = files.offsetOfWord(uri, params.position) local core = require 'core.signature' local results = core(uri, offset) if not results then @@ -539,12 +516,8 @@ end) proto.on('textDocument/documentSymbol', function (params) local core = require 'core.document-symbol' local uri = params.textDocument.uri - local lines = files.getLines(uri) - local text = files.getText(uri) - while not lines or not text do + while not files.getLines(uri) do await.sleep(0.1) - lines = files.getLines(uri) - text = files.getText(uri) end local symbols = core(uri) @@ -554,15 +527,13 @@ proto.on('textDocument/documentSymbol', function (params) local function convert(symbol) await.delay() - symbol.range = define.range( - lines, - text, + symbol.range = files.range( + uri, symbol.range[1], symbol.range[2] ) - symbol.selectionRange = define.range( - lines, - text, + symbol.selectionRange = files.range( + uri, symbol.selectionRange[1], symbol.selectionRange[2] ) @@ -595,7 +566,7 @@ proto.on('textDocument/codeAction', function (params) return nil end - local start, finish = define.unrange(lines, text, range) + local start, finish = files.unrange(uri, range) local results = core(uri, start, finish, diagnostics) if not results or #results == 0 then @@ -605,10 +576,8 @@ proto.on('textDocument/codeAction', function (params) for _, res in ipairs(results) do if res.edit then for turi, changes in pairs(res.edit.changes) do - local ttext = files.getText(turi) - local tlines = files.getLines(turi) for _, change in ipairs(changes) do - change.range = define.range(tlines, ttext, change.start, change.finish) + change.range = files.range(turi, change.start, change.finish) change.start = nil change.finish = nil end @@ -644,9 +613,8 @@ proto.on('workspace/symbol', function (params) local function convert(symbol) symbol.location = define.location( symbol.uri, - define.range( - files.getLines(symbol.uri), - files.getText(symbol.uri), + files.range( + symbol.uri, symbol.range[1], symbol.range[2] ) @@ -681,15 +649,11 @@ proto.on('textDocument/semanticTokens/range', function (params) local core = require 'core.semantic-tokens' local uri = params.textDocument.uri log.debug('semanticTokens/range', uri) - local lines = files.getLines(uri) - local text = files.getText(uri) - while not lines or not text do + while not files.getLines(uri) do await.sleep(0.1) - lines = files.getLines(uri) - text = files.getText(uri) end - local start = define.offset(lines, text, params.range.start) - local finish = define.offset(lines, text, params.range['end']) + local start = files.offsetOfWord(uri, params.range.start) + local finish = files.offsetOfWord(uri, params.range['end']) local results = core(uri, start, finish) return { data = results @@ -711,8 +675,8 @@ proto.on('textDocument/foldingRange', function (params) local results = {} for _, region in ipairs(regions) do - local startLine = define.position(lines, text, region.start).line - local endLine = define.position(lines, text, region.finish).line + local startLine = files.position(uri, region.start).line + local endLine = files.position(uri, region.finish).line if not region.hideLastLine then endLine = endLine - 1 end -- cgit v1.2.3