@@ -18,7 +18,9 @@ LUAU_FASTINTVARIABLE(LuauParseErrorLimit, 100)
18
18
// See docs/SyntaxChanges.md for an explanation.
19
19
LUAU_FASTFLAGVARIABLE(DebugLuauDeferredConstraintResolution, false )
20
20
LUAU_FASTFLAG(LuauAttributeSyntax)
21
- LUAU_FASTFLAGVARIABLE(LuauLeadingBarAndAmpersand, false )
21
+ LUAU_FASTFLAGVARIABLE(LuauLeadingBarAndAmpersand2, false )
22
+ LUAU_FASTFLAGVARIABLE(LuauNativeAttribute, false )
23
+ LUAU_FASTFLAGVARIABLE(LuauAttributeSyntaxFunExpr, false )
22
24
23
25
namespace Luau
24
26
{
@@ -29,7 +31,7 @@ struct AttributeEntry
29
31
AstAttr::Type type;
30
32
};
31
33
32
- AttributeEntry kAttributeEntries [] = {{" @checked" , AstAttr::Type::Checked}, {nullptr , AstAttr::Type::Checked}};
34
+ AttributeEntry kAttributeEntries [] = {{" @checked" , AstAttr::Type::Checked}, {" @native " , AstAttr::Type::Native}, { nullptr , AstAttr::Type::Checked}};
33
35
34
36
ParseError::ParseError (const Location& location, const std::string& message)
35
37
: location (location)
@@ -703,6 +705,10 @@ std::pair<bool, AstAttr::Type> Parser::validateAttribute(const char* attributeNa
703
705
if (found)
704
706
{
705
707
type = kAttributeEntries [i].type ;
708
+
709
+ if (!FFlag::LuauNativeAttribute && type == AstAttr::Type::Native)
710
+ found = false ;
711
+
706
712
break ;
707
713
}
708
714
}
@@ -772,7 +778,7 @@ AstStat* Parser::parseAttributeStat()
772
778
{
773
779
LUAU_ASSERT (FFlag::LuauAttributeSyntax);
774
780
775
- AstArray<AstAttr*> attributes = Parser:: parseAttributes ();
781
+ AstArray<AstAttr*> attributes = parseAttributes ();
776
782
777
783
Lexeme::Type type = lexer.current ().type ;
778
784
@@ -1654,7 +1660,7 @@ AstType* Parser::parseTypeSuffix(AstType* type, const Location& begin)
1654
1660
{
1655
1661
TempVector<AstType*> parts (scratchType);
1656
1662
1657
- if (!FFlag::LuauLeadingBarAndAmpersand || type != nullptr )
1663
+ if (!FFlag::LuauLeadingBarAndAmpersand2 || type != nullptr )
1658
1664
{
1659
1665
parts.push_back (type);
1660
1666
}
@@ -1682,6 +1688,8 @@ AstType* Parser::parseTypeSuffix(AstType* type, const Location& begin)
1682
1688
}
1683
1689
else if (c == ' ?' )
1684
1690
{
1691
+ LUAU_ASSERT (parts.size () >= 1 );
1692
+
1685
1693
Location loc = lexer.current ().location ;
1686
1694
nextLexeme ();
1687
1695
@@ -1714,7 +1722,7 @@ AstType* Parser::parseTypeSuffix(AstType* type, const Location& begin)
1714
1722
}
1715
1723
1716
1724
if (parts.size () == 1 )
1717
- return type;
1725
+ return FFlag::LuauLeadingBarAndAmpersand2 ? parts[ 0 ] : type;
1718
1726
1719
1727
if (isUnion && isIntersection)
1720
1728
{
@@ -1761,7 +1769,7 @@ AstType* Parser::parseType(bool inDeclarationContext)
1761
1769
1762
1770
Location begin = lexer.current ().location ;
1763
1771
1764
- if (FFlag::LuauLeadingBarAndAmpersand )
1772
+ if (FFlag::LuauLeadingBarAndAmpersand2 )
1765
1773
{
1766
1774
AstType* type = nullptr ;
1767
1775
@@ -2369,11 +2377,24 @@ static ConstantNumberParseResult parseDouble(double& result, const char* data)
2369
2377
return ConstantNumberParseResult::Ok;
2370
2378
}
2371
2379
2372
- // simpleexp -> NUMBER | STRING | NIL | true | false | ... | constructor | FUNCTION body | primaryexp
2380
+ // simpleexp -> NUMBER | STRING | NIL | true | false | ... | constructor | [attributes] FUNCTION body | primaryexp
2373
2381
AstExpr* Parser::parseSimpleExpr ()
2374
2382
{
2375
2383
Location start = lexer.current ().location ;
2376
2384
2385
+ AstArray<AstAttr*> attributes{nullptr , 0 };
2386
+
2387
+ if (FFlag::LuauAttributeSyntax && FFlag::LuauAttributeSyntaxFunExpr && lexer.current ().type == Lexeme::Attribute)
2388
+ {
2389
+ attributes = parseAttributes ();
2390
+
2391
+ if (lexer.current ().type != Lexeme::ReservedFunction)
2392
+ {
2393
+ return reportExprError (
2394
+ start, {}, " Expected 'function' declaration after attribute, but got %s intead" , lexer.current ().toString ().c_str ());
2395
+ }
2396
+ }
2397
+
2377
2398
if (lexer.current ().type == Lexeme::ReservedNil)
2378
2399
{
2379
2400
nextLexeme ();
@@ -2397,7 +2418,7 @@ AstExpr* Parser::parseSimpleExpr()
2397
2418
Lexeme matchFunction = lexer.current ();
2398
2419
nextLexeme ();
2399
2420
2400
- return parseFunctionBody (false , matchFunction, AstName (), nullptr , AstArray<AstAttr*>({ nullptr , 0 }) ).first ;
2421
+ return parseFunctionBody (false , matchFunction, AstName (), nullptr , attributes ).first ;
2401
2422
}
2402
2423
else if (lexer.current ().type == Lexeme::Number)
2403
2424
{
0 commit comments