From 834d5e70092d38c884b23fe2bc176ed06f362c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Wed, 14 Jul 2021 21:02:33 +0800 Subject: resolve #588 --- script/core/completion.lua | 20 +++++++++++++++++--- script/core/hover/table.lua | 18 +++++++++++++----- script/core/noder.lua | 4 +++- script/core/searcher.lua | 7 +++---- script/parser/ast.lua | 17 +++++++++++++++++ script/parser/compile.lua | 3 +++ script/parser/grammar.lua | 5 ++++- script/parser/guide.lua | 13 ++++++++++--- test/definition/table.lua | 6 ++++++ test/hover/init.lua | 28 +++++++++++++++++++++++++++- 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 ---@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. ]] + +TEST [[ +local t = { } + +print(t[]) +]] 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 = { } ]] [[ -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 = { + '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", +} +]] -- cgit v1.2.3