summaryrefslogtreecommitdiff
path: root/script/parser
diff options
context:
space:
mode:
Diffstat (limited to 'script/parser')
-rw-r--r--script/parser/guide.lua28
-rw-r--r--script/parser/lines.lua69
-rw-r--r--script/parser/luadoc.lua11
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