diff options
-rw-r--r-- | script/core/code-action.lua | 2 | ||||
-rw-r--r-- | script/core/completion.lua | 2 | ||||
-rw-r--r-- | script/core/diagnostics/newfield-call.lua | 4 | ||||
-rw-r--r-- | script/core/diagnostics/newline-call.lua | 4 | ||||
-rw-r--r-- | script/core/find-source.lua | 6 | ||||
-rw-r--r-- | script/core/keyword.lua | 4 | ||||
-rw-r--r-- | script/core/reference.lua | 4 | ||||
-rw-r--r-- | script/core/type-formatting.lua | 2 | ||||
-rw-r--r-- | script/files.lua | 2 | ||||
-rw-r--r-- | script/parser/guide.lua | 88 | ||||
-rw-r--r-- | script/parser/luadoc.lua | 12 | ||||
-rw-r--r-- | script/vm/getDocs.lua | 2 | ||||
-rw-r--r-- | test/basic/noder.lua | 2 | ||||
-rw-r--r-- | test/catch.lua | 28 | ||||
-rw-r--r-- | test/references/init.lua | 27 |
15 files changed, 78 insertions, 111 deletions
diff --git a/script/core/code-action.lua b/script/core/code-action.lua index 64f862f9..1bac9359 100644 --- a/script/core/code-action.lua +++ b/script/core/code-action.lua @@ -57,7 +57,7 @@ end local function disableDiagnostic(uri, code, start, results) local lines = files.getLines(uri) - local row = guide.positionOf(lines, start) + local row = guide.positionOf(start) results[#results+1] = { title = lang.script('ACTION_DISABLE_DIAG', code), kind = 'quickfix', diff --git a/script/core/completion.lua b/script/core/completion.lua index f81f8179..59dc19f3 100644 --- a/script/core/completion.lua +++ b/script/core/completion.lua @@ -176,7 +176,7 @@ local function getSnip(source) if vm.isMetaFile(uri) then goto CONTINUE end - local row = guide.positionOf(lines, def.start) + local row = guide.positionOf(def.start) local firstRow = lines[row] local lastRow = lines[math.min(row + context - 1, #lines)] local snip = text:sub(firstRow.start, lastRow.finish) diff --git a/script/core/diagnostics/newfield-call.lua b/script/core/diagnostics/newfield-call.lua index fe86ad66..61d52dd2 100644 --- a/script/core/diagnostics/newfield-call.lua +++ b/script/core/diagnostics/newfield-call.lua @@ -27,8 +27,8 @@ return function (uri, callback) local func = call.node local args = call.args if args then - local funcLine = guide.positionOf(lines, func.finish) - local argsLine = guide.positionOf(lines, args.start) + local funcLine = guide.positionOf(func.finish) + local argsLine = guide.positionOf(args.start) if argsLine > funcLine then callback { start = call.start, diff --git a/script/core/diagnostics/newline-call.lua b/script/core/diagnostics/newline-call.lua index 71dc33e2..69bf948f 100644 --- a/script/core/diagnostics/newline-call.lua +++ b/script/core/diagnostics/newline-call.lua @@ -26,8 +26,8 @@ return function (uri, callback) return end - local nodeRow = guide.positionOf(lines, node.finish) - local argRow = guide.positionOf(lines, args.start) + local nodeRow = guide.positionOf(node.finish) + local argRow = guide.positionOf(args.start) if nodeRow == argRow then return end diff --git a/script/core/find-source.lua b/script/core/find-source.lua index edbb1e2c..26a411e5 100644 --- a/script/core/find-source.lua +++ b/script/core/find-source.lua @@ -11,12 +11,12 @@ local function isValidFunctionPos(source, offset) return false end -return function (ast, offset, accept) +return function (ast, position, accept) local len = math.huge local result - guide.eachSourceContain(ast.ast, offset, function (source) + guide.eachSourceContain(ast.ast, position, function (source) if source.type == 'function' then - if not isValidFunctionPos(source, offset) then + if not isValidFunctionPos(source, position) then return end end diff --git a/script/core/keyword.lua b/script/core/keyword.lua index b8e37605..4b43efe5 100644 --- a/script/core/keyword.lua +++ b/script/core/keyword.lua @@ -275,8 +275,8 @@ until $1" if first == 'end' or first == 'else' or first == 'elseif' then - local startRow = guide.positionOf(lines, info.start) - local finishRow = guide.positionOf(lines, pos) + local startRow = guide.positionOf(info.start) + local finishRow = guide.positionOf(pos) local startSp = info.text:match('^%s*', lines[startRow].start + 1) local finishSp = info.text:match('^%s*', lines[finishRow].start + 1) if startSp == finishSp then diff --git a/script/core/reference.lua b/script/core/reference.lua index 5f5831c6..067d2e23 100644 --- a/script/core/reference.lua +++ b/script/core/reference.lua @@ -52,13 +52,13 @@ local accept = { ['doc.alias.name'] = true, } -return function (uri, offset) +return function (uri, position) local ast = files.getState(uri) if not ast then return nil end - local source = findSource(ast, offset, accept) + local source = findSource(ast, position, accept) if not source then return nil end diff --git a/script/core/type-formatting.lua b/script/core/type-formatting.lua index a225d9d7..12272f11 100644 --- a/script/core/type-formatting.lua +++ b/script/core/type-formatting.lua @@ -5,7 +5,7 @@ local guide = require "parser.guide" local function insertIndentation(uri, offset, edits) local lines = files.getLines(uri) local text = files.getOriginText(uri) - local row = guide.positionOf(lines, offset) + local row = guide.positionOf(offset) local line = lines[row] local indent = text:sub(line.start, line.finish):match '^%s*' for _, edit in ipairs(edits) do diff --git a/script/files.lua b/script/files.lua index ecaaa5a5..0e62a740 100644 --- a/script/files.lua +++ b/script/files.lua @@ -744,7 +744,7 @@ function m.position(uri, offset, leftOrRight) lines = m.getOriginLines(uri) text = m.getOriginText(uri) end - local row, col = guide.positionOf(lines, offset) + local row, col = guide.positionOf(offset) local start, finish = guide.lineRange(lines, row, true) start = start + 1 if col <= finish - start + 1 then diff --git a/script/parser/guide.lua b/script/parser/guide.lua index e5e9ead1..941fc7b1 100644 --- a/script/parser/guide.lua +++ b/script/parser/guide.lua @@ -548,24 +548,24 @@ function m.getRange(source) return start, finish end ---- 判断source是否包含offset -function m.isContain(source, offset) +--- 判断source是否包含position +function m.isContain(source, position) local start, finish = m.getStartFinish(source) if not start then return false end - return start <= offset and finish >= offset + return start <= position and finish >= position end ---- 判断offset在source的影响范围内 +--- 判断position在source的影响范围内 --- --- 主要针对赋值等语句时,key包含value -function m.isInRange(source, offset) +function m.isInRange(source, position) local start, finish = m.getRange(source) if not start then return false end - return start <= offset and finish >= offset + return start <= position and finish >= position end function m.isBetween(source, tStart, tFinish) @@ -597,8 +597,8 @@ local function addChilds(list, obj) f(obj, list) end ---- 遍历所有包含offset的source -function m.eachSourceContain(ast, offset, callback) +--- 遍历所有包含position的source +function m.eachSourceContain(ast, position, callback) local list = { ast } local mark = {} while true do @@ -610,8 +610,8 @@ function m.eachSourceContain(ast, offset, callback) list[len] = nil if not mark[obj] then mark[obj] = true - if m.isInRange(obj, offset) then - if m.isContain(obj, offset) then + if m.isInRange(obj, position) then + if m.isContain(obj, position) then local res = callback(obj) if res ~= nil then return res @@ -737,64 +737,24 @@ function m.eachSpecialOf(ast, name, callback) end end ---- 获取光标偏移对应的坐标。 ---- 如果在换行符的右侧,则认为在新的一行。 ---- 第一行的行号是1不是0。 ----@param lines table ----@return integer {name = 'row'} ----@return integer {name = 'col'} -function m.positionOf(lines, offset) - if offset <= 0 then - return 1, 0 - end - local lastLine = lines[#lines] - if offset >= lastLine.finish then - return #lines, lastLine.finish - lastLine.start - end - local min = 1 - local max = #lines - for _ = 1, 100 do - if max <= min then - local line = lines[min] - return min, offset - line.start - end - local row = (max - min) // 2 + min - local line = lines[row] - if offset < line.start then - max = row - 1 - elseif offset >= line.finish then - min = row + 1 - else - return row, offset - line.start - end - end - error('Stack overflow!') +--- 将 position 拆分成行号与列号 +--- +--- 第一行是0 +---@param position integer +---@return integer row +---@return integer col +function m.positionOf(position) + return position // 10000, position % 10000 end ---- 获取坐标对应的光标偏移。 ---- 一定会落在当前行的换行符左侧。 ---- 第一行的行号是1不是0。 ----@param lines table +--- 将行列合并为 position +--- +--- 第一行是0 ---@param row integer ---@param col integer ----@return integer {name = 'offset'} -function m.offsetOf(lines, row, col) - if row < 1 then - return 0 - end - if row > #lines then - local lastLine = lines[#lines] - return lastLine.finish - end - local line = lines[row] - local len = line.range - line.start - if col < 0 then - return line.start - elseif col > len then - return line.range - else - return line.start + col - end +---@return integer +function m.offsetOf(row, col) + return row * 10000 + col end function m.lineContent(lines, text, row, ignoreNL) diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua index 26341571..533aa9db 100644 --- a/script/parser/luadoc.lua +++ b/script/parser/luadoc.lua @@ -635,7 +635,7 @@ function parseType(parent) result.finish = getFinish() result.firstFinish = result.finish - local row = guide.positionOf(Lines, result.finish) + local row = guide.positionOf(result.finish) local function pushResume() local comments @@ -1178,8 +1178,8 @@ end local function isTailComment(lns, text, binded, doc) local lastDoc = binded[#binded] - local lastDocStartRow = guide.positionOf(lns, lastDoc.originalComment.start) - local lastDocStartLineData = guide.lineData(lns, lastDocStartRow) + local lastDocStartRow = guide.positionOf(lastDoc.originalComment.start) + local lastDocStartLineData = guide.lineData(lastDocStartRow) if haveCodeBeforeDocInCurLine(text, lastDocStartLineData, lastDoc.originalComment.start) then return true end @@ -1191,8 +1191,8 @@ local function isNextLine(lns, text, binded, doc) return false end local lastDoc = binded[#binded] - local lastRow = guide.positionOf(lns, lastDoc.finish) - local newRow = guide.positionOf(lns, doc.start) + local lastRow = guide.positionOf(lastDoc.finish) + local newRow = guide.positionOf(doc.start) return newRow - lastRow == 1 end @@ -1332,7 +1332,7 @@ local function bindDoc(sources, lns, binded) doc.bindSources = bindSources end bindGeneric(binded) - local row = guide.positionOf(lns, lastDoc.finish) + local row = guide.positionOf(lastDoc.finish) local cstart, cfinish = guide.lineRange(lns, row) local nstart, nfinish = guide.lineRange(lns, row + 1) bindDocsBetween(sources, binded, bindSources, cstart, cfinish) diff --git a/script/vm/getDocs.lua b/script/vm/getDocs.lua index c0205654..5fcf9478 100644 --- a/script/vm/getDocs.lua +++ b/script/vm/getDocs.lua @@ -186,7 +186,7 @@ local function makeDiagRange(uri, doc, results) names[name] = true end end - local row = guide.positionOf(lines, doc.start) + local row = guide.positionOf(doc.start) if doc.mode == 'disable-next-line' then if lines[row+1] then results[#results+1] = { diff --git a/test/basic/noder.lua b/test/basic/noder.lua index 4c0a1620..87b34e12 100644 --- a/test/basic/noder.lua +++ b/test/basic/noder.lua @@ -33,7 +33,7 @@ local function TEST(script) files.removeAll() local newScript, catched = catch(script, '?') files.setText('', newScript) - local source = getSource(catched[1][1]) + local source = getSource(catched['?'][1][1]) assert(source) local result = { id = noder.getID(source), diff --git a/test/catch.lua b/test/catch.lua index 910c368f..09b55929 100644 --- a/test/catch.lua +++ b/test/catch.lua @@ -1,3 +1,22 @@ +local mt = {} + +local function catchedTable() + return setmetatable({}, mt) +end + +function mt.__add(a, b) + if not a or not b then + return a or b + end + local t = catchedTable() + for _, v in ipairs(a) do + t[#t+1] = v + end + for _, v in ipairs(b) do + t[#t+1] = v + end + return t +end local function getLine(offset, lns) for i = 0, #lns do @@ -20,7 +39,7 @@ end ---@param script string ---@param sep string return function (script, sep) - local pattern = ('()<%%%s.-%%%s>()'):format(sep, sep) + local pattern = ('()<(%s).-%s>()'):format(sep, sep) local lns = {} lns[0] = 0 for pos in script:gmatch '()\n' do @@ -33,7 +52,7 @@ return function (script, sep) local list = {} local cuted = 0 local lastLine = 0 - for a, b in script:gmatch(pattern) do + for a, char, b in script:gmatch(pattern) do codes[#codes+1] = script:sub(pos, a - 1) codes[#codes+1] = script:sub(a + 2, b - 3) pos = b @@ -51,7 +70,10 @@ return function (script, sep) end local right = getPosition(b - 3, lns) - cuted cuted = cuted + 2 - list[#list+1] = { left, right } + if not list[char] then + list[char] = catchedTable() + end + list[char][#list[char]+1] = { left, right } end codes[#codes+1] = script:sub(pos) return table.concat(codes), list diff --git a/test/references/init.lua b/test/references/init.lua index 2fba92e5..a14f0a02 100644 --- a/test/references/init.lua +++ b/test/references/init.lua @@ -1,19 +1,6 @@ local core = require 'core.reference' local files = require 'files' - -local function catch_target(script) - local list = {} - local cur = 1 - while true do - local start, finish = script:find('<[!?].-[!?]>', cur) - if not start then - break - end - list[#list+1] = { start + 2, finish - 2 } - cur = finish + 1 - end - return list -end +local catch = require 'catch' local function founded(targets, results) if #targets ~= #results then @@ -33,14 +20,12 @@ end function TEST(script) files.removeAll() - local expect = catch_target(script) - local start = script:find('<[?~]') - local finish = script:find('[?~]>') - local pos = (start + finish) // 2 + 1 - local new_script = script:gsub('<[!?~]', ' '):gsub('[!?~]>', ' ') - files.setText('', new_script) + local newScript, catched = catch(script, '[!?~]') + files.setText('', newScript) - local results = core('', pos) + local input = catched['?'] + catched['~'] + local expect = catched['!'] + catched['?'] + catched['~'] + local results = core('', input[1][1]) if results then local positions = {} for i, result in ipairs(results) do |