mirror of
https://github.com/luau-lang/luau.git
synced 2024-11-15 22:35:43 +08:00
Merge branch 'master' into merge
This commit is contained in:
commit
b1000a6889
2
.github/workflows/benchmark-dev.yml
vendored
2
.github/workflows/benchmark-dev.yml
vendored
@ -108,7 +108,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest]
|
os: [ubuntu-20.04, macos-latest]
|
||||||
bench:
|
bench:
|
||||||
- {
|
- {
|
||||||
script: "run-benchmarks",
|
script: "run-benchmarks",
|
||||||
|
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@ -20,9 +20,9 @@ jobs:
|
|||||||
unix:
|
unix:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu, macos]
|
os: [{name: ubuntu, version: ubuntu-20.04}, {name: macos, version: macos-latest}]
|
||||||
name: ${{matrix.os}}
|
name: ${{matrix.os.name}}
|
||||||
runs-on: ${{matrix.os}}-latest
|
runs-on: ${{matrix.os.version}}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- name: make tests
|
- name: make tests
|
||||||
@ -81,7 +81,7 @@ jobs:
|
|||||||
Debug/luau-analyze tests/conformance/assert.lua
|
Debug/luau-analyze tests/conformance/assert.lua
|
||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: install
|
- name: install
|
||||||
@ -89,7 +89,7 @@ jobs:
|
|||||||
sudo apt install llvm
|
sudo apt install llvm
|
||||||
- name: make coverage
|
- name: make coverage
|
||||||
run: |
|
run: |
|
||||||
CXX=clang++ make -j2 config=coverage native=1 coverage
|
CXX=clang++-10 make -j2 config=coverage native=1 coverage
|
||||||
- name: upload coverage
|
- name: upload coverage
|
||||||
uses: codecov/codecov-action@v3
|
uses: codecov/codecov-action@v3
|
||||||
with:
|
with:
|
||||||
@ -97,7 +97,7 @@ jobs:
|
|||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|
||||||
web:
|
web:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
22
.github/workflows/new-release.yml
vendored
22
.github/workflows/new-release.yml
vendored
@ -12,7 +12,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
create-release:
|
create-release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
outputs:
|
outputs:
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
steps:
|
steps:
|
||||||
@ -30,9 +30,9 @@ jobs:
|
|||||||
needs: ["create-release"]
|
needs: ["create-release"]
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu, macos, windows]
|
os: [{name: ubuntu, version: ubuntu-20.04}, {name: macos, version: macos-latest}, {name: windows, version: windows-latest}]
|
||||||
name: ${{matrix.os}}
|
name: ${{matrix.os.name}}
|
||||||
runs-on: ${{matrix.os}}-latest
|
runs-on: ${{matrix.os.version}}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- name: configure
|
- name: configure
|
||||||
@ -40,23 +40,23 @@ jobs:
|
|||||||
- name: build
|
- name: build
|
||||||
run: cmake --build . --target Luau.Repl.CLI Luau.Analyze.CLI --config Release -j 2
|
run: cmake --build . --target Luau.Repl.CLI Luau.Analyze.CLI --config Release -j 2
|
||||||
- name: pack
|
- name: pack
|
||||||
if: matrix.os != 'windows'
|
if: matrix.os.name != 'windows'
|
||||||
run: zip luau-${{matrix.os}}.zip luau*
|
run: zip luau-${{matrix.os.name}}.zip luau*
|
||||||
- name: pack
|
- name: pack
|
||||||
if: matrix.os == 'windows'
|
if: matrix.os.name == 'windows'
|
||||||
run: 7z a luau-${{matrix.os}}.zip .\Release\luau*.exe
|
run: 7z a luau-${{matrix.os.name}}.zip .\Release\luau*.exe
|
||||||
- uses: actions/upload-release-asset@v1
|
- uses: actions/upload-release-asset@v1
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||||
asset_path: luau-${{matrix.os}}.zip
|
asset_path: luau-${{matrix.os.name}}.zip
|
||||||
asset_name: luau-${{matrix.os}}.zip
|
asset_name: luau-${{matrix.os.name}}.zip
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
web:
|
web:
|
||||||
needs: ["create-release"]
|
needs: ["create-release"]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
16
.github/workflows/release.yml
vendored
16
.github/workflows/release.yml
vendored
@ -14,9 +14,9 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu, macos, windows]
|
os: [{name: ubuntu, version: ubuntu-20.04}, {name: macos, version: macos-latest}, {name: windows, version: windows-latest}]
|
||||||
name: ${{matrix.os}}
|
name: ${{matrix.os.name}}
|
||||||
runs-on: ${{matrix.os}}-latest
|
runs-on: ${{matrix.os.version}}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- name: configure
|
- name: configure
|
||||||
@ -24,18 +24,18 @@ jobs:
|
|||||||
- name: build
|
- name: build
|
||||||
run: cmake --build . --target Luau.Repl.CLI Luau.Analyze.CLI --config Release -j 2
|
run: cmake --build . --target Luau.Repl.CLI Luau.Analyze.CLI --config Release -j 2
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
if: matrix.os != 'windows'
|
if: matrix.os.name != 'windows'
|
||||||
with:
|
with:
|
||||||
name: luau-${{matrix.os}}
|
name: luau-${{matrix.os.name}}
|
||||||
path: luau*
|
path: luau*
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
if: matrix.os == 'windows'
|
if: matrix.os.name == 'windows'
|
||||||
with:
|
with:
|
||||||
name: luau-${{matrix.os}}
|
name: luau-${{matrix.os.name}}
|
||||||
path: Release\luau*.exe
|
path: Release\luau*.exe
|
||||||
|
|
||||||
web:
|
web:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
@ -89,7 +89,8 @@ struct AutocompleteResult
|
|||||||
};
|
};
|
||||||
|
|
||||||
using ModuleName = std::string;
|
using ModuleName = std::string;
|
||||||
using StringCompletionCallback = std::function<std::optional<AutocompleteEntryMap>(std::string tag, std::optional<const ClassType*> ctx)>;
|
using StringCompletionCallback =
|
||||||
|
std::function<std::optional<AutocompleteEntryMap>(std::string tag, std::optional<const ClassType*> ctx, std::optional<std::string> contents)>;
|
||||||
|
|
||||||
AutocompleteResult autocomplete(Frontend& frontend, const ModuleName& moduleName, Position position, StringCompletionCallback callback);
|
AutocompleteResult autocomplete(Frontend& frontend, const ModuleName& moduleName, Position position, StringCompletionCallback callback);
|
||||||
|
|
||||||
|
@ -375,6 +375,7 @@ struct TableType
|
|||||||
std::vector<TypeId> instantiatedTypeParams;
|
std::vector<TypeId> instantiatedTypeParams;
|
||||||
std::vector<TypePackId> instantiatedTypePackParams;
|
std::vector<TypePackId> instantiatedTypePackParams;
|
||||||
ModuleName definitionModuleName;
|
ModuleName definitionModuleName;
|
||||||
|
Location definitionLocation;
|
||||||
|
|
||||||
std::optional<TypeId> boundTo;
|
std::optional<TypeId> boundTo;
|
||||||
Tags tags;
|
Tags tags;
|
||||||
|
@ -59,6 +59,7 @@ TypeId Anyification::clean(TypeId ty)
|
|||||||
{
|
{
|
||||||
TableType clone = TableType{ttv->props, ttv->indexer, ttv->level, TableState::Sealed};
|
TableType clone = TableType{ttv->props, ttv->indexer, ttv->level, TableState::Sealed};
|
||||||
clone.definitionModuleName = ttv->definitionModuleName;
|
clone.definitionModuleName = ttv->definitionModuleName;
|
||||||
|
clone.definitionLocation = ttv->definitionLocation;
|
||||||
clone.name = ttv->name;
|
clone.name = ttv->name;
|
||||||
clone.syntheticName = ttv->syntheticName;
|
clone.syntheticName = ttv->syntheticName;
|
||||||
clone.tags = ttv->tags;
|
clone.tags = ttv->tags;
|
||||||
|
@ -1262,6 +1262,23 @@ static bool isSimpleInterpolatedString(const AstNode* node)
|
|||||||
return interpString != nullptr && interpString->expressions.size == 0;
|
return interpString != nullptr && interpString->expressions.size == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::optional<std::string> getStringContents(const AstNode* node)
|
||||||
|
{
|
||||||
|
if (const AstExprConstantString* string = node->as<AstExprConstantString>())
|
||||||
|
{
|
||||||
|
return std::string(string->value.data, string->value.size);
|
||||||
|
}
|
||||||
|
else if (const AstExprInterpString* interpString = node->as<AstExprInterpString>(); interpString && interpString->expressions.size == 0)
|
||||||
|
{
|
||||||
|
LUAU_ASSERT(interpString->strings.size == 1);
|
||||||
|
return std::string(interpString->strings.data->data, interpString->strings.data->size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static std::optional<AutocompleteEntryMap> autocompleteStringParams(const SourceModule& sourceModule, const ModulePtr& module,
|
static std::optional<AutocompleteEntryMap> autocompleteStringParams(const SourceModule& sourceModule, const ModulePtr& module,
|
||||||
const std::vector<AstNode*>& nodes, Position position, StringCompletionCallback callback)
|
const std::vector<AstNode*>& nodes, Position position, StringCompletionCallback callback)
|
||||||
{
|
{
|
||||||
@ -1294,10 +1311,13 @@ static std::optional<AutocompleteEntryMap> autocompleteStringParams(const Source
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto performCallback = [&](const FunctionType* funcType) -> std::optional<AutocompleteEntryMap> {
|
std::optional<std::string> candidateString = getStringContents(nodes.back());
|
||||||
|
|
||||||
|
auto performCallback = [&](const FunctionType* funcType) -> std::optional<AutocompleteEntryMap>
|
||||||
|
{
|
||||||
for (const std::string& tag : funcType->tags)
|
for (const std::string& tag : funcType->tags)
|
||||||
{
|
{
|
||||||
if (std::optional<AutocompleteEntryMap> ret = callback(tag, getMethodContainingClass(module, candidate->func)))
|
if (std::optional<AutocompleteEntryMap> ret = callback(tag, getMethodContainingClass(module, candidate->func), candidateString))
|
||||||
{
|
{
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -263,6 +263,7 @@ void TypeCloner::operator()(const TableType& t)
|
|||||||
arg = clone(arg, dest, cloneState);
|
arg = clone(arg, dest, cloneState);
|
||||||
|
|
||||||
ttv->definitionModuleName = t.definitionModuleName;
|
ttv->definitionModuleName = t.definitionModuleName;
|
||||||
|
ttv->definitionLocation = t.definitionLocation;
|
||||||
ttv->tags = t.tags;
|
ttv->tags = t.tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,6 +447,7 @@ TypeId shallowClone(TypeId ty, TypeArena& dest, const TxnLog* log, bool alwaysCl
|
|||||||
LUAU_ASSERT(!ttv->boundTo);
|
LUAU_ASSERT(!ttv->boundTo);
|
||||||
TableType clone = TableType{ttv->props, ttv->indexer, ttv->level, ttv->scope, ttv->state};
|
TableType clone = TableType{ttv->props, ttv->indexer, ttv->level, ttv->scope, ttv->state};
|
||||||
clone.definitionModuleName = ttv->definitionModuleName;
|
clone.definitionModuleName = ttv->definitionModuleName;
|
||||||
|
clone.definitionLocation = ttv->definitionLocation;
|
||||||
clone.name = ttv->name;
|
clone.name = ttv->name;
|
||||||
clone.syntheticName = ttv->syntheticName;
|
clone.syntheticName = ttv->syntheticName;
|
||||||
clone.instantiatedTypeParams = ttv->instantiatedTypeParams;
|
clone.instantiatedTypeParams = ttv->instantiatedTypeParams;
|
||||||
|
@ -116,6 +116,7 @@ TypeId ReplaceGenerics::clean(TypeId ty)
|
|||||||
{
|
{
|
||||||
TableType clone = TableType{ttv->props, ttv->indexer, level, scope, TableState::Free};
|
TableType clone = TableType{ttv->props, ttv->indexer, level, scope, TableState::Free};
|
||||||
clone.definitionModuleName = ttv->definitionModuleName;
|
clone.definitionModuleName = ttv->definitionModuleName;
|
||||||
|
clone.definitionLocation = ttv->definitionLocation;
|
||||||
return addType(std::move(clone));
|
return addType(std::move(clone));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1535,6 +1535,7 @@ void TypeChecker::check(const ScopePtr& scope, const AstStatTypeAlias& typealias
|
|||||||
// This is a shallow clone, original recursive links to self are not updated
|
// This is a shallow clone, original recursive links to self are not updated
|
||||||
TableType clone = TableType{ttv->props, ttv->indexer, ttv->level, ttv->state};
|
TableType clone = TableType{ttv->props, ttv->indexer, ttv->level, ttv->state};
|
||||||
clone.definitionModuleName = ttv->definitionModuleName;
|
clone.definitionModuleName = ttv->definitionModuleName;
|
||||||
|
clone.definitionLocation = ttv->definitionLocation;
|
||||||
clone.name = name;
|
clone.name = name;
|
||||||
|
|
||||||
for (auto param : binding->typeParams)
|
for (auto param : binding->typeParams)
|
||||||
@ -2370,6 +2371,7 @@ TypeId TypeChecker::checkExprTable(
|
|||||||
TableState state = TableState::Unsealed;
|
TableState state = TableState::Unsealed;
|
||||||
TableType table = TableType{std::move(props), indexer, scope->level, state};
|
TableType table = TableType{std::move(props), indexer, scope->level, state};
|
||||||
table.definitionModuleName = currentModuleName;
|
table.definitionModuleName = currentModuleName;
|
||||||
|
table.definitionLocation = expr.location;
|
||||||
return addType(table);
|
return addType(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5371,6 +5373,7 @@ TypeId TypeChecker::resolveTypeWorker(const ScopePtr& scope, const AstType& anno
|
|||||||
|
|
||||||
TableType ttv{props, tableIndexer, scope->level, TableState::Sealed};
|
TableType ttv{props, tableIndexer, scope->level, TableState::Sealed};
|
||||||
ttv.definitionModuleName = currentModuleName;
|
ttv.definitionModuleName = currentModuleName;
|
||||||
|
ttv.definitionLocation = annotation.location;
|
||||||
return addType(std::move(ttv));
|
return addType(std::move(ttv));
|
||||||
}
|
}
|
||||||
else if (const auto& func = annotation.as<AstTypeFunction>())
|
else if (const auto& func = annotation.as<AstTypeFunction>())
|
||||||
@ -5572,6 +5575,7 @@ TypeId TypeChecker::instantiateTypeFun(const ScopePtr& scope, const TypeFun& tf,
|
|||||||
ttv->instantiatedTypeParams = typeParams;
|
ttv->instantiatedTypeParams = typeParams;
|
||||||
ttv->instantiatedTypePackParams = typePackParams;
|
ttv->instantiatedTypePackParams = typePackParams;
|
||||||
ttv->definitionModuleName = currentModuleName;
|
ttv->definitionModuleName = currentModuleName;
|
||||||
|
ttv->definitionLocation = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
return instantiated;
|
return instantiated;
|
||||||
|
@ -18,7 +18,7 @@ LUAU_FASTFLAG(LuauSetMetatableDoesNotTimeTravel)
|
|||||||
|
|
||||||
using namespace Luau;
|
using namespace Luau;
|
||||||
|
|
||||||
static std::optional<AutocompleteEntryMap> nullCallback(std::string tag, std::optional<const ClassType*> ptr)
|
static std::optional<AutocompleteEntryMap> nullCallback(std::string tag, std::optional<const ClassType*> ptr, std::optional<std::string> contents)
|
||||||
{
|
{
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
@ -36,9 +36,9 @@ struct ACFixtureImpl : BaseType
|
|||||||
return Luau::autocomplete(this->frontend, "MainModule", Position{row, column}, nullCallback);
|
return Luau::autocomplete(this->frontend, "MainModule", Position{row, column}, nullCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
AutocompleteResult autocomplete(char marker)
|
AutocompleteResult autocomplete(char marker, StringCompletionCallback callback = nullCallback)
|
||||||
{
|
{
|
||||||
return Luau::autocomplete(this->frontend, "MainModule", getPosition(marker), nullCallback);
|
return Luau::autocomplete(this->frontend, "MainModule", getPosition(marker), callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckResult check(const std::string& source)
|
CheckResult check(const std::string& source)
|
||||||
@ -3363,4 +3363,31 @@ TEST_CASE_FIXTURE(ACFixture, "type_reduction_is_hooked_up_to_autocomplete")
|
|||||||
// CHECK("{| x: nil |}" == toString(*ty2, opts));
|
// CHECK("{| x: nil |}" == toString(*ty2, opts));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE_FIXTURE(ACFixture, "string_contents_is_available_to_callback")
|
||||||
|
{
|
||||||
|
loadDefinition(R"(
|
||||||
|
declare function require(path: string): any
|
||||||
|
)");
|
||||||
|
|
||||||
|
std::optional<Binding> require = frontend.typeCheckerForAutocomplete.globalScope->linearSearchForBinding("require");
|
||||||
|
REQUIRE(require);
|
||||||
|
Luau::unfreeze(frontend.typeCheckerForAutocomplete.globalTypes);
|
||||||
|
attachTag(require->typeId, "RequireCall");
|
||||||
|
Luau::freeze(frontend.typeCheckerForAutocomplete.globalTypes);
|
||||||
|
|
||||||
|
check(R"(
|
||||||
|
local x = require("testing/@1")
|
||||||
|
)");
|
||||||
|
|
||||||
|
bool isCorrect = false;
|
||||||
|
auto ac1 = autocomplete('1',
|
||||||
|
[&isCorrect](std::string, std::optional<const ClassType*>, std::optional<std::string> contents) -> std::optional<AutocompleteEntryMap>
|
||||||
|
{
|
||||||
|
isCorrect = contents.has_value() && contents.value() == "testing/";
|
||||||
|
return std::nullopt;
|
||||||
|
});
|
||||||
|
|
||||||
|
CHECK(isCorrect);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_SUITE_END();
|
TEST_SUITE_END();
|
||||||
|
Loading…
Reference in New Issue
Block a user