Skip to content

Commit

Permalink
Modify the way line breaks are added when printing unions/intersectio…
Browse files Browse the repository at this point in the history
…ns (#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
  • Loading branch information
JohnnyMorganz authored Oct 12, 2023
1 parent 9843364 commit 1173e41
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 5 deletions.
8 changes: 8 additions & 0 deletions Analysis/include/Luau/ToString.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

LUAU_FASTINT(LuauTableTypeMaximumStringifierLength)
LUAU_FASTINT(LuauTypeMaximumStringifierLength)
LUAU_FASTFLAG(LuauToStringSimpleCompositeTypesSingleLine)

namespace Luau
{
Expand Down Expand Up @@ -39,6 +40,12 @@ struct ToStringNameMap

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 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
Expand All @@ -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
size_t maxTableLength = size_t(FInt::LuauTableTypeMaximumStringifierLength); // Only applied to TableTypes
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;
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
Expand Down
15 changes: 12 additions & 3 deletions Analysis/src/ToString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

LUAU_FASTFLAG(DebugLuauDeferredConstraintResolution)
LUAU_FASTFLAGVARIABLE(LuauToStringPrettifyLocation, false)
LUAU_FASTFLAGVARIABLE(LuauToStringSimpleCompositeTypesSingleLine, false)

/*
* Enables increasing levels of verbosity for Luau type names when stringifying.
Expand Down Expand Up @@ -878,11 +879,15 @@ struct TypeStringifier
state.emit("(");

bool first = true;
bool shouldPlaceOnNewlines = results.size() > state.opts.compositeTypesSingleLineLimit;
for (std::string& ss : results)
{
if (!first)
{
state.newline();
if (shouldPlaceOnNewlines)
state.newline();
else
state.emit(" ");
state.emit("| ");
}
state.emit(ss);
Expand All @@ -902,7 +907,7 @@ struct TypeStringifier
}
}

void operator()(TypeId, const IntersectionType& uv)
void operator()(TypeId ty, const IntersectionType& uv)
{
if (state.hasSeen(&uv))
{
Expand Down Expand Up @@ -938,11 +943,15 @@ struct TypeStringifier
std::sort(results.begin(), results.end());

bool first = true;
bool shouldPlaceOnNewlines = results.size() > state.opts.compositeTypesSingleLineLimit || isOverloadedFunction(ty);
for (std::string& ss : results)
{
if (!first)
{
state.newline();
if (shouldPlaceOnNewlines)
state.newline();
else
state.emit(" ");
state.emit("& ");
}
state.emit(ss);
Expand Down
52 changes: 50 additions & 2 deletions tests/ToString.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))");
}

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"(
local a: ((string) -> string) & ((number) -> number)
)");
Expand All @@ -250,13 +283,28 @@ TEST_CASE_FIXTURE(Fixture, "intersections_respects_use_line_breaks")
//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"(
local a: string | number | boolean
)");

ToStringOptions opts;
opts.compositeTypesSingleLineLimit = 2;
opts.useLineBreaks = true;

//clang-format off
Expand Down

0 comments on commit 1173e41

Please sign in to comment.