mirror of
https://github.com/luau-lang/luau.git
synced 2025-04-16 09:54:02 +01:00
We have lots of new changes for you! # What's Changed ## General - We updated Luau's license year to 2025! - We fixed a bug where large amounts of errors were being printed when deep intersections of unions error. ## Require-by-String This release introduces the `Luau.Require` library, which exposes the runtime semantics of require-by-string, including support for the new `@self` alias described in [this RFC](https://github.com/luau-lang/rfcs/pull/109). The library operates on a virtualized filesystem, allowing consumers to specify navigation rules without assuming a filesystem context. Documentation in `Require.h` explains how to enable the library, and the `setupState` function in Repl.cpp demonstrates how we've integrated it into the luau CLI tool. Note that the interface in `Require.h` is written in C, which enables any application written in a language with a C foreign-function interface to link against this library and enable require-by-string. This makes it straightforward for any application embedding Luau to support require-by-string, provided that it defines or operates within an environment resembling a virtual filesystem. The core navigation semantics of require-by-string have additionally been pulled into the `Luau.RequireNavigator` library. While `Luau.Require` internally depends on `Luau.RequireNavigator`, the latter does not depend on the Luau VM. This library provides an interface for inspecting require-by-string's navigation behavior and therefore serves as a useful dependency for static tooling. Documentation for `Luau.RequireNavigator` is available in `RequireNavigator.h`. ## Autocomplete - We fixed a memory leak in fragment autocomplete! ## New Solver And Old Solver - We've found a infinite iteration error over a type pack. We added a way to detect this error and throw an `InternalCompileError` instead. - We fix `table.freeze` not accounting for the first argument not getting type stated. We fall back to regular inference instead. - We fix a crash in the old solver with `length_error`. - We fix a crash in the new solver stemming from generalization reentrancy. Now we correctly generalize interior free types that do not appear in a function signature. - We fix a nil refinement. (Fixes https://github.com/luau-lang/luau/issues/1687 and https://github.com/luau-lang/luau/issues/1451) ### Internal Contributors Co-authored-by: Andy Friesen <afriesen@roblox.com> Co-authored-by: Hunter Goldstein <hgoldstein@roblox.com> Co-authored-by: Talha Pathan <tpathan@roblox.com> Co-authored-by: Varun Saini <vsaini@roblox.com> Co-authored-by: Vighnesh Vijay <vvijay@roblox.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com> Full Changelog: https://github.com/luau-lang/luau/compare/0.668...0.669 --------- Co-authored-by: Hunter Goldstein <hgoldstein@roblox.com> Co-authored-by: Varun Saini <61795485+vrn-sn@users.noreply.github.com> Co-authored-by: Alexander Youngblood <ayoungblood@roblox.com> Co-authored-by: Aviral Goel <agoel@roblox.com> Co-authored-by: Vighnesh <vvijay@roblox.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com> Co-authored-by: Ariel Weiss <aaronweiss@roblox.com>
196 lines
5.7 KiB
C++
196 lines
5.7 KiB
C++
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
|
#pragma once
|
|
|
|
#include "Luau/Ast.h"
|
|
#include "Luau/Parser.h"
|
|
#include "Luau/AutocompleteTypes.h"
|
|
#include "Luau/DenseHash.h"
|
|
#include "Luau/Module.h"
|
|
#include "Luau/Frontend.h"
|
|
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
namespace Luau
|
|
{
|
|
struct FrontendOptions;
|
|
|
|
enum class FragmentAutocompleteWaypoint
|
|
{
|
|
ParseFragmentEnd,
|
|
CloneModuleStart,
|
|
CloneModuleEnd,
|
|
DfgBuildEnd,
|
|
CloneAndSquashScopeStart,
|
|
CloneAndSquashScopeEnd,
|
|
ConstraintSolverStart,
|
|
ConstraintSolverEnd,
|
|
TypecheckFragmentEnd,
|
|
AutocompleteEnd,
|
|
COUNT,
|
|
};
|
|
|
|
class IFragmentAutocompleteReporter
|
|
{
|
|
public:
|
|
virtual void reportWaypoint(FragmentAutocompleteWaypoint) = 0;
|
|
virtual void reportFragmentString(std::string_view) = 0;
|
|
};
|
|
|
|
enum class FragmentTypeCheckStatus
|
|
{
|
|
SkipAutocomplete,
|
|
Success,
|
|
};
|
|
|
|
struct FragmentAutocompleteAncestryResult
|
|
{
|
|
DenseHashMap<AstName, AstLocal*> localMap{AstName()};
|
|
std::vector<AstLocal*> localStack;
|
|
std::vector<AstNode*> ancestry;
|
|
AstStat* nearestStatement = nullptr;
|
|
AstStatBlock* parentBlock = nullptr;
|
|
Location fragmentSelectionRegion;
|
|
};
|
|
|
|
struct FragmentParseResult
|
|
{
|
|
std::string fragmentToParse;
|
|
AstStatBlock* root = nullptr;
|
|
std::vector<AstNode*> ancestry;
|
|
AstStat* nearestStatement = nullptr;
|
|
std::vector<Comment> commentLocations;
|
|
std::unique_ptr<Allocator> alloc = std::make_unique<Allocator>();
|
|
Position scopePos{0, 0};
|
|
};
|
|
|
|
struct FragmentTypeCheckResult
|
|
{
|
|
ModulePtr incrementalModule = nullptr;
|
|
ScopePtr freshScope;
|
|
std::vector<AstNode*> ancestry;
|
|
};
|
|
|
|
struct FragmentAutocompleteResult
|
|
{
|
|
ModulePtr incrementalModule;
|
|
Scope* freshScope;
|
|
TypeArena arenaForAutocomplete_DEPRECATED;
|
|
AutocompleteResult acResults;
|
|
};
|
|
|
|
struct FragmentRegion
|
|
{
|
|
Location fragmentLocation;
|
|
AstStat* nearestStatement = nullptr; // used for tests
|
|
AstStatBlock* parentBlock = nullptr; // used for scope detection
|
|
};
|
|
|
|
std::optional<Position> blockDiffStart(AstStatBlock* blockOld, AstStatBlock* blockNew, AstStat* nearestStatementNewAst);
|
|
FragmentRegion getFragmentRegion(AstStatBlock* root, const Position& cursorPosition);
|
|
FragmentAutocompleteAncestryResult findAncestryForFragmentParse(AstStatBlock* stale, const Position& cursorPos, AstStatBlock* lastGoodParse);
|
|
FragmentAutocompleteAncestryResult findAncestryForFragmentParse_DEPRECATED(AstStatBlock* root, const Position& cursorPos);
|
|
|
|
std::optional<FragmentParseResult> parseFragment_DEPRECATED(
|
|
AstStatBlock* root,
|
|
AstNameTable* names,
|
|
std::string_view src,
|
|
const Position& cursorPos,
|
|
std::optional<Position> fragmentEndPosition
|
|
);
|
|
|
|
std::optional<FragmentParseResult> parseFragment(
|
|
AstStatBlock* stale,
|
|
AstStatBlock* mostRecentParse,
|
|
AstNameTable* names,
|
|
std::string_view src,
|
|
const Position& cursorPos,
|
|
std::optional<Position> fragmentEndPosition
|
|
);
|
|
|
|
std::pair<FragmentTypeCheckStatus, FragmentTypeCheckResult> typecheckFragment(
|
|
Frontend& frontend,
|
|
const ModuleName& moduleName,
|
|
const Position& cursorPos,
|
|
std::optional<FrontendOptions> opts,
|
|
std::string_view src,
|
|
std::optional<Position> fragmentEndPosition,
|
|
AstStatBlock* recentParse = nullptr,
|
|
IFragmentAutocompleteReporter* reporter = nullptr
|
|
);
|
|
|
|
FragmentAutocompleteResult fragmentAutocomplete(
|
|
Frontend& frontend,
|
|
std::string_view src,
|
|
const ModuleName& moduleName,
|
|
Position cursorPosition,
|
|
std::optional<FrontendOptions> opts,
|
|
StringCompletionCallback callback,
|
|
std::optional<Position> fragmentEndPosition = std::nullopt,
|
|
AstStatBlock* recentParse = nullptr,
|
|
IFragmentAutocompleteReporter* reporter = nullptr
|
|
);
|
|
|
|
enum class FragmentAutocompleteStatus
|
|
{
|
|
Success,
|
|
FragmentTypeCheckFail,
|
|
InternalIce
|
|
};
|
|
|
|
struct FragmentAutocompleteStatusResult
|
|
{
|
|
FragmentAutocompleteStatus status;
|
|
std::optional<FragmentAutocompleteResult> result;
|
|
};
|
|
|
|
struct FragmentContext
|
|
{
|
|
std::string_view newSrc;
|
|
const ParseResult& freshParse;
|
|
std::optional<FrontendOptions> opts;
|
|
std::optional<Position> DEPRECATED_fragmentEndPosition;
|
|
IFragmentAutocompleteReporter* reporter = nullptr;
|
|
};
|
|
|
|
/**
|
|
* @brief Attempts to compute autocomplete suggestions from the fragment context.
|
|
*
|
|
* This function computes autocomplete suggestions using outdated frontend typechecking data
|
|
* by patching the fragment context of the new script source content.
|
|
*
|
|
* @param frontend The Luau Frontend data structure, which may contain outdated typechecking data.
|
|
*
|
|
* @param moduleName The name of the target module, specifying which script the caller wants to request autocomplete for.
|
|
*
|
|
* @param cursorPosition The position in the script where the caller wants to trigger autocomplete.
|
|
*
|
|
* @param context The fragment context that this API will use to patch the outdated typechecking data.
|
|
*
|
|
* @param stringCompletionCB A callback function that provides autocomplete suggestions for string contexts.
|
|
*
|
|
* @return
|
|
* The status indicating whether `fragmentAutocomplete` ran successfully or failed, along with the reason for failure.
|
|
* Also includes autocomplete suggestions if the status is successful.
|
|
*
|
|
* @usage
|
|
* FragmentAutocompleteStatusResult acStatusResult;
|
|
* if (shouldFragmentAC)
|
|
* acStatusResult = Luau::tryFragmentAutocomplete(...);
|
|
*
|
|
* if (acStatusResult.status != Successful)
|
|
* {
|
|
* frontend.check(moduleName, options);
|
|
* acStatusResult.acResult = Luau::autocomplete(...);
|
|
* }
|
|
* return convertResultWithContext(acStatusResult.acResult);
|
|
*/
|
|
FragmentAutocompleteStatusResult tryFragmentAutocomplete(
|
|
Frontend& frontend,
|
|
const ModuleName& moduleName,
|
|
Position cursorPosition,
|
|
FragmentContext context,
|
|
StringCompletionCallback stringCompletionCB
|
|
);
|
|
|
|
} // namespace Luau
|