diff options
-rw-r--r-- | changelog.md | 1 | ||||
-rw-r--r-- | script/core/hover/table.lua | 3 | ||||
-rw-r--r-- | script/parser/guide.lua | 97 | ||||
-rw-r--r-- | script/proto/define.lua | 4 | ||||
-rw-r--r-- | script/vm/getDocs.lua | 16 | ||||
-rw-r--r-- | script/vm/guideInterface.lua | 16 | ||||
-rw-r--r-- | script/workspace/workspace.lua | 40 | ||||
-rw-r--r-- | test/hover/init.lua | 17 | ||||
-rw-r--r-- | test/type_inference/init.lua | 13 |
9 files changed, 139 insertions, 68 deletions
diff --git a/changelog.md b/changelog.md index 81fe54b1..9ef83946 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,7 @@ ## 1.3.1 * `NEW` setting `hover.previewFields`: limit how many fields are shown in table hover +* `NEW` fully support `---@type Object[]` ## 1.3.0 `2020-12-1` diff --git a/script/core/hover/table.lua b/script/core/hover/table.lua index 9e850c3e..b43151ea 100644 --- a/script/core/hover/table.lua +++ b/script/core/hover/table.lua @@ -74,6 +74,9 @@ local function getFieldFast(src) end return value.type, util.viewLiteral(literal) end + if value.type == 'doc.field' then + return vm.getInferType(value) + end end local function getField(src, timeUp, mark, key) diff --git a/script/parser/guide.lua b/script/parser/guide.lua index 54841333..b3275045 100644 --- a/script/parser/guide.lua +++ b/script/parser/guide.lua @@ -1284,27 +1284,6 @@ function m.getNextRef(ref) return call end end - -- doc.type.array - if ref.type == 'doc.type' then - local arrays = {} - for _, typeUnit in ipairs(ref.types) do - if typeUnit.type == 'doc.type.array' then - arrays[#arrays+1] = typeUnit.node - end - end - -- 返回一个 dummy - -- TODO 用弱表维护唯一性? - return { - type = 'doc.type', - start = ref.start, - finish = ref.finish, - types = arrays, - parent = ref.parent, - array = true, - enums = {}, - resumes = {}, - } - end return nil end @@ -1409,18 +1388,17 @@ function m.checkSameSimpleInValueOfCallMetaTable(status, call, start, queue) end function m.checkSameSimpleInSpecialBranch(status, obj, start, queue) - if not status.interface.index then - return - end - local results = status.interface.index(obj) - if not results then - return - end - for _, res in ipairs(results) do - queue[#queue+1] = { - obj = res, - start = start + 1, - } + if status.interface.index then + local results = status.interface.index(obj) + if not results then + return + end + for _, res in ipairs(results) do + queue[#queue+1] = { + obj = res, + start = start + 1, + } + end end end @@ -1523,10 +1501,10 @@ end function m.checkSameSimpleByDoc(status, obj, start, queue, mode) if obj.type == 'doc.class.name' - or obj.type == 'doc.type.name' then - obj = m.getDocState(obj) - end - if obj.type == 'doc.class' then + or obj.type == 'doc.class' then + if obj.type == 'doc.class.name' then + obj = m.getDocState(obj) + end local classStart for _, doc in ipairs(obj.bindGroup) do if doc == obj then @@ -1578,10 +1556,30 @@ function m.checkSameSimpleByDoc(status, obj, start, queue, mode) m.checkSameSimpleOfRefByDocSource(status, obj, start, queue, mode) end return true + elseif obj.type == 'doc.type.name' then + local pieceResult = stepRefOfDocType(status, obj, 'def') + for _, res in ipairs(pieceResult) do + queue[#queue+1] = { + obj = res, + start = start, + force = true, + } + end + if mode == 'ref' then + m.checkSameSimpleOfRefByDocSource(status, m.getDocState(obj), start, queue, mode) + end + return true elseif obj.type == 'doc.field' then if mode ~= 'field' then return m.checkSameSimpleByDoc(status, obj.extends, start, queue, mode) end + elseif obj.type == 'doc.type.array' then + queue[#queue+1] = { + obj = obj.node, + start = start + 1, + force = true, + } + return true end end @@ -3047,30 +3045,6 @@ function m.inferCheckUpDoc(status, source) end end -function m.inferCheckFieldDoc(status, source) - -- 检查 string[] 的情况 - if source.type == 'getindex' then - local node = source.node - if not node then - return - end - local newStatus = m.status(status) - m.searchInfer(newStatus, node) - local ok - for _, infer in ipairs(newStatus.results) do - local src = infer.source - if src.type == 'doc.type.array' then - ok = true - status.results[#status.results+1] = { - type = infer.type:gsub('%[%]$', ''), - source = src.node, - } - end - end - return ok - end -end - function m.inferCheckUnary(status, source) if source.type ~= 'unary' then return @@ -3826,7 +3800,6 @@ function m.searchInfer(status, obj) local checked = m.inferCheckDoc(status, obj) or m.inferCheckUpDoc(status, obj) - or m.inferCheckFieldDoc(status, obj) or m.inferCheckLiteral(status, obj) or m.inferCheckUnary(status, obj) or m.inferCheckBinary(status, obj) diff --git a/script/proto/define.lua b/script/proto/define.lua index 1cbb8de9..67898f9b 100644 --- a/script/proto/define.lua +++ b/script/proto/define.lua @@ -14,7 +14,7 @@ function m.offset(lines, text, position) if start <= 0 or start > #text then return #text + 1 end - local offset = utf8.offset(text, position.character + 1, start) + local offset = utf8.offset(text, position.character + 1, start) or (#text + 1) return offset - 1 end @@ -29,7 +29,7 @@ function m.offsetOfWord(lines, text, position) if start <= 0 or start > #text then return #text + 1 end - local offset = utf8.offset(text, position.character + 1, start) + local offset = utf8.offset(text, position.character + 1, start) or (#text + 1) if offset > #text or text:sub(offset-1, offset):match '[%w_][^%w_]' then offset = offset - 1 diff --git a/script/vm/getDocs.lua b/script/vm/getDocs.lua index 0f4b537d..62e12d18 100644 --- a/script/vm/getDocs.lua +++ b/script/vm/getDocs.lua @@ -84,6 +84,22 @@ function vm.getDocTypes(name) return cache end +function vm.getDocClass(name) + local cache = vm.getCache('getDocClass')[name] + if cache ~= nil then + return cache + end + cache = {} + local results = getDocTypes(name) + for _, doc in ipairs(results) do + if doc.type == 'doc.class.name' then + cache[#cache+1] = doc + end + end + vm.getCache('getDocClass')[name] = cache + return cache +end + function vm.isMetaFile(uri) local status = files.getAst(uri) if not status then diff --git a/script/vm/guideInterface.lua b/script/vm/guideInterface.lua index e646def8..eb809c30 100644 --- a/script/vm/guideInterface.lua +++ b/script/vm/guideInterface.lua @@ -82,7 +82,23 @@ function vm.interface.global(name) return vm.getGlobals(name) end +local basicTypes = { + ['any'] = true, + ['nil'] = true, + ['boolean'] = true, + ['number'] = true, + ['integer'] = true, + ['thread'] = true, + ['table'] = true, + ['string'] = true, + ['userdata'] = true, + ['lightuserdata'] = true, + ['function'] = true, +} function vm.interface.docType(name) + if basicTypes[name] then + return vm.getDocClass(name) + end await.delay() return vm.getDocTypes(name) end diff --git a/script/workspace/workspace.lua b/script/workspace/workspace.lua index 13208b75..a6425a8b 100644 --- a/script/workspace/workspace.lua +++ b/script/workspace/workspace.lua @@ -198,6 +198,41 @@ local function loadFileFactory(root, progress, isLibrary) end end +local function testProgress() + local client = require 'provider.client' + proto.notify('$/progress', { + token = client.info.workDoneToken, + value = { + kind = 'begin', + title = '测试标题', + cancellable = false, + message = '测试描述', + percentage = 0, + } + }) + for i = 1, 100 do + await.sleep(0.1) + log.info('sleep', i) + proto.notify('$/progress', { + token = client.info.workDoneToken, + value = { + kind = 'report', + cancellable = false, + message = '测试描述', + percentage = i, + } + }) + end + await.sleep(0.1) + proto.notify('$/progress', { + token = client.info.workDoneToken, + value = { + kind = 'end', + message = '测试描述', + } + }) +end + --- 预读工作区内所有文件 function m.awaitPreload() await.close 'preload' @@ -232,10 +267,7 @@ function m.awaitPreload() await.sleep(0.1) end - --for i = 1, 100 do - -- await.sleep(0.1) - -- log.info('sleep', i) - --end + --testProgress() log.info('Preload finish.') diff --git a/test/hover/init.lua b/test/hover/init.lua index 333234a6..ed16595a 100644 --- a/test/hover/init.lua +++ b/test/hover/init.lua @@ -1442,3 +1442,20 @@ local <?y?> [[ local y: any ]] + +TEST [[ +---@class Object +---@field a string + +---@type Object[] +local t + +local <?v?> = t[1] + +print(v.a) +]] +[[ +local v: Object { + a: string, +} +]] diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua index 40831c07..84462da6 100644 --- a/test/type_inference/init.lua +++ b/test/type_inference/init.lua @@ -329,3 +329,16 @@ local <?x?> TEST 'table' [[ self.<?t?>[#self.t+1] = {} ]] + +TEST 'string' [[ +---@type string[] +local x +local <?y?> = x[1] +]] + +TEST 'string' [[ +---@return string[] +local function f() end +local x = f() +local <?y?> = x[1] +]] |