diff options
Diffstat (limited to 'spec/inputs/props.yue')
-rw-r--r-- | spec/inputs/props.yue | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/spec/inputs/props.yue b/spec/inputs/props.yue new file mode 100644 index 0000000..bbb7aae --- /dev/null +++ b/spec/inputs/props.yue | |||
@@ -0,0 +1,61 @@ | |||
1 | class Props | ||
2 | __index: (name): nil => | ||
3 | cls = @.<> | ||
4 | if item := cls.__getter?[name] -- access properties | ||
5 | return item @ | ||
6 | elseif item := rawget cls, name -- access member functions | ||
7 | return item | ||
8 | else | ||
9 | c = cls | ||
10 | while c := c.<> -- recursive to access base classes | ||
11 | if item := c.__getter?[name] | ||
12 | cls.__getter ??= {} | ||
13 | cls.__getter[name] = item -- cache base properties to class | ||
14 | return item @ | ||
15 | elseif item := rawget c, name | ||
16 | rawset cls, name, item -- cache base member to class | ||
17 | return item | ||
18 | |||
19 | __newindex: (name, value) => | ||
20 | cls = @.<> | ||
21 | if item := cls.__setter?[name] -- access properties | ||
22 | item @, value | ||
23 | else | ||
24 | c = cls | ||
25 | while c := c.<> -- recursive to access base classes | ||
26 | if item := c.__setter?[name] | ||
27 | cls.__setter ??= {} | ||
28 | cls.__setter[name] = item -- cache base property to class | ||
29 | item @, value | ||
30 | return | ||
31 | rawset @, name, value -- assign field to self | ||
32 | |||
33 | assignReadOnly = -> error "assigning a readonly property" | ||
34 | |||
35 | prop: (name, props) => | ||
36 | { | ||
37 | :get | ||
38 | :set = assignReadOnly | ||
39 | } = props | ||
40 | if getter := rawget @__base, "__getter" | ||
41 | getter[name] = get | ||
42 | else | ||
43 | rawset @__base, "__getter", [name]: get | ||
44 | if setter := rawget @__base, "__setter" | ||
45 | setter[name] = set | ||
46 | else | ||
47 | rawset @__base, "__setter", [name]: set | ||
48 | |||
49 | class A extends Props | ||
50 | @prop 'x' | ||
51 | get: => @_x + 1000 | ||
52 | set: (v) => @_x = v | ||
53 | new: => | ||
54 | @_x = 0 | ||
55 | |||
56 | class B extends A | ||
57 | @prop 'abc', get: => "hello" | ||
58 | |||
59 | b = B! | ||
60 | b.x = 999 | ||
61 | print b.x, b.abc | ||