@@ -22,6 +22,7 @@ LUAU_DYNAMIC_FASTFLAGVARIABLE(DebugLuauReportReturnTypeVariadicWithTypeSuffix, f
2222LUAU_FASTFLAGVARIABLE(LuauParseIncompleteInterpStringsWithLocation)
2323LUAU_FASTFLAGVARIABLE(LuauParametrizedAttributeSyntax)
2424LUAU_FASTFLAGVARIABLE(DebugLuauStringSingletonBasedOnQuotes)
25+ LUAU_FASTFLAGVARIABLE(LuauAutocompleteAttributes)
2526
2627// Clip with DebugLuauReportReturnTypeVariadicWithTypeSuffix
2728bool luau_telemetry_parsed_return_type_variadic_with_type_suffix = false;
@@ -934,8 +935,15 @@ void Parser::parseAttribute(TempVector<AstAttr*>& attributes)
934935
935936 nextLexeme ();
936937
937- if (type)
938- attributes.push_back (allocator.alloc <AstAttr>(loc, *type, empty));
938+ if (FFlag::LuauAutocompleteAttributes)
939+ {
940+ attributes.push_back (allocator.alloc <AstAttr>(loc, type.value_or (AstAttr::Type::Unknown), empty, AstName (name)));
941+ }
942+ else
943+ {
944+ if (type)
945+ attributes.push_back (allocator.alloc <AstAttr>(loc, *type, empty));
946+ }
939947 }
940948 else
941949 {
@@ -965,14 +973,30 @@ void Parser::parseAttribute(TempVector<AstAttr*>& attributes)
965973
966974 std::optional<AstAttr::Type> type = validateAttribute (nameLoc, attrName, attributes, args);
967975
968- if (type)
969- attributes.push_back (allocator.alloc <AstAttr>(Location (nameLoc, argsLocation), *type, args));
976+ if (FFlag::LuauAutocompleteAttributes)
977+ {
978+ attributes.push_back (
979+ allocator.alloc <AstAttr>(Location (nameLoc, argsLocation), type.value_or (AstAttr::Type::Unknown), args, AstName (attrName))
980+ );
981+ }
982+ else
983+ {
984+ if (type)
985+ attributes.push_back (allocator.alloc <AstAttr>(Location (nameLoc, argsLocation), *type, args));
986+ }
970987 }
971988 else
972989 {
973990 std::optional<AstAttr::Type> type = validateAttribute (nameLoc, attrName, attributes, empty);
974- if (type)
975- attributes.push_back (allocator.alloc <AstAttr>(nameLoc, *type, empty));
991+ if (FFlag::LuauAutocompleteAttributes)
992+ {
993+ attributes.push_back (allocator.alloc <AstAttr>(nameLoc, type.value_or (AstAttr::Type::Unknown), empty, AstName (attrName)));
994+ }
995+ else
996+ {
997+ if (type)
998+ attributes.push_back (allocator.alloc <AstAttr>(nameLoc, *type, empty));
999+ }
9761000 }
9771001
9781002 if (lexer.current ().type == ' ,' )
@@ -988,6 +1012,14 @@ void Parser::parseAttribute(TempVector<AstAttr*>& attributes)
9881012 else
9891013 {
9901014 report (Location (open.location , lexer.current ().location ), " Attribute list cannot be empty" );
1015+
1016+ if (FFlag::LuauAutocompleteAttributes)
1017+ {
1018+ // autocomplete expects at least one unknown attribute.
1019+ attributes.push_back (
1020+ allocator.alloc <AstAttr>(Location (open.location , lexer.current ().location ), AstAttr::Type::Unknown, empty, nameError)
1021+ );
1022+ }
9911023 }
9921024
9931025 expectMatchAndConsume (' ]' , open);
0 commit comments