mirror of
https://github.com/luau-lang/luau.git
synced 2025-01-31 23:03:10 +00:00
Merge branch 'master' into merge
This commit is contained in:
commit
f8f0dd94f7
5 changed files with 89 additions and 4 deletions
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
@ -20,7 +20,7 @@ jobs:
|
||||||
unix:
|
unix:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [{name: ubuntu, version: ubuntu-latest}, {name: macos, version: macos-latest}]
|
os: [{name: ubuntu, version: ubuntu-latest}, {name: macos, version: macos-latest}, {name: macos-arm, version: macos-14}]
|
||||||
name: ${{matrix.os.name}}
|
name: ${{matrix.os.name}}
|
||||||
runs-on: ${{matrix.os.version}}
|
runs-on: ${{matrix.os.version}}
|
||||||
steps:
|
steps:
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
LUAU_FASTFLAG(DebugLuauDeferredConstraintResolution);
|
LUAU_FASTFLAG(DebugLuauDeferredConstraintResolution);
|
||||||
LUAU_FASTFLAG(DebugLuauReadWriteProperties);
|
LUAU_FASTFLAG(DebugLuauReadWriteProperties);
|
||||||
LUAU_FASTFLAGVARIABLE(LuauAutocompleteStringLiteralBounds, false);
|
LUAU_FASTFLAGVARIABLE(LuauAutocompleteStringLiteralBounds, false);
|
||||||
|
LUAU_FASTFLAGVARIABLE(LuauAutocompleteTableKeysNoInitialCharacter, false);
|
||||||
|
|
||||||
static const std::unordered_set<std::string> kStatementStartingKeywords = {
|
static const std::unordered_set<std::string> kStatementStartingKeywords = {
|
||||||
"while", "if", "local", "repeat", "function", "do", "for", "return", "break", "continue", "type", "export"};
|
"while", "if", "local", "repeat", "function", "do", "for", "return", "break", "continue", "type", "export"};
|
||||||
|
@ -1742,6 +1743,37 @@ static AutocompleteResult autocomplete(const SourceModule& sourceModule, const M
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (AstExprTable* exprTable = node->as<AstExprTable>(); exprTable && FFlag::LuauAutocompleteTableKeysNoInitialCharacter)
|
||||||
|
{
|
||||||
|
AutocompleteEntryMap result;
|
||||||
|
|
||||||
|
if (auto it = module->astExpectedTypes.find(exprTable))
|
||||||
|
{
|
||||||
|
result = autocompleteProps(*module, typeArena, builtinTypes, *it, PropIndexType::Key, ancestry);
|
||||||
|
|
||||||
|
// If the key type is a union of singleton strings,
|
||||||
|
// suggest those too.
|
||||||
|
if (auto ttv = get<TableType>(follow(*it)); ttv && ttv->indexer)
|
||||||
|
{
|
||||||
|
autocompleteStringSingleton(ttv->indexer->indexType, false, node, position, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove keys that are already completed
|
||||||
|
for (const auto& item : exprTable->items)
|
||||||
|
{
|
||||||
|
if (!item.key)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (auto stringKey = item.key->as<AstExprConstantString>())
|
||||||
|
result.erase(std::string(stringKey->value.data, stringKey->value.size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also offer general expression suggestions
|
||||||
|
autocompleteExpression(sourceModule, *module, builtinTypes, typeArena, ancestry, position, result);
|
||||||
|
|
||||||
|
return {result, ancestry, AutocompleteContext::Property};
|
||||||
|
}
|
||||||
else if (isIdentifier(node) && (parent->is<AstStatExpr>() || parent->is<AstStatError>()))
|
else if (isIdentifier(node) && (parent->is<AstStatExpr>() || parent->is<AstStatError>()))
|
||||||
return {autocompleteStatement(sourceModule, *module, ancestry, position), ancestry, AutocompleteContext::Statement};
|
return {autocompleteStatement(sourceModule, *module, ancestry, position), ancestry, AutocompleteContext::Statement};
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,13 @@ void luaL_sandbox(lua_State* L)
|
||||||
|
|
||||||
// set all builtin metatables to read-only
|
// set all builtin metatables to read-only
|
||||||
lua_pushliteral(L, "");
|
lua_pushliteral(L, "");
|
||||||
lua_getmetatable(L, -1);
|
if (lua_getmetatable(L, -1))
|
||||||
|
{
|
||||||
lua_setreadonly(L, -1, true);
|
lua_setreadonly(L, -1, true);
|
||||||
lua_pop(L, 2);
|
lua_pop(L, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
// set globals to readonly and activate safeenv since the env is immutable
|
// set globals to readonly and activate safeenv since the env is immutable
|
||||||
lua_setreadonly(L, LUA_GLOBALSINDEX, true);
|
lua_setreadonly(L, LUA_GLOBALSINDEX, true);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
LUAU_FASTFLAG(LuauTraceTypesInNonstrictMode2)
|
LUAU_FASTFLAG(LuauTraceTypesInNonstrictMode2)
|
||||||
LUAU_FASTFLAG(LuauSetMetatableDoesNotTimeTravel)
|
LUAU_FASTFLAG(LuauSetMetatableDoesNotTimeTravel)
|
||||||
LUAU_FASTFLAG(LuauAutocompleteStringLiteralBounds);
|
LUAU_FASTFLAG(LuauAutocompleteStringLiteralBounds);
|
||||||
|
LUAU_FASTFLAG(LuauAutocompleteTableKeysNoInitialCharacter)
|
||||||
|
|
||||||
using namespace Luau;
|
using namespace Luau;
|
||||||
|
|
||||||
|
@ -2693,6 +2694,43 @@ local t = {
|
||||||
CHECK_EQ(ac.context, AutocompleteContext::Property);
|
CHECK_EQ(ac.context, AutocompleteContext::Property);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE_FIXTURE(ACFixture, "suggest_table_keys_no_initial_character")
|
||||||
|
{
|
||||||
|
ScopedFastFlag sff{FFlag::LuauAutocompleteTableKeysNoInitialCharacter, true};
|
||||||
|
|
||||||
|
check(R"(
|
||||||
|
type Test = { first: number, second: number }
|
||||||
|
local t: Test = { @1 }
|
||||||
|
)");
|
||||||
|
|
||||||
|
auto ac = autocomplete('1');
|
||||||
|
CHECK(ac.entryMap.count("first"));
|
||||||
|
CHECK(ac.entryMap.count("second"));
|
||||||
|
CHECK_EQ(ac.context, AutocompleteContext::Property);
|
||||||
|
|
||||||
|
check(R"(
|
||||||
|
type Test = { first: number, second: number }
|
||||||
|
local t: Test = { first = 1, @1 }
|
||||||
|
)");
|
||||||
|
|
||||||
|
ac = autocomplete('1');
|
||||||
|
CHECK_EQ(ac.entryMap.count("first"), 0);
|
||||||
|
CHECK(ac.entryMap.count("second"));
|
||||||
|
CHECK_EQ(ac.context, AutocompleteContext::Property);
|
||||||
|
|
||||||
|
check(R"(
|
||||||
|
type Properties = { TextScaled: boolean, Text: string }
|
||||||
|
local function create(props: Properties) end
|
||||||
|
|
||||||
|
create({ @1 })
|
||||||
|
)");
|
||||||
|
|
||||||
|
ac = autocomplete('1');
|
||||||
|
CHECK(ac.entryMap.count("TextScaled"));
|
||||||
|
CHECK(ac.entryMap.count("Text"));
|
||||||
|
CHECK_EQ(ac.context, AutocompleteContext::Property);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(ACFixture, "autocomplete_documentation_symbols")
|
TEST_CASE_FIXTURE(ACFixture, "autocomplete_documentation_symbols")
|
||||||
{
|
{
|
||||||
loadDefinition(R"(
|
loadDefinition(R"(
|
||||||
|
|
|
@ -884,6 +884,17 @@ TEST_CASE("NewUserdataOverflow")
|
||||||
CHECK(strcmp(lua_tostring(L, -1), "memory allocation error: block too big") == 0);
|
CHECK(strcmp(lua_tostring(L, -1), "memory allocation error: block too big") == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("SandboxWithoutLibs")
|
||||||
|
{
|
||||||
|
StateRef globalState(luaL_newstate(), lua_close);
|
||||||
|
lua_State* L = globalState.get();
|
||||||
|
|
||||||
|
luaopen_base(L); // Load only base library
|
||||||
|
luaL_sandbox(L);
|
||||||
|
|
||||||
|
CHECK(lua_getreadonly(L, LUA_GLOBALSINDEX));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("ApiTables")
|
TEST_CASE("ApiTables")
|
||||||
{
|
{
|
||||||
StateRef globalState(luaL_newstate(), lua_close);
|
StateRef globalState(luaL_newstate(), lua_close);
|
||||||
|
|
Loading…
Add table
Reference in a new issue