@@ -842,7 +842,29 @@ struct AstSerialize : public Luau::AstVisitor
842842 const auto * cstNode = lookupCstNode<Luau::CstExprFunction>(node);
843843
844844 lua_rawcheckstack (L, 3 );
845- lua_createtable (L, 0 , 7 );
845+ lua_createtable (L, 0 , 9 );
846+
847+ if (node->generics .size > 0 || node->genericPacks .size > 0 )
848+ {
849+ if (cstNode)
850+ serializeToken (cstNode->openGenericsPosition , " <" );
851+ else
852+ lua_pushnil (L);
853+ lua_setfield (L, -2 , " openGenerics" );
854+
855+ auto commas = cstNode ? cstNode->genericsCommaPositions : Luau::AstArray<Luau::Position>{};
856+ serializePunctuated (node->generics , commas, " ," );
857+ lua_setfield (L, -2 , " generics" );
858+
859+ serializePunctuated (node->genericPacks , splitArray (commas, node->generics .size ), " ," );
860+ lua_setfield (L, -2 , " genericPacks" );
861+
862+ if (cstNode)
863+ serializeToken (cstNode->closeGenericsPosition , " >" );
864+ else
865+ lua_pushnil (L);
866+ lua_setfield (L, -2 , " closeGenerics" );
867+ }
846868
847869 if (node->self )
848870 serialize (node->self , /* createToken= */ false );
@@ -859,7 +881,7 @@ struct AstSerialize : public Luau::AstVisitor
859881 serializePunctuated (node->args , cstNode ? cstNode->argsCommaPositions : Luau::AstArray<Luau::Position>{}, " ," );
860882 lua_setfield (L, -2 , " parameters" );
861883
862- // TODO: generics, return types, etc.
884+ // TODO: return types
863885
864886 if (node->vararg )
865887 serialize (node->varargLocation );
@@ -1479,6 +1501,13 @@ struct AstSerialize : public Luau::AstVisitor
14791501 lua_setfield (L, -2 , " body" );
14801502 }
14811503
1504+ static Luau::AstArray<Luau::Position> splitArray (Luau::AstArray<Luau::Position> arr, size_t index)
1505+ {
1506+ if (arr.size < index)
1507+ return arr;
1508+ return {arr.data + index, arr.size - index};
1509+ }
1510+
14821511 void serializeStat (Luau::AstStatTypeAlias* node)
14831512 {
14841513 lua_rawcheckstack (L, 2 );
@@ -1500,7 +1529,27 @@ struct AstSerialize : public Luau::AstVisitor
15001529 serializeToken (node->nameLocation .begin , node->name .value );
15011530 lua_setfield (L, -2 , " name" );
15021531
1503- // TODO: generics
1532+ if (node->generics .size > 0 || node->genericPacks .size > 0 )
1533+ {
1534+ if (cstNode)
1535+ serializeToken (cstNode->genericsOpenPosition , " <" );
1536+ else
1537+ lua_pushnil (L);
1538+ lua_setfield (L, -2 , " openGenerics" );
1539+
1540+ auto commas = cstNode ? cstNode->genericsCommaPositions : Luau::AstArray<Luau::Position>{};
1541+ serializePunctuated (node->generics , commas, " ," );
1542+ lua_setfield (L, -2 , " generics" );
1543+
1544+ serializePunctuated (node->genericPacks , splitArray (commas, node->generics .size ), " ," );
1545+ lua_setfield (L, -2 , " genericPacks" );
1546+
1547+ if (cstNode)
1548+ serializeToken (cstNode->genericsClosePosition , " >" );
1549+ else
1550+ lua_pushnil (L);
1551+ lua_setfield (L, -2 , " closeGenerics" );
1552+ }
15041553
15051554 if (cstNode)
15061555 {
@@ -1950,6 +1999,62 @@ struct AstSerialize : public Luau::AstVisitor
19501999 lua_setfield (L, -2 , " closeParens" );
19512000 }
19522001
2002+ void serializeType (Luau::AstGenericType* node)
2003+ {
2004+ lua_rawcheckstack (L, 2 );
2005+ lua_createtable (L, 0 , preambleSize + 3 );
2006+
2007+ serializeNodePreamble (node, " generic" );
2008+
2009+ const auto cstNode = lookupCstNode<Luau::CstGenericType>(node);
2010+
2011+ serializeToken (node->location .begin , node->name .value );
2012+ lua_setfield (L, -2 , " name" );
2013+
2014+ if (node->defaultValue && cstNode)
2015+ serializeToken (*cstNode->defaultEqualsPosition , " =" );
2016+ else
2017+ lua_pushnil (L);
2018+ lua_setfield (L, -2 , " equals" );
2019+
2020+ if (node->defaultValue )
2021+ node->defaultValue ->visit (this );
2022+ else
2023+ lua_pushnil (L);
2024+ lua_setfield (L, -2 , " default" );
2025+ }
2026+
2027+ void serializeType (Luau::AstGenericTypePack* node)
2028+ {
2029+ lua_rawcheckstack (L, 2 );
2030+ lua_createtable (L, 0 , preambleSize + 3 );
2031+
2032+ serializeNodePreamble (node, " generic" );
2033+
2034+ const auto cstNode = lookupCstNode<Luau::CstGenericTypePack>(node);
2035+
2036+ serializeToken (node->location .begin , node->name .value );
2037+ lua_setfield (L, -2 , " name" );
2038+
2039+ if (cstNode)
2040+ serializeToken (cstNode->ellipsisPosition , " ..." );
2041+ else
2042+ lua_pushnil (L);
2043+ lua_setfield (L, -2 , " ellipsis" );
2044+
2045+ if (node->defaultValue && cstNode)
2046+ serializeToken (*cstNode->defaultEqualsPosition , " =" );
2047+ else
2048+ lua_pushnil (L);
2049+ lua_setfield (L, -2 , " equals" );
2050+
2051+ if (node->defaultValue )
2052+ node->defaultValue ->visit (this );
2053+ else
2054+ lua_pushnil (L);
2055+ lua_setfield (L, -2 , " default" );
2056+ }
2057+
19532058 void serializeType (Luau::AstTypeError* node)
19542059 {
19552060 // TODO: types
@@ -2348,6 +2453,18 @@ struct AstSerialize : public Luau::AstVisitor
23482453 serializeType (node);
23492454 return false ;
23502455 }
2456+
2457+ bool visit (Luau::AstGenericType* node) override
2458+ {
2459+ serializeType (node);
2460+ return false ;
2461+ }
2462+
2463+ bool visit (Luau::AstGenericTypePack* node) override
2464+ {
2465+ serializeType (node);
2466+ return false ;
2467+ }
23512468};
23522469
23532470int luau_parse (lua_State* L)
0 commit comments