diff options
author | fesily <fesil@foxmail.com> | 2024-01-09 14:00:49 +0800 |
---|---|---|
committer | fesily <fesil@foxmail.com> | 2024-01-09 14:00:49 +0800 |
commit | 281ba5f8c4a8cb15e53acc5f3f0d4f43872ea941 (patch) | |
tree | 5f0ee208d1a1187e40db410851d3ff84abb8dc79 /script/parser/luadoc.lua | |
parent | 7e895e9f9e9d81b6e78400976b5148a3d106dc74 (diff) | |
download | lua-language-server-281ba5f8c4a8cb15e53acc5f3f0d4f43872ea941.zip |
plugin: add OnTransformAst interface
Diffstat (limited to 'script/parser/luadoc.lua')
-rw-r--r-- | script/parser/luadoc.lua | 200 |
1 files changed, 116 insertions, 84 deletions
diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua index c022adcb..332211e1 100644 --- a/script/parser/luadoc.lua +++ b/script/parser/luadoc.lua @@ -291,7 +291,7 @@ local function parseTable(parent) needCloseParen = true end field.name = parseName('doc.field.name', field) - or parseIndexField(field) + or parseIndexField(field) if not field.name then pushWarning { type = 'LUADOC_MISS_FIELD_NAME', @@ -401,7 +401,7 @@ local function parseTypeUnitFunction(parent) parent = typeUnit, } arg.name = parseName('doc.type.arg.name', arg) - or parseDots('doc.type.arg.name', arg) + or parseDots('doc.type.arg.name', arg) if not arg.name then pushWarning { type = 'LUADOC_MISS_ARG_NAME', @@ -442,7 +442,7 @@ local function parseTypeUnitFunction(parent) local name try(function () local returnName = parseName('doc.return.name', typeUnit) - or parseDots('doc.return.name', typeUnit) + or parseDots('doc.return.name', typeUnit) if not returnName then return false end @@ -646,15 +646,15 @@ end function parseTypeUnit(parent) local result = parseFunction(parent) - or parseTable(parent) - or parseString(parent) - or parseCode(parent) - or parseInteger(parent) - or parseBoolean(parent) - or parseParen(parent) + or parseTable(parent) + or parseString(parent) + or parseCode(parent) + or parseInteger(parent) + or parseBoolean(parent) + or parseParen(parent) if not result then result = parseName('doc.type.name', parent) - or parseDots('doc.type.name', parent) + or parseDots('doc.type.name', parent) if not result then return nil end @@ -827,7 +827,7 @@ local docSwitch = util.switch() while true do local extend = parseName('doc.extends.name', result) - or parseTable(result) + or parseTable(result) if not extend then pushWarning { type = 'LUADOC_MISS_CLASS_EXTENDS_NAME', @@ -896,7 +896,7 @@ local docSwitch = util.switch() type = 'doc.param', } result.param = parseName('doc.param.name', result) - or parseDots('doc.param.name', result) + or parseDots('doc.param.name', result) if not result.param then pushWarning { type = 'LUADOC_MISS_PARAM_NAME', @@ -951,7 +951,7 @@ local docSwitch = util.switch() dots.parent = docType else docType.name = parseName('doc.return.name', docType) - or parseDots('doc.return.name', docType) + or parseDots('doc.return.name', docType) end result.returns[#result.returns+1] = docType if not checkToken('symbol', ',', 1) then @@ -990,7 +990,7 @@ local docSwitch = util.switch() return false end) result.field = parseName('doc.field.name', result) - or parseIndexField(result) + or parseIndexField(result) if not result.field then pushWarning { type = 'LUADOC_MISS_FIELD_NAME', @@ -1514,7 +1514,7 @@ end local function buildLuaDoc(comment) local text = comment.text local startPos = (comment.type == 'comment.short' and text:match '^%-%s*@()') - or (comment.type == 'comment.long' and text:match '^@()') + or (comment.type == 'comment.long' and text:match '^@()') if not startPos then return { type = 'doc.comment', @@ -1921,6 +1921,14 @@ local function bindDocWithSources(sources, binded) bindGeneric(binded) bindCommentsAndFields(binded) bindReturnIndex(binded) + + -- doc is special node + if lastDoc.special then + if bindDoc(lastDoc.special, binded) then + return + end + end + local row = guide.rowColOf(lastDoc.finish) local suc = bindDocsBetween(sources, binded, guide.positionOf(row, 0), lastDoc.start) if not suc then @@ -1950,13 +1958,14 @@ local function bindDocs(state) binded = {} state.ast.docs.groups[#state.ast.docs.groups+1] = binded end - binded[#binded+1] = doc + binded[#binded+1] = doc if isTailComment(text, doc) then bindDocWithSources(sources, binded) binded = nil else local nextDoc = state.ast.docs[i+1] - if not isNextLine(doc, nextDoc) then + if nextDoc and nextDoc.special + or not isNextLine(doc, nextDoc) then bindDocWithSources(sources, binded) binded = nil end @@ -1974,8 +1983,8 @@ local function findTouch(state, doc) local pos = guide.positionToOffset(state, doc.originalComment.start) for i = pos - 2, 1, -1 do local c = text:sub(i, i) - if c == '\r' - or c == '\n' then + if c == '\r' + or c == '\n' then break elseif c ~= ' ' and c ~= '\t' then @@ -1985,82 +1994,105 @@ local function findTouch(state, doc) end end -return function (state) - local ast = state.ast - local comments = state.comms - table.sort(comments, function (a, b) - return a.start < b.start - end) - ast.docs = { - type = 'doc', - parent = ast, - groups = {}, - } - - pushWarning = function (err) - local errs = state.errs - if err.finish < err.start then - err.finish = err.start +return { + buildAndBindDoc = function (ast, src, comment) + local doc = buildLuaDoc(comment) + if doc then + local pluginDocs = ast.state.pluginDocs or {} + pluginDocs[#pluginDocs+1] = doc + doc.special = src + doc.originalComment = comment + ast.state.pluginDocs = pluginDocs + return true end - local last = errs[#errs] - if last then - if last.start <= err.start and last.finish >= err.finish then - return + return false + end, + luadoc = function (state) + local ast = state.ast + local comments = state.comms + table.sort(comments, function (a, b) + return a.start < b.start + end) + ast.docs = ast.docs or { + type = 'doc', + parent = ast, + groups = {}, + } + + pushWarning = function (err) + local errs = state.errs + if err.finish < err.start then + err.finish = err.start + end + local last = errs[#errs] + if last then + if last.start <= err.start and last.finish >= err.finish then + return + end end + err.level = err.level or 'Warning' + errs[#errs+1] = err + return err end - err.level = err.level or 'Warning' - errs[#errs+1] = err - return err - end - Lines = state.lines + Lines = state.lines - local ci = 1 - NextComment = function (offset, peek) - local comment = comments[ci + (offset or 0)] - if not peek then - ci = ci + 1 + (offset or 0) + local ci = 1 + NextComment = function (offset, peek) + local comment = comments[ci + (offset or 0)] + if not peek then + ci = ci + 1 + (offset or 0) + end + return comment end - return comment - end - local function insertDoc(doc, comment) - ast.docs[#ast.docs+1] = doc - doc.parent = ast.docs - if ast.start > doc.start then - ast.start = doc.start - end - if ast.finish < doc.finish then - ast.finish = doc.finish - end - doc.originalComment = comment - if comment.type == 'comment.long' then - findTouch(state, doc) + local function insertDoc(doc, comment) + ast.docs[#ast.docs+1] = doc + doc.parent = ast.docs + if ast.start > doc.start then + ast.start = doc.start + end + if ast.finish < doc.finish then + ast.finish = doc.finish + end + doc.originalComment = comment + if comment.type == 'comment.long' then + findTouch(state, doc) + end end - end - while true do - local comment = NextComment() - if not comment then - break - end - lockResume = false - local doc, rests = buildLuaDoc(comment) - if doc then - insertDoc(doc, comment) - if rests then - for _, rest in ipairs(rests) do - insertDoc(rest, comment) + while true do + local comment = NextComment() + if not comment then + break + end + lockResume = false + local doc, rests = buildLuaDoc(comment) + if doc then + insertDoc(doc, comment) + if rests then + for _, rest in ipairs(rests) do + insertDoc(rest, comment) + end end end end - end + + if ast.state.pluginDocs then + for i, doc in ipairs(ast.state.pluginDocs) do + insertDoc(doc, doc.originalComment) + end + table.sort(ast.docs, function (a, b) + return a.start < b.start + end) + end - ast.docs.start = ast.start - ast.docs.finish = ast.finish + ast.docs.start = ast.start + ast.docs.finish = ast.finish - if #ast.docs == 0 then - return - end + if #ast.docs == 0 then + return + end - bindDocs(state) -end + bindDocs(state) + end +}
\ No newline at end of file |