mirror of
https://github.com/luau-lang/luau.git
synced 2024-11-15 14:25:44 +08:00
implement leading bar and ampersand in types (#1286)
Implements the [Leading `|` and `&` in types](https://rfcs.luau-lang.org/syntax-leading-bar-and-ampersand.html) RFC. The changes to the parser are exactly as described in the RFC. --------- Co-authored-by: Alexander McCord <11488393+alexmccord@users.noreply.github.com>
This commit is contained in:
parent
041b8ee4e7
commit
43bf7c4e05
@ -17,6 +17,7 @@ LUAU_FASTINTVARIABLE(LuauParseErrorLimit, 100)
|
|||||||
// flag so that we don't break production games by reverting syntax changes.
|
// flag so that we don't break production games by reverting syntax changes.
|
||||||
// See docs/SyntaxChanges.md for an explanation.
|
// See docs/SyntaxChanges.md for an explanation.
|
||||||
LUAU_FASTFLAGVARIABLE(DebugLuauDeferredConstraintResolution, false)
|
LUAU_FASTFLAGVARIABLE(DebugLuauDeferredConstraintResolution, false)
|
||||||
|
LUAU_FASTFLAGVARIABLE(LuauLeadingBarAndAmpersand, false)
|
||||||
|
|
||||||
namespace Luau
|
namespace Luau
|
||||||
{
|
{
|
||||||
@ -1523,7 +1524,11 @@ AstType* Parser::parseFunctionTypeTail(const Lexeme& begin, AstArray<AstGenericT
|
|||||||
AstType* Parser::parseTypeSuffix(AstType* type, const Location& begin)
|
AstType* Parser::parseTypeSuffix(AstType* type, const Location& begin)
|
||||||
{
|
{
|
||||||
TempVector<AstType*> parts(scratchType);
|
TempVector<AstType*> parts(scratchType);
|
||||||
parts.push_back(type);
|
|
||||||
|
if (!FFlag::LuauLeadingBarAndAmpersand || type != nullptr)
|
||||||
|
{
|
||||||
|
parts.push_back(type);
|
||||||
|
}
|
||||||
|
|
||||||
incrementRecursionCounter("type annotation");
|
incrementRecursionCounter("type annotation");
|
||||||
|
|
||||||
@ -1623,15 +1628,34 @@ AstTypeOrPack Parser::parseTypeOrPack()
|
|||||||
AstType* Parser::parseType(bool inDeclarationContext)
|
AstType* Parser::parseType(bool inDeclarationContext)
|
||||||
{
|
{
|
||||||
unsigned int oldRecursionCount = recursionCounter;
|
unsigned int oldRecursionCount = recursionCounter;
|
||||||
// recursion counter is incremented in parseSimpleType
|
// recursion counter is incremented in parseSimpleType and/or parseTypeSuffix
|
||||||
|
|
||||||
Location begin = lexer.current().location;
|
Location begin = lexer.current().location;
|
||||||
|
|
||||||
AstType* type = parseSimpleType(/* allowPack= */ false, /* in declaration context */ inDeclarationContext).type;
|
if (FFlag::LuauLeadingBarAndAmpersand)
|
||||||
|
{
|
||||||
|
AstType* type = nullptr;
|
||||||
|
|
||||||
recursionCounter = oldRecursionCount;
|
Lexeme::Type c = lexer.current().type;
|
||||||
|
if (c != '|' && c != '&')
|
||||||
|
{
|
||||||
|
type = parseSimpleType(/* allowPack= */ false, /* in declaration context */ inDeclarationContext).type;
|
||||||
|
recursionCounter = oldRecursionCount;
|
||||||
|
}
|
||||||
|
|
||||||
return parseTypeSuffix(type, begin);
|
AstType* typeWithSuffix = parseTypeSuffix(type, begin);
|
||||||
|
recursionCounter = oldRecursionCount;
|
||||||
|
|
||||||
|
return typeWithSuffix;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AstType* type = parseSimpleType(/* allowPack= */ false, /* in declaration context */ inDeclarationContext).type;
|
||||||
|
|
||||||
|
recursionCounter = oldRecursionCount;
|
||||||
|
|
||||||
|
return parseTypeSuffix(type, begin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type ::= nil | Name[`.' Name] [ `<' Type [`,' ...] `>' ] | `typeof' `(' expr `)' | `{' [PropList] `}'
|
// Type ::= nil | Name[`.' Name] [ `<' Type [`,' ...] `>' ] | `typeof' `(' expr `)' | `{' [PropList] `}'
|
||||||
|
@ -16,6 +16,7 @@ LUAU_FASTINT(LuauRecursionLimit);
|
|||||||
LUAU_FASTINT(LuauTypeLengthLimit);
|
LUAU_FASTINT(LuauTypeLengthLimit);
|
||||||
LUAU_FASTINT(LuauParseErrorLimit);
|
LUAU_FASTINT(LuauParseErrorLimit);
|
||||||
LUAU_FASTFLAG(DebugLuauDeferredConstraintResolution);
|
LUAU_FASTFLAG(DebugLuauDeferredConstraintResolution);
|
||||||
|
LUAU_FASTFLAG(LuauLeadingBarAndAmpersand);
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -3167,4 +3168,26 @@ TEST_CASE_FIXTURE(Fixture, "read_write_table_properties")
|
|||||||
LUAU_ASSERT(pr.errors.size() == 0);
|
LUAU_ASSERT(pr.errors.size() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE_FIXTURE(Fixture, "can_parse_leading_bar_unions_successfully")
|
||||||
|
{
|
||||||
|
ScopedFastFlag sff{FFlag::LuauLeadingBarAndAmpersand, true};
|
||||||
|
|
||||||
|
parse(R"(type A = | "Hello" | "World")");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE_FIXTURE(Fixture, "can_parse_leading_ampersand_intersections_successfully")
|
||||||
|
{
|
||||||
|
ScopedFastFlag sff{FFlag::LuauLeadingBarAndAmpersand, true};
|
||||||
|
|
||||||
|
parse(R"(type A = & { string } & { number })");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE_FIXTURE(Fixture, "mixed_leading_intersection_and_union_not_allowed")
|
||||||
|
{
|
||||||
|
ScopedFastFlag sff{FFlag::LuauLeadingBarAndAmpersand, true};
|
||||||
|
|
||||||
|
matchParseError("type A = & number | string | boolean", "Mixing union and intersection types is not allowed; consider wrapping in parentheses.");
|
||||||
|
matchParseError("type A = | number & string & boolean", "Mixing union and intersection types is not allowed; consider wrapping in parentheses.");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_SUITE_END();
|
TEST_SUITE_END();
|
||||||
|
Loading…
Reference in New Issue
Block a user