diff options
Diffstat (limited to 'script')
-rw-r--r-- | script/core/completion/completion.lua | 3 | ||||
-rw-r--r-- | script/files.lua | 17 | ||||
-rw-r--r-- | script/parser/guide.lua | 34 | ||||
-rw-r--r-- | script/parser/init.lua | 2 | ||||
-rw-r--r-- | script/parser/luadoc.lua | 38 | ||||
-rw-r--r-- | script/plugins/astHelper.lua | 66 |
6 files changed, 156 insertions, 4 deletions
diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua index b7d4650c..acb3adbe 100644 --- a/script/core/completion/completion.lua +++ b/script/core/completion/completion.lua @@ -2192,7 +2192,8 @@ local function buildluaDocOfFunction(func, pad) end for _, rtn in ipairs(returns) do index = index + 1 - buf[#buf+1] = ('---@return ${%d:%s}'):format( + buf[#buf+1] = ('---%s@return ${%d:%s}'):format( + pad and ' ' or '', index, rtn ) diff --git a/script/files.lua b/script/files.lua index 490ae504..b7a20e8b 100644 --- a/script/files.lua +++ b/script/files.lua @@ -655,6 +655,17 @@ function m.compileStateAsync(uri, callback) end) end +local function pluginOnTransformAst(uri, state) + local plugin = require 'plugin' + ---TODO: maybe deepcopy astNode + local suc, result = plugin.dispatch('OnTransformAst', uri, state.ast) + if not suc then + return state + end + state.ast = result + return state +end + ---@param uri uri ---@return parser.state? function m.compileState(uri) @@ -700,6 +711,12 @@ function m.compileState(uri) return nil end + state = pluginOnTransformAst(uri, state) + if not state then + log.error('pluginOnTransformAst failed! discard the file state') + return nil + end + m.compileStateThen(state, file) return state diff --git a/script/parser/guide.lua b/script/parser/guide.lua index 0dd6338e..4efe066b 100644 --- a/script/parser/guide.lua +++ b/script/parser/guide.lua @@ -422,6 +422,22 @@ function m.getParentType(obj, want) error('guide.getParentType overstack') end +--- 寻找所在父类型 +---@param obj parser.object +---@return parser.object? +function m.getParentTypes(obj, wants) + for _ = 1, 10000 do + obj = obj.parent + if not obj then + return nil + end + if wants[obj.type] then + return obj + end + end + error('guide.getParentTypes overstack') +end + --- 寻找根区块 ---@param obj parser.object ---@return parser.object @@ -1292,4 +1308,22 @@ function m.isParam(source) return true end +---@param source parser.object +---@param index integer +---@return parser.object? +function m.getParam(source, index) + if source.type == 'call' then + local args = source.args + assert(args.type == 'callargs', 'call.args type is\'t callargs') + return args[index] + elseif source.type == 'callargs' then + return source[index] + elseif source.type == 'function' then + local args = source.args + assert(args.type == 'funcargs', 'function.args type is\'t callargs') + return args[index] + end + return nil +end + return m diff --git a/script/parser/init.lua b/script/parser/init.lua index bc004f77..9848ce00 100644 --- a/script/parser/init.lua +++ b/script/parser/init.lua @@ -2,7 +2,7 @@ local api = { compile = require 'parser.compile', lines = require 'parser.lines', guide = require 'parser.guide', - luadoc = require 'parser.luadoc', + luadoc = require 'parser.luadoc'.luadoc, } return api diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua index d7338918..64394e92 100644 --- a/script/parser/luadoc.lua +++ b/script/parser/luadoc.lua @@ -1964,6 +1964,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 @@ -1999,7 +2007,8 @@ local function bindDocs(state) 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 @@ -2028,7 +2037,7 @@ local function findTouch(state, doc) end end -return function (state) +local function luadoc(state) local ast = state.ast local comments = state.comms table.sort(comments, function (a, b) @@ -2097,6 +2106,15 @@ return function (state) 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 @@ -2107,3 +2125,19 @@ return function (state) bindDocs(state) end + +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 + return false + end, + luadoc = luadoc +} diff --git a/script/plugins/astHelper.lua b/script/plugins/astHelper.lua new file mode 100644 index 00000000..6f303c79 --- /dev/null +++ b/script/plugins/astHelper.lua @@ -0,0 +1,66 @@ +local luadoc = require 'parser.luadoc' +local ssub = require 'core.substring' +local guide = require 'parser.guide' +local _M = {} + +function _M.buildComment(t, value) + return { + type = 'comment.short', + start = 1, + finish = 1, + text = "-@" .. t .. " " .. value, + } +end + +function _M.InsertDoc(ast, comm) + local comms = ast.state.comms or {} + comms[#comms+1] = comm + ast.state.comms = comms +end + +--- give the local/global variable add doc.class +---@param ast parser.object +---@param source parser.object local/global variable +---@param classname string +function _M.addClassDoc(ast, source, classname) + if source.type ~= 'local' and not guide.isGlobal(source) then + return false + end + --TODO fileds + --TODO callers + local comment = _M.buildComment("class", classname) + comment.start = source.start - 1 + comment.finish = comment.start + + return luadoc.buildAndBindDoc(ast, source, comment) +end + +---remove `ast` function node `index` arg, the variable will be the function local variable +---@param source parser.object function node +---@param index integer +---@return parser.object? +function _M.removeArg(source, index) + if source.type == 'function' then + local arg = table.remove(source.args, index) + if not arg then + return nil + end + arg.parent = arg.parent.parent + return arg + end + return nil +end + +--- 把特定函数当成构造函数,`index` 参数是self +---@param classname string +---@param source parser.object function node +---@param index integer +function _M.addClassDocAtParam(ast, classname, source, index) + local arg = _M.removeArg(source, index) + if arg then + return _M.addClassDoc(ast, arg, classname) + end + return false +end + +return _M |