22#include " Luau/Ast.h"
33
44#include " Luau/Common.h"
5+ #include " Luau/StringUtils.h"
6+
7+ LUAU_FASTFLAG (LuauParametrizedAttributeSyntax)
58
69namespace Luau
710{
811
9- static bool hasAttributeInArray (const AstArray<AstAttr*> attributes, AstAttr::Type attributeType)
12+ static AstAttr* findAttributeInArray (const AstArray<AstAttr*> attributes, AstAttr::Type attributeType)
1013{
1114 for (const auto attribute : attributes)
1215 {
1316 if (attribute->type == attributeType)
14- return true ;
17+ return attribute ;
1518 }
1619
17- return false ;
20+ return nullptr ;
21+ }
22+
23+ static bool hasAttributeInArray (const AstArray<AstAttr*> attributes, AstAttr::Type attributeType)
24+ {
25+ if (FFlag::LuauParametrizedAttributeSyntax)
26+ {
27+ return findAttributeInArray (attributes, attributeType) != nullptr ;
28+ }
29+ else
30+ {
31+ for (const auto attribute : attributes)
32+ {
33+ if (attribute->type == attributeType)
34+ return true ;
35+ }
36+
37+ return false ;
38+ }
1839}
1940
2041static void visitTypeList (AstVisitor* visitor, const AstTypeList& list)
@@ -26,9 +47,10 @@ static void visitTypeList(AstVisitor* visitor, const AstTypeList& list)
2647 list.tailType ->visit (visitor);
2748}
2849
29- AstAttr::AstAttr (const Location& location, Type type)
50+ AstAttr::AstAttr (const Location& location, Type type, AstArray<AstExpr*> args )
3051 : AstNode (ClassIndex (), location)
3152 , type (type)
53+ , args (args)
3254{
3355}
3456
@@ -37,6 +59,29 @@ void AstAttr::visit(AstVisitor* visitor)
3759 visitor->visit (this );
3860}
3961
62+ AstAttr::DeprecatedInfo AstAttr::deprecatedInfo () const
63+ {
64+ AstAttr::DeprecatedInfo info;
65+ info.deprecated = type == AstAttr::Type::Deprecated;
66+
67+ if (info.deprecated && args.size > 0 )
68+ {
69+ AstExprTable* table = args.data [0 ]->as <AstExprTable>();
70+ if (auto useValue = table->getRecord (" use" ))
71+ {
72+ AstArray<char > use = (*useValue)->as <AstExprConstantString>()->value ;
73+ info.use = {{use.data , use.size }};
74+ }
75+ if (auto reasonValue = table->getRecord (" reason" ))
76+ {
77+ AstArray<char > reason = (*reasonValue)->as <AstExprConstantString>()->value ;
78+ info.reason = {{reason.data , reason.size }};
79+ }
80+ }
81+
82+ return info;
83+ }
84+
4085int gAstRttiIndex = 0 ;
4186
4287AstGenericType::AstGenericType (const Location& location, AstName name, AstType* defaultValue)
@@ -293,6 +338,11 @@ bool AstExprFunction::hasAttribute(const AstAttr::Type attributeType) const
293338 return hasAttributeInArray (attributes, attributeType);
294339}
295340
341+ AstAttr* AstExprFunction::getAttribute (const AstAttr::Type attributeType) const
342+ {
343+ return findAttributeInArray (attributes, attributeType);
344+ }
345+
296346AstExprTable::AstExprTable (const Location& location, const AstArray<Item>& items)
297347 : AstExpr (ClassIndex (), location)
298348 , items (items)
@@ -313,6 +363,19 @@ void AstExprTable::visit(AstVisitor* visitor)
313363 }
314364}
315365
366+ std::optional<AstExpr*> AstExprTable::getRecord (const char * key) const
367+ {
368+ for (const AstExprTable::Item& item : items)
369+ {
370+ if (item.kind == AstExprTable::Item::Kind::Record)
371+ {
372+ if (strcmp (item.key ->as <AstExprConstantString>()->value .data , key) == 0 )
373+ return item.value ;
374+ }
375+ }
376+ return {};
377+ }
378+
316379AstExprUnary::AstExprUnary (const Location& location, Op op, AstExpr* expr)
317380 : AstExpr (ClassIndex (), location)
318381 , op (op)
@@ -917,6 +980,11 @@ bool AstStatDeclareFunction::hasAttribute(AstAttr::Type attributeType) const
917980 return hasAttributeInArray (attributes, attributeType);
918981}
919982
983+ AstAttr* AstStatDeclareFunction::getAttribute (const AstAttr::Type attributeType) const
984+ {
985+ return findAttributeInArray (attributes, attributeType);
986+ }
987+
920988AstStatDeclareExternType::AstStatDeclareExternType (
921989 const Location& location,
922990 const AstName& name,
@@ -1085,6 +1153,11 @@ bool AstTypeFunction::hasAttribute(AstAttr::Type attributeType) const
10851153 return hasAttributeInArray (attributes, attributeType);
10861154}
10871155
1156+ AstAttr* AstTypeFunction::getAttribute (AstAttr::Type attributeType) const
1157+ {
1158+ return findAttributeInArray (attributes, attributeType);
1159+ }
1160+
10881161AstTypeTypeof::AstTypeTypeof (const Location& location, AstExpr* expr)
10891162 : AstType (ClassIndex (), location)
10901163 , expr (expr)
@@ -1234,6 +1307,34 @@ bool isLValue(const AstExpr* expr)
12341307 return expr->is <AstExprLocal>() || expr->is <AstExprGlobal>() || expr->is <AstExprIndexName>() || expr->is <AstExprIndexExpr>();
12351308}
12361309
1310+ bool isConstantLiteral (const AstExpr* expr)
1311+ {
1312+ return expr->is <AstExprConstantNil>() || expr->is <AstExprConstantBool>() || expr->is <AstExprConstantNumber>() ||
1313+ expr->is <AstExprConstantString>();
1314+ }
1315+
1316+ bool isLiteralTable (const AstExpr* expr)
1317+ {
1318+ if (!expr->is <AstExprTable>())
1319+ return false ;
1320+
1321+ for (const AstExprTable::Item& item : expr->as <AstExprTable>()->items )
1322+ {
1323+ switch (item.kind )
1324+ {
1325+ case AstExprTable::Item::Kind::General:
1326+ return false ;
1327+ break ;
1328+ case AstExprTable::Item::Kind::Record:
1329+ case AstExprTable::Item::Kind::List:
1330+ if (!isConstantLiteral (item.value ) && !isLiteralTable (item.value ))
1331+ return false ;
1332+ break ;
1333+ }
1334+ }
1335+ return true ;
1336+ }
1337+
12371338AstName getIdentifier (AstExpr* node)
12381339{
12391340 if (AstExprGlobal* expr = node->as <AstExprGlobal>())
0 commit comments