mirror of
https://github.com/luau-lang/luau.git
synced 2024-12-13 13:30:40 +00:00
Modify the way line breaks are added when printing unions/intersections (#1047)
Adds an option `compositeTypesSingleLineLimit` to control when unions/intersections are broken up onto multiple lines when printed. Simple unions/intersections will remain on one line. Default value is set to `5`. I took the liberty to always expand overloaded function intersections on multiple lines, as I believe they are best viewed that way, even if theres only 2 functions. Closes #963
This commit is contained in:
parent
984336448c
commit
1173e415ef
3 changed files with 70 additions and 5 deletions
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
LUAU_FASTINT(LuauTableTypeMaximumStringifierLength)
|
LUAU_FASTINT(LuauTableTypeMaximumStringifierLength)
|
||||||
LUAU_FASTINT(LuauTypeMaximumStringifierLength)
|
LUAU_FASTINT(LuauTypeMaximumStringifierLength)
|
||||||
|
LUAU_FASTFLAG(LuauToStringSimpleCompositeTypesSingleLine)
|
||||||
|
|
||||||
namespace Luau
|
namespace Luau
|
||||||
{
|
{
|
||||||
|
@ -39,6 +40,12 @@ struct ToStringNameMap
|
||||||
|
|
||||||
struct ToStringOptions
|
struct ToStringOptions
|
||||||
{
|
{
|
||||||
|
ToStringOptions(bool exhaustive = false)
|
||||||
|
: exhaustive(exhaustive)
|
||||||
|
, compositeTypesSingleLineLimit(FFlag::LuauToStringSimpleCompositeTypesSingleLine ? 5 : 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool exhaustive = false; // If true, we produce complete output rather than comprehensible output
|
bool exhaustive = false; // If true, we produce complete output rather than comprehensible output
|
||||||
bool useLineBreaks = false; // If true, we insert new lines to separate long results such as table entries/metatable.
|
bool useLineBreaks = false; // If true, we insert new lines to separate long results such as table entries/metatable.
|
||||||
bool functionTypeArguments = false; // If true, output function type argument names when they are available
|
bool functionTypeArguments = false; // If true, output function type argument names when they are available
|
||||||
|
@ -47,6 +54,7 @@ struct ToStringOptions
|
||||||
bool hideFunctionSelfArgument = false; // If true, `self: X` will be omitted from the function signature if the function has self
|
bool hideFunctionSelfArgument = false; // If true, `self: X` will be omitted from the function signature if the function has self
|
||||||
size_t maxTableLength = size_t(FInt::LuauTableTypeMaximumStringifierLength); // Only applied to TableTypes
|
size_t maxTableLength = size_t(FInt::LuauTableTypeMaximumStringifierLength); // Only applied to TableTypes
|
||||||
size_t maxTypeLength = size_t(FInt::LuauTypeMaximumStringifierLength);
|
size_t maxTypeLength = size_t(FInt::LuauTypeMaximumStringifierLength);
|
||||||
|
size_t compositeTypesSingleLineLimit = 5; // The number of type elements permitted on a single line when printing type unions/intersections
|
||||||
ToStringNameMap nameMap;
|
ToStringNameMap nameMap;
|
||||||
std::shared_ptr<Scope> scope; // If present, module names will be added and types that are not available in scope will be marked as 'invalid'
|
std::shared_ptr<Scope> scope; // If present, module names will be added and types that are not available in scope will be marked as 'invalid'
|
||||||
std::vector<std::string> namedFunctionOverrideArgNames; // If present, named function argument names will be overridden
|
std::vector<std::string> namedFunctionOverrideArgNames; // If present, named function argument names will be overridden
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
LUAU_FASTFLAG(DebugLuauDeferredConstraintResolution)
|
LUAU_FASTFLAG(DebugLuauDeferredConstraintResolution)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauToStringPrettifyLocation, false)
|
LUAU_FASTFLAGVARIABLE(LuauToStringPrettifyLocation, false)
|
||||||
|
LUAU_FASTFLAGVARIABLE(LuauToStringSimpleCompositeTypesSingleLine, false)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enables increasing levels of verbosity for Luau type names when stringifying.
|
* Enables increasing levels of verbosity for Luau type names when stringifying.
|
||||||
|
@ -878,11 +879,15 @@ struct TypeStringifier
|
||||||
state.emit("(");
|
state.emit("(");
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
bool shouldPlaceOnNewlines = results.size() > state.opts.compositeTypesSingleLineLimit;
|
||||||
for (std::string& ss : results)
|
for (std::string& ss : results)
|
||||||
{
|
{
|
||||||
if (!first)
|
if (!first)
|
||||||
{
|
{
|
||||||
|
if (shouldPlaceOnNewlines)
|
||||||
state.newline();
|
state.newline();
|
||||||
|
else
|
||||||
|
state.emit(" ");
|
||||||
state.emit("| ");
|
state.emit("| ");
|
||||||
}
|
}
|
||||||
state.emit(ss);
|
state.emit(ss);
|
||||||
|
@ -902,7 +907,7 @@ struct TypeStringifier
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(TypeId, const IntersectionType& uv)
|
void operator()(TypeId ty, const IntersectionType& uv)
|
||||||
{
|
{
|
||||||
if (state.hasSeen(&uv))
|
if (state.hasSeen(&uv))
|
||||||
{
|
{
|
||||||
|
@ -938,11 +943,15 @@ struct TypeStringifier
|
||||||
std::sort(results.begin(), results.end());
|
std::sort(results.begin(), results.end());
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
bool shouldPlaceOnNewlines = results.size() > state.opts.compositeTypesSingleLineLimit || isOverloadedFunction(ty);
|
||||||
for (std::string& ss : results)
|
for (std::string& ss : results)
|
||||||
{
|
{
|
||||||
if (!first)
|
if (!first)
|
||||||
{
|
{
|
||||||
|
if (shouldPlaceOnNewlines)
|
||||||
state.newline();
|
state.newline();
|
||||||
|
else
|
||||||
|
state.emit(" ");
|
||||||
state.emit("& ");
|
state.emit("& ");
|
||||||
}
|
}
|
||||||
state.emit(ss);
|
state.emit(ss);
|
||||||
|
|
|
@ -234,8 +234,41 @@ TEST_CASE_FIXTURE(Fixture, "functions_are_always_parenthesized_in_unions_or_inte
|
||||||
CHECK_EQ(toString(&itv), "((number, string) -> (string, number)) & ((string, number) -> (number, string))");
|
CHECK_EQ(toString(&itv), "((number, string) -> (string, number)) & ((string, number) -> (number, string))");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "intersections_respects_use_line_breaks")
|
TEST_CASE_FIXTURE(Fixture, "simple_intersections_printed_on_one_line")
|
||||||
{
|
{
|
||||||
|
ScopedFastFlag sff{"LuauToStringSimpleCompositeTypesSingleLine", true};
|
||||||
|
CheckResult result = check(R"(
|
||||||
|
local a: string & number
|
||||||
|
)");
|
||||||
|
|
||||||
|
ToStringOptions opts;
|
||||||
|
opts.useLineBreaks = true;
|
||||||
|
|
||||||
|
CHECK_EQ("number & string", toString(requireType("a"), opts));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE_FIXTURE(Fixture, "complex_intersections_printed_on_multiple_lines")
|
||||||
|
{
|
||||||
|
ScopedFastFlag sff{"LuauToStringSimpleCompositeTypesSingleLine", true};
|
||||||
|
CheckResult result = check(R"(
|
||||||
|
local a: string & number & boolean
|
||||||
|
)");
|
||||||
|
|
||||||
|
ToStringOptions opts;
|
||||||
|
opts.useLineBreaks = true;
|
||||||
|
opts.compositeTypesSingleLineLimit = 2;
|
||||||
|
|
||||||
|
//clang-format off
|
||||||
|
CHECK_EQ("boolean\n"
|
||||||
|
"& number\n"
|
||||||
|
"& string",
|
||||||
|
toString(requireType("a"), opts));
|
||||||
|
//clang-format on
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE_FIXTURE(Fixture, "overloaded_functions_always_printed_on_multiple_lines")
|
||||||
|
{
|
||||||
|
ScopedFastFlag sff{"LuauToStringSimpleCompositeTypesSingleLine", true};
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a: ((string) -> string) & ((number) -> number)
|
local a: ((string) -> string) & ((number) -> number)
|
||||||
)");
|
)");
|
||||||
|
@ -250,13 +283,28 @@ TEST_CASE_FIXTURE(Fixture, "intersections_respects_use_line_breaks")
|
||||||
//clang-format on
|
//clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "unions_respects_use_line_breaks")
|
TEST_CASE_FIXTURE(Fixture, "simple_unions_printed_on_one_line")
|
||||||
{
|
{
|
||||||
|
ScopedFastFlag sff{"LuauToStringSimpleCompositeTypesSingleLine", true};
|
||||||
|
CheckResult result = check(R"(
|
||||||
|
local a: number | boolean
|
||||||
|
)");
|
||||||
|
|
||||||
|
ToStringOptions opts;
|
||||||
|
opts.useLineBreaks = true;
|
||||||
|
|
||||||
|
CHECK_EQ("boolean | number", toString(requireType("a"), opts));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE_FIXTURE(Fixture, "complex_unions_printed_on_multiple_lines")
|
||||||
|
{
|
||||||
|
ScopedFastFlag sff{"LuauToStringSimpleCompositeTypesSingleLine", true};
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a: string | number | boolean
|
local a: string | number | boolean
|
||||||
)");
|
)");
|
||||||
|
|
||||||
ToStringOptions opts;
|
ToStringOptions opts;
|
||||||
|
opts.compositeTypesSingleLineLimit = 2;
|
||||||
opts.useLineBreaks = true;
|
opts.useLineBreaks = true;
|
||||||
|
|
||||||
//clang-format off
|
//clang-format off
|
||||||
|
|
Loading…
Reference in a new issue