Skip to content
← Back

src/syntax/process/await_scanner.ghul

1
namespace Syntax.Process is
2
3
// Scans a function body for `await` expressions, stopping at
4
// nested function/lambda boundaries (their awaits belong to
5
// their own state machines). Used by declare-symbols to
6
// classify functions; `found_value_return` distinguishes
7
// void-async (`Tasks.TASK`) from value-async (`Tasks.TASK[T]`).
8
class AWAIT_SCANNER: Visitor is
9
_found: bool;
10
_found_value_return: bool;
11
12
init() is
13
super.init();
14
si
15
16
body_has_await(body: Trees.Bodies.Body) -> bool is
17
scan(body);
18
return _found;
19
si
20
21
scan(body: Trees.Bodies.Body?) is
22
_found = false;
23
_found_value_return = false;
24
25
if body? then
26
body.walk(self);
27
fi
28
si
29
30
found: bool => _found;
31
found_value_return: bool => _found_value_return;
32
33
pre(await_expr: Trees.Expressions.AWAIT) -> bool is
34
_found = true;
35
36
return true;
37
si
38
39
pre(r: Trees.Statements.RETURN) -> bool is
40
if r.expression? then
41
_found_value_return = true;
42
fi
43
44
return false;
45
si
46
47
pre(function: Trees.Definitions.FUNCTION) -> bool => true;
48
pre(function: Trees.Expressions.FUNCTION) -> bool => true;
49
si
50
51
// `await` inside a `catch` or `finally` HANDLER needs an AST-
52
// level rewrite (pend the exception, perform the await OUTSIDE
53
// the handler, restore the exception). Roslyn does exactly that
54
// when lowering async; ghūl doesn't yet, so emit a diagnostic
55
// pointing at the workaround.
56
//
57
// NOTE: `await` inside a `try` BODY is fine — state-machine
58
// codegen handles it via per-region cold-resume dispatch + the
59
// V_state local + state-guarded finally. Only the catch/finally
60
// HANDLER bodies remain unsupported.
61
class AWAIT_IN_PROTECTED_SCANNER: HANDLER_DEPTH_SCANNER is
62
init(logger: Logging.Logger) is
63
super.init(logger);
64
si
65
66
pre(await_expr: Trees.Expressions.AWAIT) -> bool is
67
if handler_depth > 0 then
68
logger.error(await_expr.location, "await inside a catch or finally handler is not yet supported");
69
fi
70
return true;
71
si
72
si
73
si