Skip to content

Commit

Permalink
Fix type registration with solver v2
Browse files Browse the repository at this point in the history
remove legacy arg

start work with the tests
  • Loading branch information
checkraisefold committed Sep 28, 2024
1 parent 3c148ed commit 650c3a4
Show file tree
Hide file tree
Showing 11 changed files with 125 additions and 108 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/build
.vscode/settings.json
/.vs
out/
.cache
.idea
.DS_Store
Expand Down
18 changes: 11 additions & 7 deletions src/AnalyzeCli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <vector>

LUAU_FASTFLAG(DebugLuauTimeTracing)
LUAU_FASTFLAG(LuauSolverV2)

enum class ReportFormat
{
Expand Down Expand Up @@ -174,7 +175,7 @@ int startAnalyze(const argparse::ArgumentParser& program)
if (std::filesystem::is_directory(path))
{
for (std::filesystem::recursive_directory_iterator next(path, std::filesystem::directory_options::skip_permission_denied), end;
next != end; ++next)
next != end; ++next)
{
try
{
Expand Down Expand Up @@ -307,8 +308,9 @@ int startAnalyze(const argparse::ArgumentParser& program)

Luau::Frontend frontend(&fileResolver, &fileResolver, frontendOptions);

Luau::registerBuiltinGlobals(frontend, frontend.globals, /* typeCheckForAutocomplete = */ false);
Luau::registerBuiltinGlobals(frontend, frontend.globalsForAutocomplete, /* typeCheckForAutocomplete = */ true);
Luau::registerBuiltinGlobals(frontend, frontend.globals);
if (!FFlag::LuauSolverV2)
Luau::registerBuiltinGlobals(frontend, frontend.globalsForAutocomplete);

for (auto& definitionsPath : definitionsPaths)
{
Expand All @@ -325,7 +327,7 @@ int startAnalyze(const argparse::ArgumentParser& program)
return 1;
}

auto loadResult = types::registerDefinitions(frontend, frontend.globals, *definitionsContents, /* typeCheckForAutocomplete = */ false);
auto loadResult = types::registerDefinitions(frontend, frontend.globals, *definitionsContents);
if (!loadResult.success)
{
fprintf(stderr, "Failed to load definitions\n");
Expand Down Expand Up @@ -359,8 +361,9 @@ int startAnalyze(const argparse::ArgumentParser& program)
{
robloxPlatform->updateSourceNodeMap(sourceMapContents.value());

robloxPlatform->handleSourcemapUpdate(
frontend, frontend.globals, !program.is_used("--no-strict-dm-types") && client.configuration.diagnostics.strictDatamodelTypes);
bool expressiveTypes =
(program.is_used("--no-strict-dm-types") && client.configuration.diagnostics.strictDatamodelTypes) || FFlag::LuauSolverV2;
robloxPlatform->handleSourcemapUpdate(frontend, frontend.globals, expressiveTypes);
}
}
else
Expand All @@ -371,7 +374,8 @@ int startAnalyze(const argparse::ArgumentParser& program)
}

Luau::freeze(frontend.globals.globalTypes);
Luau::freeze(frontend.globalsForAutocomplete.globalTypes);
if (!FFlag::LuauSolverV2)
Luau::freeze(frontend.globalsForAutocomplete.globalTypes);

int failed = 0;

Expand Down
5 changes: 2 additions & 3 deletions src/LuauExt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,10 @@ std::optional<nlohmann::json> parseDefinitionsFileMetadata(const std::string& de
return std::nullopt;
}

Luau::LoadDefinitionFileResult registerDefinitions(
Luau::Frontend& frontend, Luau::GlobalTypes& globals, const std::string& definitions, bool typeCheckForAutocomplete)
Luau::LoadDefinitionFileResult registerDefinitions(Luau::Frontend& frontend, Luau::GlobalTypes& globals, const std::string& definitions)
{
// TODO: packageName shouldn't just be "@roblox"
return frontend.loadDefinitionFile(globals, globals.globalScope, definitions, "@roblox", /* captureComments = */ false, typeCheckForAutocomplete);
return frontend.loadDefinitionFile(globals, globals.globalScope, definitions, "@roblox", /* captureComments = */ false);
}

using NameOrExpr = std::variant<std::string, Luau::AstExpr*>;
Expand Down
16 changes: 10 additions & 6 deletions src/Workspace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,10 +285,12 @@ void WorkspaceFolder::registerTypes()
{
LUAU_TIMETRACE_SCOPE("WorkspaceFolder::initialize", "LSP");
client->sendTrace("workspace initialization: registering Luau globals");
Luau::registerBuiltinGlobals(frontend, frontend.globals, /* typeCheckForAutocomplete = */ false);
Luau::registerBuiltinGlobals(frontend, frontend.globalsForAutocomplete, /* typeCheckForAutocomplete = */ true);
Luau::registerBuiltinGlobals(frontend, frontend.globals);
if (!FFlag::LuauSolverV2)
Luau::registerBuiltinGlobals(frontend, frontend.globalsForAutocomplete);

Luau::attachTag(Luau::getGlobalBinding(frontend.globalsForAutocomplete, "require"), "Require");
auto& tagRegisterGlobals = FFlag::LuauSolverV2 ? frontend.globals : frontend.globalsForAutocomplete;
Luau::attachTag(Luau::getGlobalBinding(tagRegisterGlobals, "require"), "Require");

if (client->definitionsFiles.empty())
client->sendLogMessage(lsp::MessageType::Warning, "No definitions file provided by client");
Expand All @@ -314,8 +316,9 @@ void WorkspaceFolder::registerTypes()
client->sendTrace("workspace initialization: parsing definitions file metadata COMPLETED", json(definitionsFileMetadata).dump());

client->sendTrace("workspace initialization: registering types definition");
auto result = types::registerDefinitions(frontend, frontend.globals, *definitionsContents, /* typeCheckForAutocomplete = */ false);
types::registerDefinitions(frontend, frontend.globalsForAutocomplete, *definitionsContents, /* typeCheckForAutocomplete = */ true);
auto result = types::registerDefinitions(frontend, frontend.globals, *definitionsContents);
if (!FFlag::LuauSolverV2)
types::registerDefinitions(frontend, frontend.globalsForAutocomplete, *definitionsContents);
client->sendTrace("workspace initialization: registering types definition COMPLETED");

client->sendTrace("workspace: applying platform mutations on definitions");
Expand Down Expand Up @@ -347,7 +350,8 @@ void WorkspaceFolder::registerTypes()
}
}
Luau::freeze(frontend.globals.globalTypes);
Luau::freeze(frontend.globalsForAutocomplete.globalTypes);
if (!FFlag::LuauSolverV2)
Luau::freeze(frontend.globalsForAutocomplete.globalTypes);
}

