2
2
#include " Luau/Ast.h"
3
3
4
4
#include " Luau/Common.h"
5
+ #include " Luau/StringUtils.h"
6
+
7
+ LUAU_FASTFLAG (LuauParametrizedAttributeSyntax)
5
8
6
9
namespace Luau
7
10
{
8
11
9
- static bool hasAttributeInArray (const AstArray<AstAttr*> attributes, AstAttr::Type attributeType)
12
+ static AstAttr* findAttributeInArray (const AstArray<AstAttr*> attributes, AstAttr::Type attributeType)
10
13
{
11
14
for (const auto attribute : attributes)
12
15
{
13
16
if (attribute->type == attributeType)
14
- return true ;
17
+ return attribute ;
15
18
}
16
19
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
+ }
18
39
}
19
40
20
41
static void visitTypeList (AstVisitor* visitor, const AstTypeList& list)
@@ -26,9 +47,10 @@ static void visitTypeList(AstVisitor* visitor, const AstTypeList& list)
26
47
list.tailType ->visit (visitor);
27
48
}
28
49
29
- AstAttr::AstAttr (const Location& location, Type type)
50
+ AstAttr::AstAttr (const Location& location, Type type, AstArray<AstExpr*> args )
30
51
: AstNode (ClassIndex (), location)
31
52
, type (type)
53
+ , args (args)
32
54
{
33
55
}
34
56
@@ -37,6 +59,29 @@ void AstAttr::visit(AstVisitor* visitor)
37
59
visitor->visit (this );
38
60
}
39
61
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
+
40
85
int gAstRttiIndex = 0 ;
41
86
42
87
AstGenericType::AstGenericType (const Location& location, AstName name, AstType* defaultValue)
@@ -293,6 +338,11 @@ bool AstExprFunction::hasAttribute(const AstAttr::Type attributeType) const
293
338
return hasAttributeInArray (attributes, attributeType);
294
339
}
295
340
341
+ AstAttr* AstExprFunction::getAttribute (const AstAttr::Type attributeType) const
342
+ {
343
+ return findAttributeInArray (attributes, attributeType);
344
+ }
345
+
296
346
AstExprTable::AstExprTable (const Location& location, const AstArray<Item>& items)
297
347
: AstExpr (ClassIndex (), location)
298
348
, items (items)
@@ -313,6 +363,19 @@ void AstExprTable::visit(AstVisitor* visitor)
313
363
}
314
364
}
315
365
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
+
316
379
AstExprUnary::AstExprUnary (const Location& location, Op op, AstExpr* expr)
317
380
: AstExpr (ClassIndex (), location)
318
381
, op (op)
@@ -917,6 +980,11 @@ bool AstStatDeclareFunction::hasAttribute(AstAttr::Type attributeType) const
917
980
return hasAttributeInArray (attributes, attributeType);
918
981
}
919
982
983
+ AstAttr* AstStatDeclareFunction::getAttribute (const AstAttr::Type attributeType) const
984
+ {
985
+ return findAttributeInArray (attributes, attributeType);
986
+ }
987
+
920
988
AstStatDeclareExternType::AstStatDeclareExternType (
921
989
const Location& location,
922
990
const AstName& name,
@@ -1085,6 +1153,11 @@ bool AstTypeFunction::hasAttribute(AstAttr::Type attributeType) const
1085
1153
return hasAttributeInArray (attributes, attributeType);
1086
1154
}
1087
1155
1156
+ AstAttr* AstTypeFunction::getAttribute (AstAttr::Type attributeType) const
1157
+ {
1158
+ return findAttributeInArray (attributes, attributeType);
1159
+ }
1160
+
1088
1161
AstTypeTypeof::AstTypeTypeof (const Location& location, AstExpr* expr)
1089
1162
: AstType (ClassIndex (), location)
1090
1163
, expr (expr)
@@ -1234,6 +1307,34 @@ bool isLValue(const AstExpr* expr)
1234
1307
return expr->is <AstExprLocal>() || expr->is <AstExprGlobal>() || expr->is <AstExprIndexName>() || expr->is <AstExprIndexExpr>();
1235
1308
}
1236
1309
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
+
1237
1338
AstName getIdentifier (AstExpr* node)
1238
1339
{
1239
1340
if (AstExprGlobal* expr = node->as <AstExprGlobal>())
0 commit comments