Skip to content

Commit

Permalink
Fix reverse deps > 1 node away not correctly marked as dirty (#719)
Browse files Browse the repository at this point in the history
`Frontend.markDirty()` does not correctly mark reverse dependencies that
are not immediate as dirty.
This is because it would keep adding the reverse deps of `name` into the
queue to mark as dirty, instead of the reverse deps of `next`
  • Loading branch information
JohnnyMorganz authored Oct 20, 2022
1 parent 662a553 commit c4c1205
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 5 deletions.
24 changes: 19 additions & 5 deletions Analysis/src/Frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ LUAU_FASTFLAGVARIABLE(LuauAutocompleteDynamicLimits, false)
LUAU_FASTINTVARIABLE(LuauAutocompleteCheckTimeoutMs, 100)
LUAU_FASTFLAGVARIABLE(DebugLuauDeferredConstraintResolution, false)
LUAU_FASTFLAG(DebugLuauLogSolverToJson);
LUAU_FASTFLAGVARIABLE(LuauFixMarkDirtyReverseDeps, false)

namespace Luau
{
Expand Down Expand Up @@ -807,13 +808,26 @@ void Frontend::markDirty(const ModuleName& name, std::vector<ModuleName>* marked
sourceNode.dirtyModule = true;
sourceNode.dirtyModuleForAutocomplete = true;

if (0 == reverseDeps.count(name))
continue;
if (FFlag::LuauFixMarkDirtyReverseDeps)
{
if (0 == reverseDeps.count(next))
continue;

sourceModules.erase(name);
sourceModules.erase(next);

const std::vector<ModuleName>& dependents = reverseDeps[name];
queue.insert(queue.end(), dependents.begin(), dependents.end());
const std::vector<ModuleName>& dependents = reverseDeps[next];
queue.insert(queue.end(), dependents.begin(), dependents.end());
}
else
{
if (0 == reverseDeps.count(name))
continue;

sourceModules.erase(name);

const std::vector<ModuleName>& dependents = reverseDeps[name];
queue.insert(queue.end(), dependents.begin(), dependents.end());
}
}
}

Expand Down
27 changes: 27 additions & 0 deletions tests/Frontend.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,33 @@ TEST_CASE_FIXTURE(FrontendFixture, "recheck_if_dependent_script_is_dirty")
CHECK_EQ("{| b_value: string |}", toString(*bExports));
}

TEST_CASE_FIXTURE(FrontendFixture, "mark_non_immediate_reverse_deps_as_dirty")
{
ScopedFastFlag sff[] = {
{"LuauFixMarkDirtyReverseDeps", true},
};

fileResolver.source["game/Gui/Modules/A"] = "return {hello=5, world=true}";
fileResolver.source["game/Gui/Modules/B"] = R"(
return require(game:GetService('Gui').Modules.A)
)";
fileResolver.source["game/Gui/Modules/C"] = R"(
local Modules = game:GetService('Gui').Modules
local B = require(Modules.B)
return {c_value = B.hello}
)";

frontend.check("game/Gui/Modules/C");

std::vector<Luau::ModuleName> markedDirty;
frontend.markDirty("game/Gui/Modules/A", &markedDirty);

REQUIRE(markedDirty.size() == 3);
CHECK(std::find(markedDirty.begin(), markedDirty.end(), "game/Gui/Modules/A") != markedDirty.end());
CHECK(std::find(markedDirty.begin(), markedDirty.end(), "game/Gui/Modules/B") != markedDirty.end());
CHECK(std::find(markedDirty.begin(), markedDirty.end(), "game/Gui/Modules/C") != markedDirty.end());
}

#if 0
// Does not work yet. :(
TEST_CASE_FIXTURE(FrontendFixture, "recheck_if_dependent_script_has_a_parse_error")
Expand Down

0 comments on commit c4c1205

Please sign in to comment.