From af68d1e84435b1fbbf30ef24658255206f1ff7b3 Mon Sep 17 00:00:00 2001 From: Crollie Rollz Date: Sun, 3 Apr 2022 01:45:58 +0800 Subject: [PATCH 1/4] fix(completion): OOP emitter should have `self` arg 3db634a3a2e48a97772065e7e9da4d29a07a8098 Align docFUnc with the call index, rather than assume it's always the 2nd arg (where "self" is concerned this is the 3rd arg) --- script/core/completion/completion.lua | 2 +- test/completion/common.lua | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua index 969de95aa..eadf2739b 100644 --- a/script/core/completion/completion.lua +++ b/script/core/completion/completion.lua @@ -1401,7 +1401,7 @@ local function getCallEnumsAndFuncs(source, index, oop, call) and doc.field[1] == source[1] then local eventName = noder.getFieldEventName(doc) if eventName and eventName == myEventName then - local docFunc = doc.extends.types[1].args[2].extends.types[1] + local docFunc = doc.extends.types[1].args[index].extends.types[1] results[#results+1] = { label = infer.viewDocFunction(docFunc), description = doc.comment, diff --git a/test/completion/common.lua b/test/completion/common.lua index 787549f71..22d9f554b 100644 --- a/test/completion/common.lua +++ b/test/completion/common.lua @@ -2640,9 +2640,9 @@ class2: TEST [[ --- @class Emit ---- @field on fun(eventName: string, cb: function) ---- @field on fun(eventName: '"died"', cb: fun(i: integer)) ---- @field on fun(eventName: '"won"', cb: fun(s: string)) +--- @field on fun(self: Emit, eventName: string, cb: function) +--- @field on fun(self: Emit, eventName: '"died"', cb: fun(i: integer)) +--- @field on fun(self: Emit, eventName: '"won"', cb: fun(s: string)) local emit = {} emit:on('') @@ -2656,6 +2656,22 @@ TEST [[ --- @field on fun(eventName: '"won"', cb: fun(s: string)) local emit = {} +emit.on('died', ) +]] +{ + [1] = { + label = 'fun(i: integer)', + kind = define.CompletionItemKind.Function, + } +} + +TEST [[ +--- @class Emit +--- @field on fun(self: Emit, eventName: string, cb: function) +--- @field on fun(self: Emit, eventName: '"died"', cb: fun(i: integer)) +--- @field on fun(self: Emit, eventName: '"won"', cb: fun(s: string)) +local emit = {} + emit:on('won', ) ]] { From 9f46e568af0a63e0db46596de3b32c779d27c5cd Mon Sep 17 00:00:00 2001 From: Crollie Rollz Date: Sun, 3 Apr 2022 02:10:57 +0800 Subject: [PATCH 2/4] fix(completion): call OOP emitter without colon syntax --- script/core/completion/completion.lua | 55 ++++++++++++++------------- script/core/noder.lua | 25 +++++++----- test/completion/common.lua | 16 ++++++++ 3 files changed, 61 insertions(+), 35 deletions(-) diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua index eadf2739b..e960af15a 100644 --- a/script/core/completion/completion.lua +++ b/script/core/completion/completion.lua @@ -1380,34 +1380,37 @@ local function getCallEnumsAndFuncs(source, index, oop, call) return end local results = {} - if currentIndex == 1 then - for _, doc in ipairs(class.fields) do - if doc.field ~= source - and doc.field[1] == source[1] then - local eventName = noder.getFieldEventName(doc) - if eventName then - results[#results+1] = { - label = ('%q'):format(eventName), - description = doc.comment, - kind = define.CompletionItemKind.EnumMember, - } + local valueBeforeIndex = index > 1 and call.args[index - 1][1] + + for _, doc in ipairs(class.fields) do + if doc.field ~= source + and doc.field[1] == source[1] then + local indexType = currentIndex + if not oop then + local args = noder.getFieldArgs(doc) + -- offset if doc's first arg is `self` + if args and args[1] and args[1].name[1] == 'self' then + indexType = indexType - 1 end end - end - elseif currentIndex == 2 then - local myEventName = call.args[index - 1][1] - for _, doc in ipairs(class.fields) do - if doc.field ~= source - and doc.field[1] == source[1] then - local eventName = noder.getFieldEventName(doc) - if eventName and eventName == myEventName then - local docFunc = doc.extends.types[1].args[index].extends.types[1] - results[#results+1] = { - label = infer.viewDocFunction(docFunc), - description = doc.comment, - kind = define.CompletionItemKind.Function, - insertText = buildInsertDocFunction(docFunc), - } + local eventName = noder.getFieldEventName(doc) + if eventName then + if indexType == 1 then + results[#results+1] = { + label = ('%q'):format(eventName), + description = doc.comment, + kind = define.CompletionItemKind.EnumMember, + } + elseif indexType == 2 then + if eventName == valueBeforeIndex then + local docFunc = doc.extends.types[1].args[index].extends.types[1] + results[#results+1] = { + label = infer.viewDocFunction(docFunc), + description = doc.comment, + kind = define.CompletionItemKind.Function, + insertText = buildInsertDocFunction(docFunc), + } + end end end end diff --git a/script/core/noder.lua b/script/core/noder.lua index fcc6b6f4b..1e5023395 100644 --- a/script/core/noder.lua +++ b/script/core/noder.lua @@ -140,11 +140,7 @@ local function getMethodNode(source) end end -local function getFieldEventName(field) - if field._eventName then - return field._eventName or nil - end - field._eventName = false +local function getFieldArgs(field) local fieldType = field.extends if not fieldType then return nil @@ -153,19 +149,29 @@ local function getFieldEventName(field) if not docFunc or docFunc.type ~= 'doc.type.function' then return nil end - local firstArg = docFunc.args and docFunc.args[1] + return docFunc.args +end + +local function getFieldEventName(field) + if field._eventName then + return field._eventName or nil + end + field._eventName = false + + local args = getFieldArgs(field) + local firstArg = args and args[1] if not firstArg then return nil end local secondArg if firstArg.name[1] == 'self' then - firstArg = docFunc.args[2] + firstArg = args[2] if not firstArg then return nil end - secondArg = docFunc.args[3] + secondArg = args[3] else - secondArg = docFunc.args[2] + secondArg = args[2] end if not secondArg then return @@ -1685,6 +1691,7 @@ function m.eachID(noders) return next, noders.source end +m.getFieldArgs = getFieldArgs m.getFieldEventName = getFieldEventName ---获取对象的noders diff --git a/test/completion/common.lua b/test/completion/common.lua index 22d9f554b..95903acbe 100644 --- a/test/completion/common.lua +++ b/test/completion/common.lua @@ -2681,6 +2681,22 @@ emit:on('won', ) } } +TEST [[ +--- @class Emit +--- @field on fun(self: Emit, eventName: string, cb: function) +--- @field on fun(self: Emit, eventName: '"died"', cb: fun(i: integer)) +--- @field on fun(self: Emit, eventName: '"won"', cb: fun(s: string)) +local emit = {} + +emit.on(emit, 'won', ) +]] +{ + [1] = { + label = 'fun(s: string)', + kind = define.CompletionItemKind.Function, + } +} + TEST [[ local function f() local inferCache From cd032f35f1922c663b0a67c41adee4996d5cb858 Mon Sep 17 00:00:00 2001 From: Crollie Rollz Date: Sun, 3 Apr 2022 02:47:37 +0800 Subject: [PATCH 3/4] fix(infer): check second arg for event name --- script/core/noder.lua | 3 ++- test/type_inference/init.lua | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/script/core/noder.lua b/script/core/noder.lua index 1e5023395..2a60baee6 100644 --- a/script/core/noder.lua +++ b/script/core/noder.lua @@ -887,7 +887,8 @@ local function compileCallParam(noders, call, sourceID) local eventNodeID for firstIndex, callArg in ipairs(call.args) do firstIndex = firstIndex - fixIndex - if firstIndex == 1 and callArg.type == 'string' then + if (firstIndex == 1 or firstIndex == 2) + and callArg.type == 'string' then if callArg[1] then eventNodeID = sformat('%s%s%s' , nodeID diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua index ef2d1f623..7316730eb 100644 --- a/test/type_inference/init.lua +++ b/test/type_inference/init.lua @@ -941,6 +941,17 @@ emit:on("died", function () end) ]] +TEST 'integer' [[ +--- @class Emit +--- @field on fun(self: Emit, eventName: string, cb: function) +--- @field on fun(self: Emit, eventName: '"died"', cb: fun(i: integer)) +--- @field on fun(self: Emit, eventName: '"won"', cb: fun(s: string)) +local emit = {} + +emit.on(self, "died", function () +end) +]] + TEST '👍' [[ ---@class 👍 local From 0173906aec91baa04cd1c8fcbdd2c4da0a058240 Mon Sep 17 00:00:00 2001 From: Crollie Rollz Date: Sun, 3 Apr 2022 03:48:16 +0800 Subject: [PATCH 4/4] fix formatting --- script/core/completion/completion.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua index e960af15a..30df047cd 100644 --- a/script/core/completion/completion.lua +++ b/script/core/completion/completion.lua @@ -1396,11 +1396,11 @@ local function getCallEnumsAndFuncs(source, index, oop, call) local eventName = noder.getFieldEventName(doc) if eventName then if indexType == 1 then - results[#results+1] = { - label = ('%q'):format(eventName), - description = doc.comment, - kind = define.CompletionItemKind.EnumMember, - } + results[#results+1] = { + label = ('%q'):format(eventName), + description = doc.comment, + kind = define.CompletionItemKind.EnumMember, + } elseif indexType == 2 then if eventName == valueBeforeIndex then local docFunc = doc.extends.types[1].args[index].extends.types[1]