summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2021-07-14 21:02:33 +0800
committer最萌小汐 <sumneko@hotmail.com>2021-07-14 21:02:33 +0800
commit834d5e70092d38c884b23fe2bc176ed06f362c69 (patch)
treeefd70348303f4d21249ffcb6e6b10779566b011c
parentad89a32126617db2e139edb90a4dac96bc0e0496 (diff)
downloadlua-language-server-834d5e70092d38c884b23fe2bc176ed06f362c69.zip
resolve #588
-rw-r--r--script/core/completion.lua20
-rw-r--r--script/core/hover/table.lua18
-rw-r--r--script/core/noder.lua4
-rw-r--r--script/core/searcher.lua7
-rw-r--r--script/parser/ast.lua17
-rw-r--r--script/parser/compile.lua3
-rw-r--r--script/parser/grammar.lua5
-rw-r--r--script/parser/guide.lua13
-rw-r--r--test/definition/table.lua6
-rw-r--r--test/hover/init.lua28
10 files changed, 103 insertions, 18 deletions
diff --git a/script/core/completion.lua b/script/core/completion.lua
index 8f8dda1c..986f6696 100644
--- a/script/core/completion.lua
+++ b/script/core/completion.lua
@@ -61,6 +61,19 @@ local function findNearestSource(ast, offset)
return source
end
+local function findNearestTableField(ast, offset)
+ local source
+ guide.eachSourceContain(ast.ast, offset, function (src)
+ if src.type == 'table'
+ or src.type == 'tablefield'
+ or src.type == 'tableindex'
+ or src.type == 'tableexp' then
+ source = src
+ end
+ end)
+ return source
+end
+
local function findParent(ast, text, offset)
for i = offset, 1, -1 do
local char = text:sub(i, i)
@@ -1357,7 +1370,8 @@ local function checkTableLiteralField(ast, text, offset, tbl, fields, results)
local mark = {}
for _, field in ipairs(tbl) do
if field.type == 'tablefield'
- or field.type == 'tableindex' then
+ or field.type == 'tableindex'
+ or field.type == 'tableexp' then
local name = guide.getKeyName(field)
if name then
mark[name] = true
@@ -1397,7 +1411,7 @@ local function checkTableLiteralField(ast, text, offset, tbl, fields, results)
end
local function checkTableLiteralFieldByCall(ast, text, offset, call, defs, index, results)
- local source = findNearestSource(ast, offset)
+ local source = findNearestTableField(ast, offset)
if not source then
return
end
@@ -1459,7 +1473,7 @@ end
local function tryTable(ast, text, offset, results)
offset = lookBackward.skipSpace(text, offset)
- local source = findNearestSource(ast, offset)
+ local source = findNearestTableField(ast, offset)
if not source then
return
end
diff --git a/script/core/hover/table.lua b/script/core/hover/table.lua
index bd0274cf..68a04b40 100644
--- a/script/core/hover/table.lua
+++ b/script/core/hover/table.lua
@@ -96,12 +96,20 @@ local function getKeyMap(fields)
end
end
table.sort(keys, function (a, b)
- local ta = typeSorter[type(a)]
- local tb = typeSorter[type(b)]
- if ta == tb then
- return tostring(a) < tostring(b)
+ if a == b then
+ return false
+ end
+ local ta = type(a)
+ local tb = type(b)
+ local tsa = typeSorter[ta]
+ local tsb = typeSorter[tb]
+ if tsa == tsb then
+ if ta == 'boolean' then
+ return a == true
+ end
+ return a < b
else
- return ta < tb
+ return tsa < tsb
end
end)
return keys
diff --git a/script/core/noder.lua b/script/core/noder.lua
index 566a7445..dd6ba22b 100644
--- a/script/core/noder.lua
+++ b/script/core/noder.lua
@@ -149,6 +149,8 @@ local function getKey(source)
and index.type ~= 'table' then
return ANY_FIELD_CHAR, source.parent
end
+ elseif source.type == 'tableexp' then
+ return tostring(source.tindex), source.parent
elseif source.type == 'table' then
return 't:' .. source.start, nil
elseif source.type == 'label' then
@@ -1084,7 +1086,7 @@ function m.compileNode(noders, source)
elseif firstField.type == 'tableindex' then
pushForward(noders, keyID, getID(firstField.index))
pushForward(noders, valueID, getID(firstField.value))
- else
+ elseif firstField.type == 'tableexp' then
pushForward(noders, keyID, 'dn:integer')
pushForward(noders, valueID, getID(firstField))
end
diff --git a/script/core/searcher.lua b/script/core/searcher.lua
index 5848b659..852f7b2a 100644
--- a/script/core/searcher.lua
+++ b/script/core/searcher.lua
@@ -62,6 +62,7 @@ function m.pushResult(status, mode, source, force)
or source.type == 'setindex'
or source.type == 'tableindex'
or source.type == 'tablefield'
+ or source.type == 'tableexp'
or source.type == 'function'
or source.type == 'table'
or source.type == 'doc.class.name'
@@ -103,6 +104,7 @@ function m.pushResult(status, mode, source, force)
or source.type == 'getindex'
or source.type == 'tableindex'
or source.type == 'tablefield'
+ or source.type == 'tableexp'
or source.type == 'function'
or source.type == 'table'
or source.type == 'string'
@@ -874,10 +876,7 @@ end
local function getField(status, source, mode)
if source.type == 'table' then
for _, field in ipairs(source) do
- if field.type == 'tablefield'
- or field.type == 'tableindex' then
- m.pushResult(status, mode, field)
- end
+ m.pushResult(status, mode, field)
end
return
end
diff --git a/script/parser/ast.lua b/script/parser/ast.lua
index aa02ae3d..18bff05c 100644
--- a/script/parser/ast.lua
+++ b/script/parser/ast.lua
@@ -1095,6 +1095,7 @@ local Defs = {
local wantField = true
local lastStart = start + 1
local fieldCount = 0
+ local n = 0
for i = 1, #tbl do
local field = tbl[i]
if field.type == ',' or field.type == ';' then
@@ -1119,6 +1120,10 @@ local Defs = {
lastStart = field.finish + 1
fieldCount = fieldCount + 1
tbl[fieldCount] = field
+ if field.type == 'tableexp' then
+ n = n + 1
+ field.tindex = n
+ end
end
end
for i = fieldCount + 1, #tbl do
@@ -1153,6 +1158,18 @@ local Defs = {
end
return obj
end,
+ TableExp = function (start, value, finish)
+ if not value then
+ return
+ end
+ local obj = {
+ type = 'tableexp',
+ start = start,
+ finish = finish-1,
+ value = value,
+ }
+ return obj
+ end,
FuncArgs = function (start, args, finish)
args.type = 'funcargs'
args.start = start
diff --git a/script/parser/compile.lua b/script/parser/compile.lua
index e1e07c54..207664cc 100644
--- a/script/parser/compile.lua
+++ b/script/parser/compile.lua
@@ -198,6 +198,9 @@ local vmMap = {
Compile(obj.index, obj)
Compile(obj.value, obj)
end,
+ ['tableexp'] = function (obj)
+ Compile(obj.value, obj)
+ end,
['index'] = function (obj)
Compile(obj.index, obj)
end,
diff --git a/script/parser/grammar.lua b/script/parser/grammar.lua
index 5120df20..1a3913e0 100644
--- a/script/parser/grammar.lua
+++ b/script/parser/grammar.lua
@@ -381,14 +381,17 @@ Table <- Sp ({} TL {| TableField* |} DirtyTR {})
-> Table
TableField <- COMMA
/ SEMICOLON
+ / Dots
/ NewIndex
/ NewField
- / Exp->NoNil
+ / TableExp
Index <- BL DirtyExp DirtyBR
NewIndex <- Sp ({} Index NeedAssign DirtyExp {})
-> NewIndex
NewField <- Sp ({} MustName ASSIGN DirtyExp {})
-> NewField
+TableExp <- Sp ({} Exp {})
+ -> TableExp
ExpFunction <- Function
-> ExpFunction
diff --git a/script/parser/guide.lua b/script/parser/guide.lua
index 2508b801..59794e5f 100644
--- a/script/parser/guide.lua
+++ b/script/parser/guide.lua
@@ -33,6 +33,7 @@ local type = type
---@field typeGeneric table<integer, parser.guide.object[]>
---@field tkey parser.guide.object
---@field tvalue parser.guide.object
+---@field tindex integer
---@field op parser.guide.object
---@field next parser.guide.object
---@field docParam parser.guide.object
@@ -102,6 +103,7 @@ m.childMap = {
['table'] = {'#'},
['tableindex'] = {'index', 'value'},
['tablefield'] = {'field', 'value'},
+ ['tableexp'] = {'value'},
['function'] = {'args', '#'},
['funcargs'] = {'#'},
['setmethod'] = {'node', 'method', 'value'},
@@ -770,7 +772,8 @@ function m.isSet(source)
or tp == 'setmethod'
or tp == 'setindex'
or tp == 'tablefield'
- or tp == 'tableindex' then
+ or tp == 'tableindex'
+ or tp == 'tableexp' then
return true
end
if tp == 'call' then
@@ -823,12 +826,12 @@ function m.getKeyNameOfLiteral(obj)
elseif tp == 'number' then
local n = obj[1]
if n then
- return ('%s'):format(formatNumber(obj[1]))
+ return formatNumber(obj[1])
end
elseif tp == 'integer' then
local n = obj[1]
if n then
- return ('%s'):format(formatNumber(obj[1]))
+ return formatNumber(obj[1])
end
elseif tp == 'boolean' then
local b = obj[1]
@@ -865,6 +868,8 @@ function m.getKeyName(obj)
or tp == 'setindex'
or tp == 'tableindex' then
return m.getKeyNameOfLiteral(obj.index)
+ elseif tp == 'tableexp' then
+ return tostring(obj.tindex)
elseif tp == 'field'
or tp == 'method'
or tp == 'doc.see.field' then
@@ -927,6 +932,8 @@ function m.getKeyType(obj)
or tp == 'setindex'
or tp == 'tableindex' then
return m.getKeyTypeOfLiteral(obj.index)
+ elseif tp == 'tableexp' then
+ return 'integer'
elseif tp == 'field'
or tp == 'method'
or tp == 'doc.see.field' then
diff --git a/test/definition/table.lua b/test/definition/table.lua
index ba2d2aa3..d63cc655 100644
--- a/test/definition/table.lua
+++ b/test/definition/table.lua
@@ -157,3 +157,9 @@ end
local t = f()
t.field1.<?x?>
]]
+
+TEST [[
+local t = { <!a!> }
+
+print(t[<?1?>])
+]]
diff --git a/test/hover/init.lua b/test/hover/init.lua
index 80f6009c..18482de5 100644
--- a/test/hover/init.lua
+++ b/test/hover/init.lua
@@ -818,7 +818,11 @@ local <?t?> = {
}
]]
[[
-local t: {}
+local t: {
+ [1]: string = "aaa",
+ [2]: string = "bbb",
+ [3]: string = "ccc",
+}
]]
TEST [[
@@ -1638,3 +1642,25 @@ global a.b: {
c: integer,
}
]]
+
+TEST [[
+local <?t?> = {
+ 'a', 'b', 'c',
+ [10] = 'd',
+ x = 'e',
+ y = 'f',
+ ['z'] = 'g',
+ [3] = 'h',
+}
+]]
+[[
+local t: {
+ x: string = "e",
+ y: string = "f",
+ z: string = "g",
+ [1]: string = "a",
+ [2]: string = "b",
+ [3]: string = "c"|"h",
+ [10]: string = "d",
+}
+]]