diff options
Diffstat (limited to 'script/cli')
-rw-r--r-- | script/cli/check.lua | 8 | ||||
-rw-r--r-- | script/cli/doc.lua | 27 | ||||
-rw-r--r-- | script/cli/init.lua | 5 | ||||
-rw-r--r-- | script/cli/visualize.lua | 103 |
4 files changed, 141 insertions, 2 deletions
diff --git a/script/cli/check.lua b/script/cli/check.lua index 94f34b2a..4295fa06 100644 --- a/script/cli/check.lua +++ b/script/cli/check.lua @@ -9,6 +9,7 @@ local lang = require 'language' local define = require 'proto.define' local config = require 'config.config' local fs = require 'bee.filesystem' +local provider = require 'provider' require 'vm' @@ -52,6 +53,8 @@ lclient():start(function (client) io.write(lang.script('CLI_CHECK_INITING')) + provider.updateConfig(rootUri) + ws.awaitReady(rootUri) local disables = util.arrayToHash(config.get(rootUri, 'Lua.diagnostics.disable')) @@ -96,7 +99,10 @@ end if count == 0 then print(lang.script('CLI_CHECK_SUCCESS')) else - local outpath = LOGPATH .. '/check.json' + local outpath = CHECK_OUT_PATH + if outpath == nil then + outpath = LOGPATH .. '/check.json' + end util.saveFile(outpath, jsonb.beautify(results)) print(lang.script('CLI_CHECK_RESULTS', count, outpath)) diff --git a/script/cli/doc.lua b/script/cli/doc.lua index c643deea..fb9b0a8e 100644 --- a/script/cli/doc.lua +++ b/script/cli/doc.lua @@ -65,6 +65,7 @@ local function packObject(source, mark) end if source.type == 'function.return' then new['desc'] = source.comment and getDesc(source.comment) + new['rawdesc'] = source.comment and getDesc(source.comment, true) end if source.type == 'doc.type.table' then new['fields'] = packObject(source.fields, mark) @@ -82,6 +83,7 @@ local function packObject(source, mark) end if source.bindDocs then new['desc'] = getDesc(source) + new['rawdesc'] = getDesc(source, true) end new['view'] = new['view'] or vm.getInfer(source):view(ws.rootUri) end @@ -115,6 +117,7 @@ local function collectTypes(global, results) name = global.name, type = 'type', desc = nil, + rawdesc = nil, defines = {}, fields = {}, } @@ -131,6 +134,7 @@ local function collectTypes(global, results) extends = getExtends(set), } result.desc = result.desc or getDesc(set) + result.rawdesc = result.rawdesc or getDesc(set, true) ::CONTINUE:: end if #result.defines == 0 then @@ -163,7 +167,9 @@ local function collectTypes(global, results) field.start = source.start field.finish = source.finish field.desc = getDesc(source) + field.rawdesc = getDesc(source, true) field.extends = packObject(source.extends) + field.visible = vm.getVisibleType(source) return end if source.type == 'setfield' @@ -180,7 +186,9 @@ local function collectTypes(global, results) field.start = source.start field.finish = source.finish field.desc = getDesc(source) + field.rawdesc = getDesc(source, true) field.extends = packObject(source.value) + field.visible = vm.getVisibleType(source) return end if source.type == 'tableindex' then @@ -199,7 +207,9 @@ local function collectTypes(global, results) field.start = source.start field.finish = source.finish field.desc = getDesc(source) + field.rawdesc = getDesc(source, true) field.extends = packObject(source.value) + field.visible = vm.getVisibleType(source) return end end) @@ -237,6 +247,9 @@ local function collectVars(global, results) extends = packObject(set.value), } result.desc = result.desc or getDesc(set) + result.rawdesc = result.rawdesc or getDesc(set, true) + result.defines[#result.defines].extends['desc'] = getDesc(set) + result.defines[#result.defines].extends['rawdesc'] = getDesc(set, true) end end if #result.defines == 0 then @@ -284,6 +297,18 @@ function export.export(outputPath, callback) return docPath, mdPath end +function export.getDocOutputPath() + local doc_output_path = '' + if type(DOC_OUT_PATH) == 'string' then + doc_output_path = fs.absolute(fs.path(DOC_OUT_PATH)):string() + elseif DOC_OUT_PATH == true then + doc_output_path = fs.current_path():string() + else + doc_output_path = LOGPATH + end + return doc_output_path +end + ---@async ---@param outputPath string function export.makeDoc(outputPath) @@ -342,7 +367,7 @@ function export.runCLI() ws.awaitReady(rootUri) await.sleep(0.1) - local docPath, mdPath = export.export(LOGPATH, function (i, max) + local docPath, mdPath = export.export(export.getDocOutputPath(), function (i, max) if os.clock() - lastClock > 0.2 then lastClock = os.clock() local output = '\x0D' diff --git a/script/cli/init.lua b/script/cli/init.lua index b5a9f86d..6d7fc0ff 100644 --- a/script/cli/init.lua +++ b/script/cli/init.lua @@ -12,3 +12,8 @@ if _G['DOC'] then require 'cli.doc' .runCLI() os.exit(0, true) end + +if _G['VISUALIZE'] then + local ret = require 'cli.visualize' .runCLI() + os.exit(ret or 0, true) +end diff --git a/script/cli/visualize.lua b/script/cli/visualize.lua new file mode 100644 index 00000000..29269b82 --- /dev/null +++ b/script/cli/visualize.lua @@ -0,0 +1,103 @@ +local lang = require 'language' +local parser = require 'parser' +local guide = require 'parser.guide' + +local function nodeId(node) + return node.type .. ':' .. node.start .. ':' .. node.finish +end + +local function shorten(str) + if type(str) ~= 'string' then + return str + end + str = str:gsub('\n', '\\\\n') + if #str <= 20 then + return str + else + return str:sub(1, 17) .. '...' + end +end + +local function getTooltipLine(k, v) + if type(v) == 'table' then + if v.type then + v = '<node ' .. v.type .. '>' + else + v = '<table>' + end + end + v = tostring(v) + v = v:gsub('"', '\\"') + return k .. ': ' .. shorten(v) .. '\\n' +end + +local function getTooltip(node) + local str = '' + local skipNodes = {parent = true, start = true, finish = true, type = true} + str = str .. getTooltipLine('start', node.start) + str = str .. getTooltipLine('finish', node.finish) + for k, v in pairs(node) do + if type(k) ~= 'number' and not skipNodes[k] then + str = str .. getTooltipLine(k, v) + end + end + for i = 1, math.min(#node, 15) do + str = str .. getTooltipLine(i, node[i]) + end + if #node > 15 then + str = str .. getTooltipLine('15..' .. #node, '(...)') + end + return str +end + +local nodeEntry = '\t"%s" [\n\t\tlabel="%s\\l%s\\l"\n\t\ttooltip="%s"\n\t]' +local function getNodeLabel(node) + local keyName = guide.getKeyName(node) + if node.type == 'binary' or node.type == 'unary' then + keyName = node.op.type + elseif node.type == 'label' or node.type == 'goto' then + keyName = node[1] + end + return nodeEntry:format(nodeId(node), node.type, shorten(keyName) or '', getTooltip(node)) +end + +local function getVisualizeVisitor(writer) + local function visitNode(node, parent) + if node == nil then return end + writer:write(getNodeLabel(node)) + writer:write('\n') + if parent then + writer:write(('\t"%s" -> "%s"'):format(nodeId(parent), nodeId(node))) + writer:write('\n') + end + guide.eachChild(node, function(child) + visitNode(child, node) + end) + end + return visitNode +end + + +local export = {} + +function export.visualizeAst(code, writer) + local state = parser.compile(code, 'Lua', _G['LUA_VER'] or 'Lua 5.4') + writer:write('digraph AST {\n') + writer:write('\tnode [shape = rect]\n') + getVisualizeVisitor(writer)(state.ast) + writer:write('}\n') +end + +function export.runCLI() + lang(LOCALE) + local file = _G['VISUALIZE'] + local code, err = io.open(file) + if not code then + io.stderr:write('failed to open ' .. file .. ': ' .. err) + return 1 + end + code = code:read('a') + return export.visualizeAst(code, io.stdout) +end + +return export |