diff options
Diffstat (limited to 'script/parser')
-rw-r--r-- | script/parser/guide.lua | 28 | ||||
-rw-r--r-- | script/parser/lines.lua | 69 | ||||
-rw-r--r-- | script/parser/luadoc.lua | 11 |
3 files changed, 51 insertions, 57 deletions
diff --git a/script/parser/guide.lua b/script/parser/guide.lua index 9e854bf5..c14f5a37 100644 --- a/script/parser/guide.lua +++ b/script/parser/guide.lua @@ -688,39 +688,43 @@ 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 < 1 then - return 0, 0 + if offset <= 0 then + return 1, 0 end local lastLine = lines[#lines] - if offset > lastLine.finish then - return #lines, offset - lastLine.start + 1 + 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 + 1 + 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 + elseif offset >= line.finish then min = row + 1 else - return row, offset - line.start + 1 + return row, offset - line.start end end error('Stack overflow!') end ---- 获取坐标对应的偏移 +--- 获取坐标对应的光标偏移。 +--- 一定会落在当前行的换行符左侧。 +--- 第一行的行号是1不是0。 ---@param lines table ---@param row integer ---@param col integer @@ -734,13 +738,13 @@ function m.offsetOf(lines, row, col) return lastLine.finish end local line = lines[row] - local len = line.finish - line.start + 1 + local len = line.range - line.start if col < 0 then return line.start elseif col > len then - return line.finish + return line.range else - return line.start + col - 1 + return line.start + col end end diff --git a/script/parser/lines.lua b/script/parser/lines.lua index ee6b4f41..1aba0ae5 100644 --- a/script/parser/lines.lua +++ b/script/parser/lines.lua @@ -1,45 +1,34 @@ -local m = require 'lpeglabel' - -_ENV = nil - -local function Line(start, line, range, finish) - line.start = start - line.finish = finish - 1 - line.range = range - 1 - return line -end - -local function Space(...) - local line = {...} - local sp = 0 - local tab = 0 - for i = 1, #line do - if line[i] == ' ' then - sp = sp + 1 - elseif line[i] == '\t' then - tab = tab + 1 - end - line[i] = nil - end - line.sp = sp - line.tab = tab - return line -end - -local parser = m.P{ -'Lines', -Lines = m.Ct(m.V'Line'^0 * m.V'LastLine'), -Line = m.Cp() * m.V'Indent' * (1 - m.V'Nl')^0 * m.Cp() * m.V'Nl' * m.Cp() / Line, -LastLine= m.Cp() * m.V'Indent' * (1 - m.V'Nl')^0 * m.Cp() * m.Cp() / Line, -Nl = m.P'\r\n' + m.S'\r\n', -Indent = m.C(m.S' \t')^0 / Space, -} +local sfind = string.find +local ssub = string.sub +---@param text string return function (self, text) - local lines, err = parser:match(text) - if not lines then - return nil, err + local current = 1 + local lines = {} + local i = 1 + while true do + local pos = sfind(text,'[\r\n]', current) + if not pos then + break + end + local line = { + start = current - 1, + range = pos - 1, + } + lines[i] = line + i = i + 1 + if ssub(text, pos, pos + 1) == '\r\n' then + current = pos + 2 + line.finish = pos + 1 + else + current = pos + 1 + line.finish = pos + end end - + lines[i] = { + start = current - 1, + finish = #text, + range = #text, + } return lines end diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua index 6e8500ba..0aa98482 100644 --- a/script/parser/luadoc.lua +++ b/script/parser/luadoc.lua @@ -1172,18 +1172,18 @@ local function buildLuaDoc(comment) end ---当前行在注释doc前是否有代码 -local function haveCodeBeforeDocInCurLine(lineData, docStartCol) - return docStartCol > lineData.sp + lineData.tab + 3 +local function haveCodeBeforeDocInCurLine(text, lineData, docStartCol) + return text:sub(lineData.start + 1, docStartCol - 1):find '[^ \t]' end -local function isNextLine(lns, binded, doc) +local function isNextLine(lns, text, binded, doc) if not binded then return false end local lastDoc = binded[#binded] local lastDocStartRow, lastDocStartCol = guide.positionOf(lns, lastDoc.originalComment.start) local lastDocStartLineData = guide.lineData(lns, lastDocStartRow) - if haveCodeBeforeDocInCurLine(lastDocStartLineData, lastDocStartCol) then + if haveCodeBeforeDocInCurLine(text, lastDocStartLineData, lastDocStartCol) then return false end @@ -1340,6 +1340,7 @@ local function bindDoc(sources, lns, binded) end local function bindDocs(state) + local text = state.lua local sources = {} guide.eachSource(state.ast, function (src) if src.type == 'local' @@ -1361,7 +1362,7 @@ local function bindDocs(state) end) local binded for _, doc in ipairs(state.ast.docs) do - if not isNextLine(Lines, binded, doc) then + if not isNextLine(Lines, text, binded, doc) then bindDoc(sources, Lines, binded) binded = {} state.ast.docs.groups[#state.ast.docs.groups+1] = binded |