Skip to content

Commit 4774c8c

Browse files
authored
Merge pull request #1241 from FAForever/array-contents-support
Array contents support
2 parents f9b3b65 + a824f07 commit 4774c8c

File tree

4 files changed

+327
-36
lines changed

4 files changed

+327
-36
lines changed

script/core/completion/completion.lua

Lines changed: 57 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ local function trim(str)
5656
end
5757

5858
local function findNearestSource(state, position)
59+
---@type parser.object
5960
local source
6061
guide.eachSourceContain(state.ast, position, function (src)
6162
source = src
@@ -1132,32 +1133,42 @@ local function cleanEnums(enums, source)
11321133
return enums
11331134
end
11341135

1135-
local function checkTypingEnum(state, position, defs, str, results)
1136+
---@return boolean
1137+
local function insertEnum(state, src, enums, isInArray)
1138+
if src.type == 'doc.type.string'
1139+
or src.type == 'doc.type.integer'
1140+
or src.type == 'doc.type.boolean' then
1141+
---@cast src parser.object
1142+
enums[#enums+1] = {
1143+
label = vm.viewObject(src, state.uri),
1144+
description = src.comment,
1145+
kind = define.CompletionItemKind.EnumMember,
1146+
}
1147+
elseif src.type == 'doc.type.code' then
1148+
enums[#enums+1] = {
1149+
label = src[1],
1150+
description = src.comment,
1151+
kind = define.CompletionItemKind.EnumMember,
1152+
}
1153+
elseif isInArray and src.type == 'doc.type.array' then
1154+
for i, d in ipairs(vm.getDefs(src.node)) do
1155+
insertEnum(state, d, enums, isInArray)
1156+
end
1157+
end
1158+
end
1159+
1160+
local function checkTypingEnum(state, position, defs, str, results, isInArray)
11361161
local enums = {}
11371162
for _, def in ipairs(defs) do
1138-
if def.type == 'doc.type.string'
1139-
or def.type == 'doc.type.integer'
1140-
or def.type == 'doc.type.boolean' then
1141-
enums[#enums+1] = {
1142-
label = vm.viewObject(def, state.uri),
1143-
description = def.comment and def.comment.text,
1144-
kind = define.CompletionItemKind.EnumMember,
1145-
}
1146-
elseif def.type == 'doc.type.code' then
1147-
enums[#enums+1] = {
1148-
label = def[1],
1149-
description = def.comment and def.comment.text,
1150-
kind = define.CompletionItemKind.EnumMember,
1151-
}
1152-
end
1163+
insertEnum(state, def, enums, isInArray)
11531164
end
11541165
cleanEnums(enums, str)
11551166
for _, res in ipairs(enums) do
11561167
results[#results+1] = res
11571168
end
11581169
end
11591170

1160-
local function checkEqualEnumLeft(state, position, source, results)
1171+
local function checkEqualEnumLeft(state, position, source, results, isInArray)
11611172
if not source then
11621173
return
11631174
end
@@ -1167,7 +1178,7 @@ local function checkEqualEnumLeft(state, position, source, results)
11671178
end
11681179
end)
11691180
local defs = vm.getDefs(source)
1170-
checkTypingEnum(state, position, defs, str, results)
1181+
checkTypingEnum(state, position, defs, str, results, isInArray)
11711182
end
11721183

11731184
local function checkEqualEnum(state, position, results)
@@ -1211,9 +1222,14 @@ local function checkEqualEnumInString(state, position, results)
12111222
end
12121223
checkEqualEnumLeft(state, position, parent[1], results)
12131224
end
1225+
if (parent.type == 'tableexp') then
1226+
checkEqualEnumLeft(state, position, parent.parent.parent, results, true)
1227+
return
1228+
end
12141229
if parent.type == 'local' then
12151230
checkEqualEnumLeft(state, position, parent, results)
12161231
end
1232+
12171233
if parent.type == 'setlocal'
12181234
or parent.type == 'setglobal'
12191235
or parent.type == 'setfield'
@@ -1435,24 +1451,10 @@ local function tryCallArg(state, position, results)
14351451
if not node then
14361452
return
14371453
end
1454+
14381455
local enums = {}
14391456
for src in node:eachObject() do
1440-
if src.type == 'doc.type.string'
1441-
or src.type == 'doc.type.integer'
1442-
or src.type == 'doc.type.boolean' then
1443-
---@cast src parser.object
1444-
enums[#enums+1] = {
1445-
label = vm.viewObject(src, state.uri),
1446-
description = src.comment,
1447-
kind = define.CompletionItemKind.EnumMember,
1448-
}
1449-
elseif src.type == 'doc.type.code' then
1450-
enums[#enums+1] = {
1451-
label = src[1],
1452-
description = src.comment,
1453-
kind = define.CompletionItemKind.EnumMember,
1454-
}
1455-
end
1457+
insertEnum(state, src, enums, arg and arg.type == 'table')
14561458
if src.type == 'doc.type.function' then
14571459
---@cast src parser.object
14581460
local insertText = buildInsertDocFunction(src)
@@ -1496,6 +1498,7 @@ local function tryTable(state, position, results)
14961498
if source.type ~= 'table' then
14971499
tbl = source.parent
14981500
end
1501+
14991502
local defs = vm.getFields(tbl)
15001503
for _, field in ipairs(defs) do
15011504
local name = guide.getKeyName(field)
@@ -1507,6 +1510,25 @@ local function tryTable(state, position, results)
15071510
checkTableLiteralField(state, position, tbl, fields, results)
15081511
end
15091512

1513+
local function tryArray(state, position, results)
1514+
local source = findNearestSource(state, position)
1515+
if not source then
1516+
return
1517+
end
1518+
if source.type ~= 'table' and (not source.parent or source.parent.type ~= 'table') then
1519+
return
1520+
end
1521+
local tbl = source
1522+
if source.type ~= 'table' then
1523+
tbl = source.parent
1524+
end
1525+
if source.parent.type == 'callargs' and source.parent.parent.type == 'call' then
1526+
return
1527+
end
1528+
-- { } inside when enum
1529+
checkEqualEnumLeft(state, position, tbl, results, true)
1530+
end
1531+
15101532
local function getComment(state, position)
15111533
local offset = guide.positionToOffset(state, position)
15121534
local symbolOffset = lookBackward.findAnyOffset(state.lua, offset)
@@ -2001,6 +2023,7 @@ local function tryCompletions(state, position, triggerCharacter, results)
20012023
trySpecial(state, position, results)
20022024
tryCallArg(state, position, results)
20032025
tryTable(state, position, results)
2026+
tryArray(state, position, results)
20042027
tryWord(state, position, triggerCharacter, results)
20052028
tryIndex(state, position, results)
20062029
trySymbol(state, position, results)

script/parser/guide.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,7 @@ local isSetMap = {
889889
['doc.alias.name'] = true,
890890
['doc.field.name'] = true,
891891
['doc.type.field'] = true,
892+
['doc.type.array'] = true,
892893
}
893894
function m.isSet(source)
894895
local tp = source.type

script/vm/compiler.lua

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,7 @@ local function isValidCallArgNode(source, node)
805805
return node.type == 'doc.type.function'
806806
end
807807
if source.type == 'table' then
808-
return node.type == 'doc.type.table'
808+
return node.type == 'doc.type.table' or node.type == 'doc.type.array'
809809
or ( node.type == 'global'
810810
and node.cate == 'type'
811811
---@cast node vm.global
@@ -1274,6 +1274,7 @@ local compilerSwitch = util.switch()
12741274
or source.parent.type == 'setlocal'
12751275
or source.parent.type == 'tablefield'
12761276
or source.parent.type == 'tableindex'
1277+
or source.parent.type == 'tableexp'
12771278
or source.parent.type == 'setfield'
12781279
or source.parent.type == 'setindex' then
12791280
local parentNode = vm.compileNode(source.parent)
@@ -1284,7 +1285,7 @@ local compilerSwitch = util.switch()
12841285
if not guide.isBasicType(pn.name) then
12851286
vm.setNode(source, pn)
12861287
end
1287-
elseif pn.type == 'doc.type.table' then
1288+
elseif pn.type == 'doc.type.table' or pn.type == 'doc.type.array' then
12881289
vm.setNode(source, pn)
12891290
end
12901291
end
@@ -1490,6 +1491,14 @@ local compilerSwitch = util.switch()
14901491
end)
14911492
: case 'tableexp'
14921493
: call(function (source)
1494+
if (source.parent.type == 'table') then
1495+
local node = vm.compileNode(source.parent)
1496+
for n in node:eachObject() do
1497+
if n.type == 'doc.type.array' then
1498+
vm.setNode(source, vm.compileNode(n.node))
1499+
end
1500+
end
1501+
end
14931502
vm.setNode(source, vm.compileNode(source.value))
14941503
end)
14951504
: case 'function.return'

0 commit comments

Comments
 (0)