Skip to content
← Back

src/syntax/trees/definitions/function.ghul

1
namespace Syntax.Trees.Definitions is
2
use IO.Std
3
4
use Source
5
6
class FUNCTION(
7
location: LOCATION,
8
name: Identifiers.Identifier?,
9
generic_arguments: TypeExpressions.LIST,
10
arguments: Variables.LIST public,
11
type_expression: TypeExpressions.TypeExpression,
12
modifiers: Modifiers.LIST,
13
body: Bodies.Body? public
14
): MODIFIABLE, ScopeCarrier is
15
scope: Semantic.Scope? public
16
17
// True when the body contains an `await` expression (not in
18
// a nested lambda). Set by declare-symbols. Drives async
19
// classification + downstream IL emission decisions.
20
contains_let_await: bool public
21
22
// True when `contains_let_await` is set AND the body has no
23
// value-returning `return X;` statements — meaning the
24
// function returns the non-generic `Tasks.TASK` (rather than
25
// `Tasks.TASK[T]` for some T).
26
is_void_async: bool public
27
28
// Set on the `init` FUNCTION synthesised by
29
// rewrite-primary-constructors from a class's primary-constructor
30
// header. Lets declare-symbols record the primary constructor on
31
// the owning type (a class can have secondary constructors too, so
32
// the primary is not simply the only `init`).
33
is_primary_constructor: bool public
34
35
// Set on a FUNCTION the compiler wrote that stands for no
36
// member the user did, and that keeps a real source location so
37
// its diagnostics anchor somewhere meaningful — a union's
38
// structural `=~` and `get_hash_code`, for instance, which are
39
// built at the union's own declaration. Distinct from a
40
// synthesised accessor, which does stand for a written member.
41
is_synthesized: bool public
42
43
mark_synthesized() is
44
is_synthesized = true
45
si
46
47
// Set on the FUNCTION synthesise-top-level-entry builds from a
48
// file's top-level statements. Declare-members copies it onto the
49
// function's symbol, which distinguishes the synthesised entry
50
// from every other function during name resolution.
51
is_top_level_entry: bool public
52
53
// Set on the private CLR-facing `_entry` wrapper that
54
// synthesise-entry-environment-wrapper builds beside a hand-written
55
// entry function declaring a `Ghul.Environment` parameter. Read by
56
// select-entry-point, which treats it as a named-entry candidate
57
// even though its own name never matches `--entry`.
58
is_synthesized_main_wrapper: bool public
59
60
// Set on the hand-written entry function a synthesised `_entry`
61
// wrapper stands in for. Read by select-entry-point, which excludes
62
// it from candidacy entirely: its own signature is never
63
// Main-compatible, and the wrapper is what represents it.
64
wrapped_by_synthesized_main: bool public
65
66
// Set on a synthesised `_entry` wrapper whose wrapped function is a
67
// top-level entry. Read by select-entry-point, which ranks it with
68
// the top-level candidates rather than the named ones, so several
69
// files each carrying top-level statements stay the tolerated tie
70
// they are without a wrapper.
71
wraps_top_level_entry: bool public
72
73
for_property: PROPERTY? public
74
75
// Set on the accessor FUNCTIONs synthesised by add-accessors-for-
76
// properties when the owning property is underscore-prefixed. The
77
// accessor's own IL name ($get_/$set_) does not start with an
78
// underscore, so this carries the property's underscore scope
79
// through to declare-symbols, where it drives the access policy.
80
is_underscore_scoped: bool public
81
82
// Set on FUNCTIONs synthesised by add-accessors-for-
83
// properties from a `[index]: T` indexer. The CLR-required
84
// accessor names aren't user-chosen, so
85
// diagnostics that target user naming (e.g. the snake_case
86
// member-name warning) gate on `!for_indexer?`.
87
for_indexer: INDEXER? public
88
89
// For a synthesised accessor (for_property or for_indexer
90
// set): true for the assign accessor, false for the read
91
// accessor. Carries which half this is structurally, so
92
// nothing has to infer it back from the accessor's name.
93
is_assign_accessor: bool public
94
95
super(location, modifiers)
96
97
accept(visitor: Visitor) is
98
visitor.visit(self)
99
si
100
101
walk(visitor: Visitor) is
102
if !visitor.pre(self) then
103
// the children can be left null when the parser hits
104
// catastrophic input and unwinds out of the declaration
105
if name? then
106
name.walk(visitor)
107
fi
108
109
arguments.walk(visitor)
110
111
type_expression.walk(visitor)
112
113
if body? then
114
body.walk(visitor)
115
fi
116
fi
117
118
accept(visitor)
119
si
120
si
121
si