mirror of
https://github.com/zeek/zeek.git
synced 2025-10-11 19:18:19 +00:00
captures for "when" statements
update Triggers to IntrusivePtr's and simpler AST traversal introduce IDSet type, migrate associated "ID*" types to "const ID*"
This commit is contained in:
parent
fa142438fe
commit
f895008c34
24 changed files with 648 additions and 202 deletions
31
src/Expr.cc
31
src/Expr.cc
|
@ -4588,7 +4588,8 @@ void CallExpr::ExprDescribe(ODesc* d) const
|
|||
args->Describe(d);
|
||||
}
|
||||
|
||||
LambdaExpr::LambdaExpr(std::unique_ptr<function_ingredients> arg_ing, IDPList arg_outer_ids)
|
||||
LambdaExpr::LambdaExpr(std::unique_ptr<function_ingredients> arg_ing, IDPList arg_outer_ids,
|
||||
StmtPtr when_parent)
|
||||
: Expr(EXPR_LAMBDA)
|
||||
{
|
||||
ingredients = std::move(arg_ing);
|
||||
|
@ -4596,7 +4597,7 @@ LambdaExpr::LambdaExpr(std::unique_ptr<function_ingredients> arg_ing, IDPList ar
|
|||
|
||||
SetType(ingredients->id->GetType());
|
||||
|
||||
CheckCaptures();
|
||||
CheckCaptures(when_parent);
|
||||
|
||||
// Install a dummy version of the function globally for use only
|
||||
// when broker provides a closure.
|
||||
|
@ -4641,7 +4642,7 @@ LambdaExpr::LambdaExpr(std::unique_ptr<function_ingredients> arg_ing, IDPList ar
|
|||
id->SetConst();
|
||||
}
|
||||
|
||||
void LambdaExpr::CheckCaptures()
|
||||
void LambdaExpr::CheckCaptures(StmtPtr when_parent)
|
||||
{
|
||||
auto ft = type->AsFuncType();
|
||||
const auto& captures = ft->GetCaptures();
|
||||
|
@ -4665,6 +4666,8 @@ void LambdaExpr::CheckCaptures()
|
|||
std::set<const ID*> outer_is_matched;
|
||||
std::set<const ID*> capture_is_matched;
|
||||
|
||||
auto desc = when_parent ? "\"when\" statement" : "lambda";
|
||||
|
||||
for ( const auto& c : *captures )
|
||||
{
|
||||
auto cid = c.id.get();
|
||||
|
@ -4677,7 +4680,11 @@ void LambdaExpr::CheckCaptures()
|
|||
|
||||
if ( capture_is_matched.count(cid) > 0 )
|
||||
{
|
||||
ExprError(util::fmt("%s listed multiple times in capture", cid->Name()));
|
||||
auto msg = util::fmt("%s listed multiple times in capture", cid->Name());
|
||||
if ( when_parent )
|
||||
when_parent->Error(msg);
|
||||
else
|
||||
ExprError(msg);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -4692,13 +4699,25 @@ void LambdaExpr::CheckCaptures()
|
|||
|
||||
for ( auto id : outer_ids )
|
||||
if ( outer_is_matched.count(id) == 0 )
|
||||
ExprError(util::fmt("%s is used inside lambda but not captured", id->Name()));
|
||||
{
|
||||
auto msg = util::fmt("%s is used inside %s but not captured", id->Name(), desc);
|
||||
if ( when_parent )
|
||||
when_parent->Error(msg);
|
||||
else
|
||||
ExprError(msg);
|
||||
}
|
||||
|
||||
for ( const auto& c : *captures )
|
||||
{
|
||||
auto cid = c.id.get();
|
||||
if ( cid && capture_is_matched.count(cid) == 0 )
|
||||
ExprError(util::fmt("%s is captured but not used inside lambda", cid->Name()));
|
||||
{
|
||||
auto msg = util::fmt("%s is captured but not used inside %s", cid->Name(), desc);
|
||||
if ( when_parent )
|
||||
when_parent->Error(msg);
|
||||
else
|
||||
ExprError(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue