Skip to content
This repository has been archived by the owner on Jun 12, 2022. It is now read-only.

Commit

Permalink
Type FindFirstChildWhichIsA(T) etc. as returning T?
Browse files Browse the repository at this point in the history
Done through magic functions
Closes #7
  • Loading branch information
JohnnyMorganz committed Apr 30, 2022
1 parent 0e6d837 commit 183a493
Showing 1 changed file with 24 additions and 2 deletions.
26 changes: 24 additions & 2 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,12 +536,29 @@ std::optional<Luau::ExprResult<Luau::TypePackId>> magicFunctionInstanceIsA(
if (!lvalue || !tfun)
return std::nullopt;

unfreeze(typeChecker.globalTypes);
Luau::TypePackId booleanPack = typeChecker.globalTypes.addTypePack({typeChecker.booleanType});
freeze(typeChecker.globalTypes);
return Luau::ExprResult<Luau::TypePackId>{booleanPack, {Luau::IsAPredicate{std::move(*lvalue), expr.location, tfun->type}}};
}

// Magic function for `Instance:FindFirstChildWhichIsA("ClassName")` and friends
std::optional<Luau::ExprResult<Luau::TypePackId>> magicFunctionFindFirstXWhichIsA(
Luau::TypeChecker& typeChecker, const Luau::ScopePtr& scope, const Luau::AstExprCall& expr, Luau::ExprResult<Luau::TypePackId> exprResult)
{
if (expr.args.size < 1)
return std::nullopt;

auto str = expr.args.data[0]->as<Luau::AstExprConstantString>();
if (!str)
return std::nullopt;

std::optional<Luau::TypeFun> tfun = scope->lookupType(std::string(str->value.data, str->value.size));
if (!tfun)
return std::nullopt;

Luau::TypeId nillableClass = Luau::makeOption(typeChecker, typeChecker.globalTypes, tfun->type);
return Luau::ExprResult<Luau::TypePackId>{typeChecker.globalTypes.addTypePack({nillableClass})};
}

int main(int argc, char** argv)
{
Luau::assertHandler() = assertionHandler;
Expand Down Expand Up @@ -815,12 +832,17 @@ int main(int argc, char** argv)
}

// Register Instance:IsA("ClassName") type predicate
// Register FindFirstChildWhichIsA / FindFirstChildOfClassName / FindFirstAncestorWhichIsA / FindFirstAncestorOfClass magic functions
auto instanceType = frontend.typeChecker.globalScope->lookupType("Instance");
if (instanceType.has_value())
{
if (Luau::ClassTypeVar* ctv = Luau::getMutable<Luau::ClassTypeVar>(instanceType.value().type))
{
Luau::attachMagicFunction(ctv->props["IsA"].type, magicFunctionInstanceIsA);
Luau::attachMagicFunction(ctv->props["FindFirstChildWhichIsA"].type, magicFunctionFindFirstXWhichIsA);
Luau::attachMagicFunction(ctv->props["FindFirstChildOfClass"].type, magicFunctionFindFirstXWhichIsA);
Luau::attachMagicFunction(ctv->props["FindFirstAncestorWhichIsA"].type, magicFunctionFindFirstXWhichIsA);
Luau::attachMagicFunction(ctv->props["FindFirstAncestorOfClass"].type, magicFunctionFindFirstXWhichIsA);
}
}
}
Expand Down

0 comments on commit 183a493

Please sign in to comment.