Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor for new solver #783

Merged
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,12 @@ jobs:
cmake ..
cmake --build . --target Luau.LanguageServer.Test -j 3

- name: Run Tests
- name: Run Tests (Old Solver)
run: ${{ matrix.test-path }}

- name: Run Tests (New Solver)
run: ${{ matrix.test-path }} --new-solver

types_smoketest:
name: Types Smoketest
runs-on: ubuntu-20.04
Expand Down
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

- Sync to upstream Luau 0.650

### Fixed

- Fixed autocompletion, type registration, hover types/documentation, and some crashes for cases where the new solver is enabled

## [1.34.0] - 2024-10-27

### Changed
Expand Down Expand Up @@ -117,7 +121,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed

- Sync to upstream Luau 0.632
- Language clients are recommended to send configuration during intializationOptions (see https://github.com/JohnnyMorganz/luau-lsp/blob/main/editors/README.md for details)
- Language clients are recommended to send configuration during intializationOptions (see <https://github.com/JohnnyMorganz/luau-lsp/blob/main/editors/README.md> for details)
- Removed need for postponing requests whilst waiting for platform configuration (relies on clients sending config in intializationOptions)

### Fixed
Expand Down Expand Up @@ -150,7 +154,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed

- Sync to upstream Luau 0.631
- An indexed expression will no longer show an inlay hint if the index matches the parameter name (i.e., `call(other.value)` won't add `value: ` inlay hint) ([#618](https://github.com/JohnnyMorganz/luau-lsp/issues/618))
- An indexed expression will no longer show an inlay hint if the index matches the parameter name (i.e., `call(other.value)` won't add `value:` inlay hint) ([#618](https://github.com/JohnnyMorganz/luau-lsp/issues/618))
- Studio Plugin will now perform Gzip compression on sent requests

### Fixed
Expand Down Expand Up @@ -182,7 +186,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

- Sync to upstream Luau 0.625
- Improved memory usage of document and workspace diagnostics by no longer storing type graphs
- Rewritten the Luau grammar syntax: https://github.com/JohnnyMorganz/Luau.tmLanguage
- Rewritten the Luau grammar syntax: <https://github.com/JohnnyMorganz/Luau.tmLanguage>

### Fixed

Expand Down Expand Up @@ -604,7 +608,7 @@ local DATA = {

--- Doc comment
type Contents = {
...
...
}
```

Expand Down Expand Up @@ -763,7 +767,7 @@ local y = tbl.data -- Should give "This is some special information"
- Provide autocomplete for class names in `Instance:IsA("ClassName")` and errors when ClassName is unknown
- Provide autocomplete for properties in `Instance:GetPropertyChangedSignal("Property")` and errors when Property is unknown
- Provide autocomplete for enums in `EnumItem:IsA("enum")` and errors when Enum is unknown
- Added support for moonwave-style documentation comments! Currently only supports comments attached to functions directly. See https://eryn.io/moonwave for how to write doc comments
- Added support for moonwave-style documentation comments! Currently only supports comments attached to functions directly. See <https://eryn.io/moonwave> for how to write doc comments
- Added command line flag `--ignore=GLOB` to `luau-lsp analyze` allowing you to provide glob patterns to ignore diagnostics, similar to `luau-lsp.ignoreGlobs`. Repeat the flag multiple times for multiple patterns

### Changed
Expand Down Expand Up @@ -981,7 +985,7 @@ local y = tbl.data -- Should give "This is some special information"
- Fixed regression where diagnostics are not cleared when you close an ignored file
- Fixed errors sometimes occuring when you index `script`/`workspace`/`game` for children
- Fixed internal error caused by `:Clone()` calls when called on an expression which isn't an Lvalue (e.g., `inst:FindFirstChild(name):Clone()`)
- Fixed bug where `_: ` would not be removed as the name of function arguments. `function foo(_: number, _: number)` will now show as `function foo(number, number)`
- Fixed bug where `_:` would not be removed as the name of function arguments. `function foo(_: number, _: number)` will now show as `function foo(number, number)`
- Fixed analyze mode not exiting with a non-zero exit code when there are errors
- Fixed excessive whitespace in document symbols for expr-named function defintions
- Fixed hover for global functions and local variables
Expand Down Expand Up @@ -1147,7 +1151,7 @@ local y = tbl.data -- Should give "This is some special information"

- Hover over definitions will now try to give more expressive types
- `self` will now no longer show up in hover/signature help if it has already been implicitly provided
- `_: ` will no longer show up in hover/signature help for unnamed function parameters
- `_:` will no longer show up in hover/signature help for unnamed function parameters

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion luau
Submodule luau updated from a251bc to 26b230
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
7 changes: 4 additions & 3 deletions src/LuauExt.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include <optional>
#include <utility>

#include "Luau/Type.h"
#include "Platform/LSPPlatform.hpp"
#include "Luau/BuiltinDefinitions.h"
#include "Luau/ToString.h"
Expand Down Expand Up @@ -51,11 +53,10 @@ std::optional<nlohmann::json> parseDefinitionsFileMetadata(const std::string& de
return std::nullopt;
}

Luau::LoadDefinitionFileResult registerDefinitions(
JohnnyMorganz marked this conversation as resolved.
Show resolved Hide resolved
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);
JohnnyMorganz marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -256,8 +258,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 @@ -371,10 +373,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
Loading
Loading