@@ -21,6 +21,7 @@ LUAU_FASTFLAG(LuauAttributeSyntax)
21
21
LUAU_FASTFLAGVARIABLE(LuauLeadingBarAndAmpersand2, false )
22
22
LUAU_FASTFLAGVARIABLE(LuauNativeAttribute, false )
23
23
LUAU_FASTFLAGVARIABLE(LuauAttributeSyntaxFunExpr, false )
24
+ LUAU_FASTFLAGVARIABLE(LuauDeclarationExtraPropData, false )
24
25
25
26
namespace Luau
26
27
{
@@ -796,7 +797,7 @@ AstStat* Parser::parseAttributeStat()
796
797
}
797
798
default :
798
799
return reportStatError (lexer.current ().location , {}, {},
799
- " Expected 'function', 'local function', 'declare function' or a function type declaration after attribute, but got %s intead " ,
800
+ " Expected 'function', 'local function', 'declare function' or a function type declaration after attribute, but got %s instead " ,
800
801
lexer.current ().toString ().c_str ());
801
802
}
802
803
}
@@ -835,7 +836,7 @@ AstStat* Parser::parseLocal(const AstArray<AstAttr*>& attributes)
835
836
{
836
837
if (FFlag::LuauAttributeSyntax && attributes.size != 0 )
837
838
{
838
- return reportStatError (lexer.current ().location , {}, {}, " Expected 'function' after local declaration with attribute, but got %s intead " ,
839
+ return reportStatError (lexer.current ().location , {}, {}, " Expected 'function' after local declaration with attribute, but got %s instead " ,
839
840
lexer.current ().toString ().c_str ());
840
841
}
841
842
@@ -909,8 +910,16 @@ AstStat* Parser::parseTypeAlias(const Location& start, bool exported)
909
910
910
911
AstDeclaredClassProp Parser::parseDeclaredClassMethod ()
911
912
{
913
+ Location start;
914
+
915
+ if (FFlag::LuauDeclarationExtraPropData)
916
+ start = lexer.current ().location ;
917
+
912
918
nextLexeme ();
913
- Location start = lexer.current ().location ;
919
+
920
+ if (!FFlag::LuauDeclarationExtraPropData)
921
+ start = lexer.current ().location ;
922
+
914
923
Name fnName = parseName (" function name" );
915
924
916
925
// TODO: generic method declarations CLI-39909
@@ -935,15 +944,15 @@ AstDeclaredClassProp Parser::parseDeclaredClassMethod()
935
944
expectMatchAndConsume (' )' , matchParen);
936
945
937
946
AstTypeList retTypes = parseOptionalReturnType ().value_or (AstTypeList{copy<AstType*>(nullptr , 0 ), nullptr });
938
- Location end = lexer.current ().location ;
947
+ Location end = FFlag::LuauDeclarationExtraPropData ? lexer. previousLocation () : lexer.current ().location ;
939
948
940
949
TempVector<AstType*> vars (scratchType);
941
950
TempVector<std::optional<AstArgumentName>> varNames (scratchOptArgName);
942
951
943
952
if (args.size () == 0 || args[0 ].name .name != " self" || args[0 ].annotation != nullptr )
944
953
{
945
- return AstDeclaredClassProp{
946
- fnName. name , reportTypeError (Location (start, end), {}, " 'self' must be present as the unannotated first parameter" ), true };
954
+ return AstDeclaredClassProp{fnName. name , FFlag::LuauDeclarationExtraPropData ? fnName. location : Location{},
955
+ reportTypeError (Location (start, end), {}, " 'self' must be present as the unannotated first parameter" ), true };
947
956
}
948
957
949
958
// Skip the first index.
@@ -963,15 +972,16 @@ AstDeclaredClassProp Parser::parseDeclaredClassMethod()
963
972
AstType* fnType = allocator.alloc <AstTypeFunction>(
964
973
Location (start, end), generics, genericPacks, AstTypeList{copy (vars), varargAnnotation}, copy (varNames), retTypes);
965
974
966
- return AstDeclaredClassProp{fnName.name , fnType, true };
975
+ return AstDeclaredClassProp{fnName.name , FFlag::LuauDeclarationExtraPropData ? fnName.location : Location{}, fnType, true ,
976
+ FFlag::LuauDeclarationExtraPropData ? Location (start, end) : Location{}};
967
977
}
968
978
969
979
AstStat* Parser::parseDeclaration (const Location& start, const AstArray<AstAttr*>& attributes)
970
980
{
971
981
// `declare` token is already parsed at this point
972
982
973
983
if (FFlag::LuauAttributeSyntax && (attributes.size != 0 ) && (lexer.current ().type != Lexeme::ReservedFunction))
974
- return reportStatError (lexer.current ().location , {}, {}, " Expected a function type declaration after attribute, but got %s intead " ,
984
+ return reportStatError (lexer.current ().location , {}, {}, " Expected a function type declaration after attribute, but got %s instead " ,
975
985
lexer.current ().toString ().c_str ());
976
986
977
987
if (lexer.current ().type == Lexeme::ReservedFunction)
@@ -1014,8 +1024,12 @@ AstStat* Parser::parseDeclaration(const Location& start, const AstArray<AstAttr*
1014
1024
if (vararg && !varargAnnotation)
1015
1025
return reportStatError (Location (start, end), {}, {}, " All declaration parameters must be annotated" );
1016
1026
1017
- return allocator.alloc <AstStatDeclareFunction>(Location (start, end), attributes, globalName.name , generics, genericPacks,
1018
- AstTypeList{copy (vars), varargAnnotation}, copy (varNames), retTypes);
1027
+ if (FFlag::LuauDeclarationExtraPropData)
1028
+ return allocator.alloc <AstStatDeclareFunction>(Location (start, end), attributes, globalName.name , globalName.location , generics,
1029
+ genericPacks, AstTypeList{copy (vars), varargAnnotation}, copy (varNames), vararg, varargLocation, retTypes);
1030
+ else
1031
+ return allocator.alloc <AstStatDeclareFunction>(Location (start, end), attributes, globalName.name , Location{}, generics, genericPacks,
1032
+ AstTypeList{copy (vars), varargAnnotation}, copy (varNames), false , Location{}, retTypes);
1019
1033
}
1020
1034
else if (AstName (lexer.current ().name ) == " class" )
1021
1035
{
@@ -1045,19 +1059,42 @@ AstStat* Parser::parseDeclaration(const Location& start, const AstArray<AstAttr*
1045
1059
const Lexeme begin = lexer.current ();
1046
1060
nextLexeme (); // [
1047
1061
1048
- std::optional<AstArray<char >> chars = parseCharArray ();
1062
+ if (FFlag::LuauDeclarationExtraPropData)
1063
+ {
1064
+ const Location nameBegin = lexer.current ().location ;
1065
+ std::optional<AstArray<char >> chars = parseCharArray ();
1049
1066
1050
- expectMatchAndConsume (' ]' , begin);
1051
- expectAndConsume (' :' , " property type annotation" );
1052
- AstType* type = parseType ();
1067
+ const Location nameEnd = lexer.previousLocation ();
1053
1068
1054
- // since AstName contains a char*, it can't contain null
1055
- bool containsNull = chars && (strnlen (chars->data , chars->size ) < chars->size );
1069
+ expectMatchAndConsume (' ]' , begin);
1070
+ expectAndConsume (' :' , " property type annotation" );
1071
+ AstType* type = parseType ();
1056
1072
1057
- if (chars && !containsNull)
1058
- props.push_back (AstDeclaredClassProp{AstName (chars->data ), type, false });
1073
+ // since AstName contains a char*, it can't contain null
1074
+ bool containsNull = chars && (strnlen (chars->data , chars->size ) < chars->size );
1075
+
1076
+ if (chars && !containsNull)
1077
+ props.push_back (AstDeclaredClassProp{
1078
+ AstName (chars->data ), Location (nameBegin, nameEnd), type, false , Location (begin.location , lexer.previousLocation ())});
1079
+ else
1080
+ report (begin.location , " String literal contains malformed escape sequence or \\ 0" );
1081
+ }
1059
1082
else
1060
- report (begin.location , " String literal contains malformed escape sequence or \\ 0" );
1083
+ {
1084
+ std::optional<AstArray<char >> chars = parseCharArray ();
1085
+
1086
+ expectMatchAndConsume (' ]' , begin);
1087
+ expectAndConsume (' :' , " property type annotation" );
1088
+ AstType* type = parseType ();
1089
+
1090
+ // since AstName contains a char*, it can't contain null
1091
+ bool containsNull = chars && (strnlen (chars->data , chars->size ) < chars->size );
1092
+
1093
+ if (chars && !containsNull)
1094
+ props.push_back (AstDeclaredClassProp{AstName (chars->data ), Location{}, type, false });
1095
+ else
1096
+ report (begin.location , " String literal contains malformed escape sequence or \\ 0" );
1097
+ }
1061
1098
}
1062
1099
else if (lexer.current ().type == ' [' )
1063
1100
{
@@ -1075,12 +1112,21 @@ AstStat* Parser::parseDeclaration(const Location& start, const AstArray<AstAttr*
1075
1112
indexer = parseTableIndexer (AstTableAccess::ReadWrite, std::nullopt);
1076
1113
}
1077
1114
}
1115
+ else if (FFlag::LuauDeclarationExtraPropData)
1116
+ {
1117
+ Location propStart = lexer.current ().location ;
1118
+ Name propName = parseName (" property name" );
1119
+ expectAndConsume (' :' , " property type annotation" );
1120
+ AstType* propType = parseType ();
1121
+ props.push_back (
1122
+ AstDeclaredClassProp{propName.name , propName.location , propType, false , Location (propStart, lexer.previousLocation ())});
1123
+ }
1078
1124
else
1079
1125
{
1080
1126
Name propName = parseName (" property name" );
1081
1127
expectAndConsume (' :' , " property type annotation" );
1082
1128
AstType* propType = parseType ();
1083
- props.push_back (AstDeclaredClassProp{propName.name , propType, false });
1129
+ props.push_back (AstDeclaredClassProp{propName.name , Location{}, propType, false });
1084
1130
}
1085
1131
}
1086
1132
@@ -1094,7 +1140,8 @@ AstStat* Parser::parseDeclaration(const Location& start, const AstArray<AstAttr*
1094
1140
expectAndConsume (' :' , " global variable declaration" );
1095
1141
1096
1142
AstType* type = parseType (/* in declaration context */ true );
1097
- return allocator.alloc <AstStatDeclareGlobal>(Location (start, type->location ), globalName->name , type);
1143
+ return allocator.alloc <AstStatDeclareGlobal>(
1144
+ Location (start, type->location ), globalName->name , FFlag::LuauDeclarationExtraPropData ? globalName->location : Location{}, type);
1098
1145
}
1099
1146
else
1100
1147
{
@@ -2391,7 +2438,7 @@ AstExpr* Parser::parseSimpleExpr()
2391
2438
if (lexer.current ().type != Lexeme::ReservedFunction)
2392
2439
{
2393
2440
return reportExprError (
2394
- start, {}, " Expected 'function' declaration after attribute, but got %s intead " , lexer.current ().toString ().c_str ());
2441
+ start, {}, " Expected 'function' declaration after attribute, but got %s instead " , lexer.current ().toString ().c_str ());
2395
2442
}
2396
2443
}
2397
2444
0 commit comments