void WorkspaceFolder::setupWithConfiguration(const ClientConfiguration& configuration)
Expand Down
3 changes: 1 addition & 2 deletions src/include/LSP/LuauExt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ bool isMetamethod(const Luau::Name& name);

std::optional<nlohmann::json> parseDefinitionsFileMetadata(const std::string& definitions);

Luau::LoadDefinitionFileResult registerDefinitions(
Luau::Frontend& frontend, Luau::GlobalTypes& globals, const std::string& definitions, bool typeCheckForAutocomplete = false);
Luau::LoadDefinitionFileResult registerDefinitions(Luau::Frontend& frontend, Luau::GlobalTypes& globals, const std::string& definitions);

using NameOrExpr = std::variant<std::string, Luau::AstExpr*>;

Expand Down
11 changes: 7 additions & 4 deletions src/operations/Completion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "LSP/LuauExt.hpp"
#include "LSP/DocumentationParser.hpp"

LUAU_FASTFLAG(LuauSolverV2)

void WorkspaceFolder::endAutocompletion(const lsp::CompletionParams& params)
{
auto moduleName = fileResolver.getModuleName(params.textDocument.uri);
Expand Down Expand Up @@ -254,8 +256,8 @@ static const char* sortText(const Luau::Frontend& frontend, const std::string& n
return SortText::AutoImports;

// If the entry is `loadstring`, deprioritise it
if (auto it = frontend.globalsForAutocomplete.globalScope->bindings.find(Luau::AstName("loadstring"));
it != frontend.globalsForAutocomplete.globalScope->bindings.end())
auto& completionGlobals = FFlag::LuauSolverV2 ? frontend.globals : frontend.globalsForAutocomplete;
if (auto it = completionGlobals.globalScope->bindings.find(Luau::AstName("loadstring")); it != completionGlobals.globalScope->bindings.end())
{
if (entry.type == it->second.typeId)
return SortText::Deprioritized;
Expand Down Expand Up @@ -369,10 +371,11 @@ std::optional<std::string> WorkspaceFolder::getDocumentationForAutocompleteEntry
if (parentTy)
{
// parentTy might be an intersected type, find the actual base ttv
if (auto propInformation = lookupProp(*parentTy, name))
auto followedTy = Luau::follow(*parentTy);
if (auto propInformation = lookupProp(followedTy, name))
definitionModuleName = Luau::getDefinitionModuleName(propInformation->first);
else
definitionModuleName = Luau::getDefinitionModuleName(*parentTy);
definitionModuleName = Luau::getDefinitionModuleName(followedTy);
}
}
}
Expand Down
11 changes: 7 additions & 4 deletions src/platform/roblox/RobloxCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "LSP/Completion.hpp"
#include "LSP/Workspace.hpp"

LUAU_FASTFLAG(LuauSolverV2)

static constexpr const char* COMMON_SERVICES[] = {
"Players",
"ReplicatedStorage",
Expand Down Expand Up @@ -254,7 +256,8 @@ const char* RobloxPlatform::handleSortText(
return SortText::PrioritisedSuggestion;

// If calling a property on ServiceProvider, then prioritise these properties
if (auto dataModelType = frontend.globalsForAutocomplete.globalScope->lookupType("ServiceProvider");
auto& completionGlobals = FFlag::LuauSolverV2 ? frontend.globals : frontend.globalsForAutocomplete;
if (auto dataModelType = completionGlobals.globalScope->lookupType("ServiceProvider");
dataModelType && Luau::get<Luau::ClassType>(dataModelType->type) && entry.containingClass &&
Luau::isSubclass(entry.containingClass.value(), Luau::get<Luau::ClassType>(dataModelType->type)) && !entry.wrongIndexType)
{
Expand All @@ -264,9 +267,9 @@ const char* RobloxPlatform::handleSortText(
}

// If calling a property on an Instance, then prioritise these properties
else if (auto instanceType = frontend.globalsForAutocomplete.globalScope->lookupType("Instance");
instanceType && Luau::get<Luau::ClassType>(instanceType->type) && entry.containingClass &&
Luau::isSubclass(entry.containingClass.value(), Luau::get<Luau::ClassType>(instanceType->type)) && !entry.wrongIndexType)
else if (auto instanceType = completionGlobals.globalScope->lookupType("Instance");
instanceType && Luau::get<Luau::ClassType>(instanceType->type) && entry.containingClass &&
Luau::isSubclass(entry.containingClass.value(), Luau::get<Luau::ClassType>(instanceType->type)) && !entry.wrongIndexType)
{
if (auto it = std::find(std::begin(COMMON_INSTANCE_PROPERTIES), std::end(COMMON_INSTANCE_PROPERTIES), name);
it != std::end(COMMON_INSTANCE_PROPERTIES))
Expand Down
15 changes: 10 additions & 5 deletions src/platform/roblox/RobloxSourcemap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "Luau/BuiltinDefinitions.h"
#include "Luau/ConstraintSolver.h"

LUAU_FASTFLAG(LuauSolverV2)

static void mutateSourceNodeWithPluginInfo(SourceNode& sourceNode, const PluginNodePtr& pluginInstance)
{
// We currently perform purely additive changes where we add in new children
Expand Down Expand Up @@ -283,15 +285,18 @@ bool RobloxPlatform::updateSourceMapFromContents(const std::string& sourceMapCon
// Recreate instance types
instanceTypes.clear(); // NOTE: used across BOTH instances of handleSourcemapUpdate, don't clear in between!
auto config = workspaceFolder->client->getConfiguration(workspaceFolder->rootUri);
bool expressiveTypes = config.diagnostics.strictDatamodelTypes;
bool expressiveTypes = config.diagnostics.strictDatamodelTypes || FFlag::LuauSolverV2;

// NOTE: expressive types is always enabled for autocomplete, regardless of the setting!
// We pass the same setting even when we are registering autocomplete globals since
// the setting impacts what happens to diagnostics (as both calls overwrite frontend.prepareModuleScope)
workspaceFolder->client->sendTrace("Updating diagnostic types with sourcemap");
handleSourcemapUpdate(workspaceFolder->frontend, workspaceFolder->frontend.globals, expressiveTypes);
workspaceFolder->client->sendTrace("Updating autocomplete types with sourcemap");
handleSourcemapUpdate(workspaceFolder->frontend, workspaceFolder->frontend.globalsForAutocomplete, expressiveTypes);
if (!FFlag::LuauSolverV2)
{
workspaceFolder->client->sendTrace("Updating autocomplete types with sourcemap");
handleSourcemapUpdate(workspaceFolder->frontend, workspaceFolder->frontend.globalsForAutocomplete, expressiveTypes);
}

workspaceFolder->client->sendTrace("Updating sourcemap contents COMPLETED");

Expand Down Expand Up @@ -448,10 +453,10 @@ void RobloxPlatform::handleSourcemapUpdate(Luau::Frontend& frontend, const Luau:
// Prepare module scope so that we can dynamically reassign the type of "script" to retrieve instance info
frontend.prepareModuleScope = [this, &frontend, expressiveTypes](const Luau::ModuleName& name, const Luau::ScopePtr& scope, bool forAutocomplete)
{
Luau::GlobalTypes& globals = forAutocomplete ? frontend.globalsForAutocomplete : frontend.globals;
Luau::GlobalTypes& globals = (forAutocomplete && !FFlag::LuauSolverV2) ? frontend.globalsForAutocomplete : frontend.globals;

// TODO: we hope to remove these in future!
if (!expressiveTypes && !forAutocomplete)
if (!expressiveTypes && !forAutocomplete && !FFlag::LuauSolverV2)
{
scope->bindings[Luau::AstName("script")] = Luau::Binding{globals.builtinTypes->anyType};
scope->bindings[Luau::AstName("workspace")] = Luau::Binding{globals.builtinTypes->anyType};
Expand Down
Loading

0 comments on commit 650c3a4

Please sign in to comment.