Skip to content
← Back

src/syntax/trees/expressions/memberwise_equals.ghul

1
namespace Syntax.Trees.Expressions is
2
3
use Source
4
5
// The whole body of a synthesized `=~`. The parser never produces
6
// one: ADD_ACCESSORS_FOR_PROPERTIES puts a single node where the
7
// body goes, and compile-expressions emits the comparison from it
8
// once the owner, its ancestors and its members have resolved.
9
//
10
// One node rather than a tree of tests and calls. Everything the
11
// comparison needs to decide - which guard the owner takes, how
12
// each member compares, whether a base contributes members of its
13
// own - is settled by types and ancestors that do not exist where
14
// the body is written, and a tree built ahead of them has to be
15
// patched afterwards by a pass that does know. It is also read by
16
// every diagnostic that reads user code, so it draws reports at
17
// source locations for expressions nobody wrote.
18
//
19
// `members` names what to compare, in declaration order, under the
20
// names a value of the owner is read by - an auto-property through
21
// its backing field, a `field` member by its own name. The rules
22
// that decide which members those are read the declarations, so
23
// they are answered where the declarations are.
24
class MEMBERWISE_EQUALS(
25
location: LOCATION,
26
members: Collections.LIST[string],
27
// Where each member was declared, so that a report about how
28
// it compares lands on the declaration rather than on a body
29
// nobody wrote.
30
member_locations: Collections.LIST[LOCATION]
31
): Expression is
32
// Whether a member reaching neither an operator nor an
33
// element-wise comparison is worth reporting. A union's
34
// structural equality is what choosing a union asks for, so a
35
// member that degrades it is; a struct's or a class's operator
36
// is given rather than asked for, and reporting there would
37
// fire on every type in a program, including the ones nothing
38
// ever compares.
39
reports_fallback: bool public
40
41
// Every function the lowering decided to call - each member's
42
// own comparison, and the base's operator where one is
43
// reached. The effects walk reads them: a synthesized body
44
// stores nothing itself, so what it can do is exactly what
45
// these do, and the solver is told rather than left to guess.
46
called_functions: Collections.LIST[Semantic.Symbols.Function] => memberwise_state.functions()
47
48
memberwise_state: Syntax.Process.MEMBERWISE_STATE field
49
50
super(location)
51
52
clear() is
53
super.clear()
54
memberwise_state.clear()
55
si
56
57
clear_outputs() is
58
super.clear_outputs()
59
memberwise_state.clear()
60
si
61
62
accept(visitor: Visitor) is
63
visitor.visit(self)
64
si
65
si
66
si