From 174a333b2b505c8d83413c30f546daf6a269dfb3 Mon Sep 17 00:00:00 2001 From: Shararvev Date: Thu, 2 Jan 2025 17:43:21 +0500 Subject: [PATCH 1/2] #3014, #3015 Generic pattern supports optional, union, array and comment without a space. Fixed regression. --- changelog.md | 8 ++++---- script/parser/luadoc.lua | 35 +++++++++++++++++------------------ test/definition/luadoc.lua | 34 +++++++++++++++++++++++++++++++--- 3 files changed, 52 insertions(+), 25 deletions(-) diff --git a/changelog.md b/changelog.md index 8b5f93f76..2650369b1 100644 --- a/changelog.md +++ b/changelog.md @@ -2,14 +2,14 @@ ## Unreleased -* `CHG` [#3014] Generic pattern now supports definition after capture +* `CHG` [#3014] Generic pattern now supports definition after capture and optional, union, array ```lua ---@generic T - ---@param t `T`.Cat - ---@return T + ---@param t `T`.Cat? + ---@return T? local function f(t) end - local t = f('Smile') --> t is `Smile.Cat` + local t = f('Smile') --> t is `(Smile.Cat)?` ``` * `NEW` Test CLI: `--name=` `-n=`: run specify unit test * `FIX` Fixed the error that the configuration file pointed to by the `--configpath` option was not read and loaded. diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua index 3fec5c182..35f121748 100644 --- a/script/parser/luadoc.lua +++ b/script/parser/luadoc.lua @@ -72,7 +72,7 @@ Symbol <- ({} { er = '\r', et = '\t', ev = '\v', - name = (m.R('az', 'AZ', '09', '\x80\xff') + m.S('_')) * (m.R('az', 'AZ', '__', '09', '\x80\xff') + m.S('_.*-'))^0, + name = (m.R('az', 'AZ', '09', '\x80\xff') + m.S('_')) * (m.R('az', 'AZ', '09', '\x80\xff') + m.S('_.*-'))^0, Char10 = function (char) ---@type integer? char = tonumber(char) @@ -727,7 +727,6 @@ local function parseCodePattern(parent) return nil end local codeOffset - local finishOffset local content local i = 1 if tp == 'code' then @@ -736,41 +735,41 @@ local function parseCodePattern(parent) pattern = '%s' end while true do - i = i + 1 - local next, nextContent = peekToken(i) - if not next or TokenFinishs[Ci+i-1] + 1 ~= TokenStarts[Ci+i] then - if codeOffset then - finishOffset = i-1 - break - end + i = i+1 + local nextTp, nextContent = peekToken(i) + if not nextTp or TokenFinishs[Ci+i-1] + 1 ~= TokenStarts[Ci+i] then ---不连续的name,无效的 - return nil + break end - if next == 'name' then + if nextTp == 'name' then pattern = pattern .. nextContent - elseif next == 'code' then + elseif nextTp == 'code' then if codeOffset then -- 暂时不支持多generic - return nil + break end codeOffset = i pattern = pattern .. '%s' content = nextContent elseif codeOffset then -- should be match with Parser "name" mask - if next == 'integer' then + if nextTp == 'integer' then pattern = pattern .. nextContent - elseif next == 'symbol' and (nextContent == '.' or nextContent == '*' or nextContent == '-') then + elseif nextTp == 'symbol' and (nextContent == '.' or nextContent == '*' or nextContent == '-') then pattern = pattern .. nextContent else - return nil + break end else - return nil + break end end + if not codeOffset then + return nil + end nextToken() local start = getStart() + local finishOffset = i-1 if finishOffset == 1 then -- code only, no pattern pattern = nil @@ -932,7 +931,7 @@ function parseType(parent) local function pushResume() local comments for i = 0, 100 do - local nextComm = NextComment(i,'peek') + local nextComm = NextComment(i, true) if not nextComm then return false end diff --git a/test/definition/luadoc.lua b/test/definition/luadoc.lua index d6e0d467c..e7c2be22d 100644 --- a/test/definition/luadoc.lua +++ b/test/definition/luadoc.lua @@ -239,7 +239,7 @@ TEST [[ AAAA = {}; function AAAA:() - + end AAAA.a. @@ -352,7 +352,7 @@ local Foo = {} function Foo:bar1() end ---@generic T ----@param arg1 `T`* +---@param arg1 `T`*? ---@return T function Generic(arg1) print(arg1) end @@ -366,7 +366,7 @@ local Foo = {} function Foo:() end ---@generic T ----@param arg1 `T`* +---@param arg1 `T`*? ---@return T function Generic(arg1) print(arg1) end @@ -402,6 +402,34 @@ local v1 = Generic("Foo") print(v1.) ]] +TEST [[ +---@class n-Foo-2 +local Foo = {} +function Foo:bar1() end + +---@generic T +---@param arg1 n-`T`-2[] +---@return T +function Generic(arg1) print(arg1) end + +local v1 = Generic({Foo}) +print(v1.) +]] + +TEST [[ +---@class n-Foo-2 +local Foo = {} +function Foo:() end + +---@generic T +---@param arg1 n-`T`-2[] +---@return T +function Generic(arg1) print(arg1) end + +local v1 = Generic({"Foo"}) +print(v1.) +]] + TEST [[ ---@class A local t From 5f0efc4da14c8cb324056e092c87f07f60172115 Mon Sep 17 00:00:00 2001 From: Shararvev Date: Sun, 5 Jan 2025 05:32:12 +0500 Subject: [PATCH 2/2] Generic return can be optional. --- changelog.md | 1 + script/vm/generic.lua | 3 +++ test/diagnostics/missing-return.lua | 18 ++++++++++++++++++ test/type_inference/common.lua | 26 +++++++++++++++++++++++++- 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 2650369b1..5d8c483c9 100644 --- a/changelog.md +++ b/changelog.md @@ -13,6 +13,7 @@ ``` * `NEW` Test CLI: `--name=` `-n=`: run specify unit test * `FIX` Fixed the error that the configuration file pointed to by the `--configpath` option was not read and loaded. +* `FIX` Generic return can be optional. ## 3.13.5 `2024-12-20` diff --git a/script/vm/generic.lua b/script/vm/generic.lua index ed832d9bd..f1eaaf99d 100644 --- a/script/vm/generic.lua +++ b/script/vm/generic.lua @@ -136,6 +136,9 @@ function mt:resolve(uri, args) end end end + if protoNode:isOptional() then + result:addOptional() + end return result end diff --git a/test/diagnostics/missing-return.lua b/test/diagnostics/missing-return.lua index b8c1e7d37..33b50b16f 100644 --- a/test/diagnostics/missing-return.lua +++ b/test/diagnostics/missing-return.lua @@ -156,3 +156,21 @@ function F() end ]] + +TEST [[ +---@generic T +---@param t T +---@return T +function F(t) + return t +end +]] + +TEST [[ +---@generic T +---@param t T +---@return T? +function F(t) + +end +]] diff --git a/test/type_inference/common.lua b/test/type_inference/common.lua index 4140e2b01..5f0fd81a6 100644 --- a/test/type_inference/common.lua +++ b/test/type_inference/common.lua @@ -359,8 +359,32 @@ end local _, _, _, , _ = x(nil, true, 1, 'yy') ]] +TEST 'nil' [[ +local , = next() +local , = next({}) +]] + +TEST 'integer?' [[ +local , = next({1}) +]] + +TEST 'integer?' [[ +local a +local , v = next({a}) +]] + +-- probably explicit unknown generic should be unknown +TEST 'nil' [[ +local a +local k, = next({a}) +]] + TEST 'unknown' [[ -local = next() +---@generic T +---@param t T? +---@return T +local function F(t) end +local = F() ]] TEST 'unknown' [[