diff options
Diffstat (limited to 'script/core/completion.lua')
-rw-r--r-- | script/core/completion.lua | 132 |
1 files changed, 63 insertions, 69 deletions
diff --git a/script/core/completion.lua b/script/core/completion.lua index e3980eca..acaaa276 100644 --- a/script/core/completion.lua +++ b/script/core/completion.lua @@ -1,19 +1,14 @@ local define = require 'proto.define' local files = require 'files' -local guide = require 'core.guide' +local searcher = require 'core.searcher' local matchKey = require 'core.matchkey' local vm = require 'vm' -local getLabel = require 'core.hover.label' local getName = require 'core.hover.name' local getArg = require 'core.hover.arg' -local getReturn = require 'core.hover.return' -local getDesc = require 'core.hover.description' local getHover = require 'core.hover' local config = require 'config' local util = require 'utility' local markdown = require 'provider.markdown' -local findSource = require 'core.find-source' -local await = require 'await' local parser = require 'parser' local keyWordMap = require 'core.keyword' local workspace = require 'workspace' @@ -21,6 +16,8 @@ local furi = require 'file-uri' local rpath = require 'workspace.require-path' local lang = require 'language' local lookBackward = require 'core.look-backward' +local guide = require 'parser.guide' +local infer = require 'core.infer' local DiagnosticModes = { 'disable-next-line', @@ -135,8 +132,8 @@ local function buildFunctionSnip(source, value, oop) end local function buildDetail(source) - local types = vm.getInferType(source, 0) - local literals = vm.getInferLiteral(source, 0) + local types = infer.searchAndViewInfers(source) + local literals = infer.searchAndViewLiterals(source) if literals then return types .. ' = ' .. literals else @@ -149,9 +146,9 @@ local function getSnip(source) if context <= 0 then return nil end - local defs = vm.getRefs(source, 0) + local defs = vm.getRefs(source) for _, def in ipairs(defs) do - def = guide.getObjectValue(def) or def + def = searcher.getObjectValue(def) or def if def ~= source and def.type == 'function' then local uri = guide.getUri(def) local text = files.getText(uri) @@ -273,8 +270,8 @@ local function checkLocal(ast, word, offset, results) if not matchKey(word, name) then goto CONTINUE end - if vm.hasType(source, 'function') then - for _, def in ipairs(vm.getDefs(source, 0)) do + if infer.hasType(source, 'function') then + for _, def in ipairs(vm.getDefs(source)) do if def.type == 'function' or def.type == 'doc.type.function' then local funcLabel = name .. getParams(def, false) @@ -417,7 +414,7 @@ local function checkFieldFromFieldToIndex(name, parent, word, start, offset) end local function checkFieldThen(name, src, word, start, offset, parent, oop, results) - local value = guide.getObjectValue(src) or src + local value = searcher.getObjectValue(src) or src local kind = define.CompletionItemKind.Field if value.type == 'function' or value.type == 'doc.type.function' then @@ -492,7 +489,7 @@ local function checkFieldOfRefs(refs, ast, word, start, offset, parent, oop, res end local funcLabel if config.config.completion.showParams then - local value = guide.getObjectValue(src) or src + local value = searcher.getObjectValue(src) or src if value.type == 'function' or value.type == 'doc.type.function' then funcLabel = name .. getParams(value, oop) @@ -539,16 +536,16 @@ end local function checkGlobal(ast, word, start, offset, parent, oop, results) local locals = guide.getVisibleLocals(ast.ast, offset) - local refs = vm.getGlobalSets '*' - checkFieldOfRefs(refs, ast, word, start, offset, parent, oop, results, locals, 'global') + local globals = vm.getGlobalSets '*' + checkFieldOfRefs(globals, ast, word, start, offset, parent, oop, results, locals, 'global') end local function checkField(ast, word, start, offset, parent, oop, results) if parent.tag == '_ENV' or parent.special == '_G' then - local refs = vm.getGlobalSets '*' - checkFieldOfRefs(refs, ast, word, start, offset, parent, oop, results) + local globals = vm.getGlobalSets '*' + checkFieldOfRefs(globals, ast, word, start, offset, parent, oop, results) else - local refs = vm.getFields(parent, 0) + local refs = vm.getRefs(parent, '*') checkFieldOfRefs(refs, ast, word, start, offset, parent, oop, results) end end @@ -1043,14 +1040,14 @@ local function mergeEnums(a, b, source) end end -local function checkTypingEnum(ast, text, offset, infers, str, results) +local function checkTypingEnum(ast, text, offset, defs, str, results) local enums = {} - for _, infer in ipairs(infers) do - if infer.source.type == 'doc.type.enum' - or infer.source.type == 'doc.resume' then + for _, def in ipairs(defs) do + if def.type == 'doc.type.enum' + or def.type == 'doc.resume' then enums[#enums+1] = { - label = infer.source[1], - description = infer.source.comment and infer.source.comment.text, + label = def[1], + description = def.comment and def.comment.text, kind = define.CompletionItemKind.EnumMember, } end @@ -1074,8 +1071,8 @@ local function checkEqualEnumLeft(ast, text, offset, source, results) return src end end) - local infers = vm.getInfers(source, 0) - checkTypingEnum(ast, text, offset, infers, str, results) + local defs = vm.getDefs(source) + checkTypingEnum(ast, text, offset, defs, str, results) end local function checkEqualEnum(ast, text, offset, results) @@ -1247,7 +1244,30 @@ function (%s)\ end"):format(table.concat(args, ', ')) end -local function getCallEnums(source, index) +local function pushCallEnumsAndFuncs(defs) + local results = {} + for _, def in ipairs(defs) do + if def.type == 'doc.type.enum' + or def.type == 'doc.resume' then + results[#results+1] = { + label = def[1], + description = def.comment, + kind = define.CompletionItemKind.EnumMember, + } + end + if def.type == 'doc.type.function' then + results[#results+1] = { + label = infer.viewDocFunction(def), + description = def.comment, + kind = define.CompletionItemKind.Function, + insertText = buildInsertDocFunction(def), + } + end + end + return results +end + +local function getCallEnumsAndFuncs(source, index) if source.type == 'function' and source.bindDocs then if not source.args then return @@ -1266,37 +1286,10 @@ local function getCallEnums(source, index) for _, doc in ipairs(source.bindDocs) do if doc.type == 'doc.param' and doc.param[1] == arg[1] then - local enums = {} - for _, enum in ipairs(vm.getDocEnums(doc.extends) or {}) do - enums[#enums+1] = { - label = enum[1], - description = enum.comment, - kind = define.CompletionItemKind.EnumMember, - } - end - for _, unit in ipairs(vm.getDocTypeUnits(doc.extends) or {}) do - if unit.type == 'doc.type.function' then - local text = files.getText(guide.getUri(unit)) - enums[#enums+1] = { - label = text:sub(unit.start, unit.finish), - description = doc.comment, - kind = define.CompletionItemKind.Function, - insertText = buildInsertDocFunction(unit), - } - end - end - return enums + return pushCallEnumsAndFuncs(vm.getDefs(doc.extends)) elseif doc.type == 'doc.vararg' and arg.type == '...' then - local enums = {} - for _, enum in ipairs(vm.getDocEnums(doc.vararg)) do - enums[#enums+1] = { - label = enum[1], - description = enum.comment, - kind = define.CompletionItemKind.EnumMember, - } - end - return enums + return pushCallEnumsAndFuncs(vm.getDefs(doc.vararg)) end end end @@ -1403,12 +1396,12 @@ local function checkTableLiteralFieldByCall(ast, text, offset, call, defs, index return end for _, def in ipairs(defs) do - local func = guide.getObjectValue(def) or def + local func = searcher.getObjectValue(def) or def local param = getFuncParamByCallIndex(func, index) if not param then goto CONTINUE end - local defs = vm.getDefFields(param, 0) + local defs = vm.getDefs(param, '*') for _, field in ipairs(defs) do local name = guide.getKeyName(field) if name and not mark[name] then @@ -1431,10 +1424,10 @@ local function tryCallArg(ast, text, offset, results) if arg and arg.type == 'function' then return end - local defs = vm.getDefs(call.node, 0) + local defs = vm.getDefs(call.node) for _, def in ipairs(defs) do - def = guide.getObjectValue(def) or def - local enums = getCallEnums(def, argIndex) + def = searcher.getObjectValue(def) or def + local enums = getCallEnumsAndFuncs(def, argIndex) if enums then mergeEnums(myResults, enums, arg) end @@ -1461,7 +1454,8 @@ local function tryTable(ast, text, offset, results) if source.type ~= 'table' then tbl = source.parent end - local defs = vm.getDefFields(tbl, 0) + local parent = tbl.parent + local defs = vm.getDefs(parent, '*') for _, field in ipairs(defs) do local name = guide.getKeyName(field) if name and not mark[name] then @@ -1560,7 +1554,7 @@ end local function tryLuaDocBySource(ast, offset, source, results) if source.type == 'doc.extends.name' then if source.parent.type == 'doc.class' then - for _, doc in ipairs(vm.getDocTypes '*') do + for _, doc in ipairs(vm.getDocDefines()) do if doc.type == 'doc.class.name' and doc.parent ~= source.parent and matchKey(source[1], doc[1]) then @@ -1578,7 +1572,7 @@ local function tryLuaDocBySource(ast, offset, source, results) end return true elseif source.type == 'doc.type.name' then - for _, doc in ipairs(vm.getDocTypes '*') do + for _, doc in ipairs(vm.getDocDefines()) do if (doc.type == 'doc.class.name' or doc.type == 'doc.alias.name') and doc.parent ~= source.parent and matchKey(source[1], doc[1]) then @@ -1652,7 +1646,7 @@ end local function tryLuaDocByErr(ast, offset, err, docState, results) if err.type == 'LUADOC_MISS_CLASS_EXTENDS_NAME' then - for _, doc in ipairs(vm.getDocTypes '*') do + for _, doc in ipairs(vm.getDocDefines()) do if doc.type == 'doc.class.name' and doc.parent ~= docState then results[#results+1] = { @@ -1662,7 +1656,7 @@ local function tryLuaDocByErr(ast, offset, err, docState, results) end end elseif err.type == 'LUADOC_MISS_TYPE_NAME' then - for _, doc in ipairs(vm.getDocTypes '*') do + for _, doc in ipairs(vm.getDocDefines()) do if (doc.type == 'doc.class.name' or doc.type == 'doc.alias.name') then results[#results+1] = { label = doc[1], @@ -1735,14 +1729,14 @@ local function buildLuaDocOfFunction(func) local returns = {} if func.args then for _, arg in ipairs(func.args) do - args[#args+1] = vm.getInferType(arg) + args[#args+1] = infer.searchAndViewInfers(arg) end end if func.returns then for _, rtns in ipairs(func.returns) do for n = 1, #rtns do if not returns[n] then - returns[n] = vm.getInferType(rtns[n]) + returns[n] = infer.searchAndViewInfers(rtns[n]) end end end |