summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changelog.md1
-rw-r--r--script/core/hover/table.lua3
-rw-r--r--script/parser/guide.lua97
-rw-r--r--script/proto/define.lua4
-rw-r--r--script/vm/getDocs.lua16
-rw-r--r--script/vm/guideInterface.lua16
-rw-r--r--script/workspace/workspace.lua40
-rw-r--r--test/hover/init.lua17
-rw-r--r--test/type_inference/init.lua13
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]
+]]