@@ -24,6 +24,7 @@ LUAU_FASTFLAGVARIABLE(LuauParseStringIndexer)
2424LUAU_FASTFLAGVARIABLE(LuauStoreReturnTypesAsPackOnAst)
2525LUAU_FASTFLAGVARIABLE(LuauStoreLocalAnnotationColonPositions)
2626LUAU_FASTFLAGVARIABLE(LuauCSTForReturnTypeFunctionTail)
27+ LUAU_FASTFLAGVARIABLE(LuauParseAttributeFixUninit)
2728LUAU_DYNAMIC_FASTFLAGVARIABLE(DebugLuauReportReturnTypeVariadicWithTypeSuffix, false )
2829
2930// Clip with DebugLuauReportReturnTypeVariadicWithTypeSuffix
@@ -808,8 +809,10 @@ AstStat* Parser::parseFunctionStat(const AstArray<AstAttr*>& attributes)
808809}
809810
810811
811- std::pair<bool , AstAttr::Type> Parser::validateAttribute (const char * attributeName, const TempVector<AstAttr*>& attributes)
812+ std::pair<bool , AstAttr::Type> Parser::validateAttribute_DEPRECATED (const char * attributeName, const TempVector<AstAttr*>& attributes)
812813{
814+ LUAU_ASSERT (!FFlag::LuauParseAttributeFixUninit);
815+
813816 AstAttr::Type type;
814817
815818 // check if the attribute name is valid
@@ -848,20 +851,69 @@ std::pair<bool, AstAttr::Type> Parser::validateAttribute(const char* attributeNa
848851 return {found, type};
849852}
850853
854+ std::optional<AstAttr::Type> Parser::validateAttribute (const char * attributeName, const TempVector<AstAttr*>& attributes)
855+ {
856+ LUAU_ASSERT (FFlag::LuauParseAttributeFixUninit);
857+
858+ // check if the attribute name is valid
859+ std::optional<AstAttr::Type> type;
860+
861+ for (int i = 0 ; kAttributeEntries [i].name ; ++i)
862+ {
863+ if (strcmp (attributeName, kAttributeEntries [i].name ) == 0 )
864+ {
865+ type = kAttributeEntries [i].type ;
866+ break ;
867+ }
868+ }
869+
870+ if (!type)
871+ {
872+ if (strlen (attributeName) == 1 )
873+ report (lexer.current ().location , " Attribute name is missing" );
874+ else
875+ report (lexer.current ().location , " Invalid attribute '%s'" , attributeName);
876+ }
877+ else
878+ {
879+ // check that attribute is not duplicated
880+ for (const AstAttr* attr : attributes)
881+ {
882+ if (attr->type == *type)
883+ report (lexer.current ().location , " Cannot duplicate attribute '%s'" , attributeName);
884+ }
885+ }
886+
887+ return type;
888+ }
889+
851890// attribute ::= '@' NAME
852891void Parser::parseAttribute (TempVector<AstAttr*>& attributes)
853892{
854893 LUAU_ASSERT (lexer.current ().type == Lexeme::Type::Attribute);
855894
856895 Location loc = lexer.current ().location ;
857896
858- const char * name = lexer.current ().name ;
859- const auto [found, type] = validateAttribute (name, attributes);
897+ if (FFlag::LuauParseAttributeFixUninit)
898+ {
899+ const char * name = lexer.current ().name ;
900+ std::optional<AstAttr::Type> type = validateAttribute (name, attributes);
901+
902+ nextLexeme ();
860903
861- nextLexeme ();
904+ if (type)
905+ attributes.push_back (allocator.alloc <AstAttr>(loc, *type));
906+ }
907+ else
908+ {
909+ const char * name = lexer.current ().name ;
910+ const auto [found, type] = validateAttribute_DEPRECATED (name, attributes);
911+
912+ nextLexeme ();
862913
863- if (found)
864- attributes.push_back (allocator.alloc <AstAttr>(loc, type));
914+ if (found)
915+ attributes.push_back (allocator.alloc <AstAttr>(loc, type));
916+ }
865917}
866918
867919// attributes ::= {attribute}
0 commit comments