Skip to content

Commit cea7955

Browse files
committed
Added a new test.
1 parent 2f61682 commit cea7955

2 files changed

Lines changed: 301 additions & 0 deletions

File tree

spec/inputs/props.yue

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

spec/outputs/props.lua

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
local Props
2+
do
3+
local _class_0
4+
local assignReadOnly
5+
local _base_0 = {
6+
__index = function(self, name)
7+
local cls = getmetatable(self)
8+
do
9+
local item
10+
do
11+
local _obj_0 = cls.__getter
12+
if _obj_0 ~= nil then
13+
item = _obj_0[name]
14+
end
15+
end
16+
if item then
17+
return item(self)
18+
else
19+
item = rawget(cls, name)
20+
if item then
21+
return item
22+
else
23+
local c = cls
24+
repeat
25+
c = getmetatable(c)
26+
if c then
27+
local _obj_0 = c.__getter
28+
if _obj_0 ~= nil then
29+
item = _obj_0[name]
30+
end
31+
if item then
32+
if cls.__getter == nil then
33+
cls.__getter = { }
34+
end
35+
cls.__getter[name] = item
36+
return item(self)
37+
else
38+
item = rawget(c, name)
39+
if item then
40+
rawset(cls, name, item)
41+
return item
42+
end
43+
end
44+
else
45+
break
46+
end
47+
until false
48+
end
49+
end
50+
end
51+
return nil
52+
end,
53+
__newindex = function(self, name, value)
54+
local cls = getmetatable(self)
55+
local item
56+
local _obj_0 = cls.__setter
57+
if _obj_0 ~= nil then
58+
item = _obj_0[name]
59+
end
60+
if item then
61+
return item(self, value)
62+
else
63+
local c = cls
64+
repeat
65+
c = getmetatable(c)
66+
if c then
67+
local _obj_1 = c.__setter
68+
if _obj_1 ~= nil then
69+
item = _obj_1[name]
70+
end
71+
if item then
72+
if cls.__setter == nil then
73+
cls.__setter = { }
74+
end
75+
cls.__setter[name] = item
76+
item(self, value)
77+
return
78+
end
79+
else
80+
break
81+
end
82+
until false
83+
return rawset(self, name, value)
84+
end
85+
end,
86+
prop = function(self, name, props)
87+
local get, set = props.get, props.set
88+
if set == nil then
89+
set = assignReadOnly
90+
end
91+
do
92+
local getter = rawget(self.__base, "__getter")
93+
if getter then
94+
getter[name] = get
95+
else
96+
rawset(self.__base, "__getter", {
97+
[name] = get
98+
})
99+
end
100+
end
101+
local setter = rawget(self.__base, "__setter")
102+
if setter then
103+
setter[name] = set
104+
else
105+
return rawset(self.__base, "__setter", {
106+
[name] = set
107+
})
108+
end
109+
end
110+
}
111+
if _base_0.__index == nil then
112+
_base_0.__index = _base_0
113+
end
114+
_class_0 = setmetatable({
115+
__init = function() end,
116+
__base = _base_0,
117+
__name = "Props"
118+
}, {
119+
__index = _base_0,
120+
__call = function(cls, ...)
121+
local _self_0 = setmetatable({ }, _base_0)
122+
cls.__init(_self_0, ...)
123+
return _self_0
124+
end
125+
})
126+
_base_0.__class = _class_0
127+
local self = _class_0;
128+
assignReadOnly = function()
129+
return error("assigning a readonly property")
130+
end
131+
Props = _class_0
132+
end
133+
local A
134+
do
135+
local _class_0
136+
local _parent_0 = Props
137+
local _base_0 = { }
138+
for _key_0, _val_0 in pairs(_parent_0.__base) do
139+
if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
140+
_base_0[_key_0] = _val_0
141+
end
142+
end
143+
if _base_0.__index == nil then
144+
_base_0.__index = _base_0
145+
end
146+
setmetatable(_base_0, _parent_0.__base)
147+
_class_0 = setmetatable({
148+
__init = function(self)
149+
self._x = 0
150+
end,
151+
__base = _base_0,
152+
__name = "A",
153+
__parent = _parent_0
154+
}, {
155+
__index = function(cls, name)
156+
local val = rawget(_base_0, name)
157+
if val == nil then
158+
local parent = rawget(cls, "__parent")
159+
if parent then
160+
return parent[name]
161+
end
162+
else
163+
return val
164+
end
165+
end,
166+
__call = function(cls, ...)
167+
local _self_0 = setmetatable({ }, _base_0)
168+
cls.__init(_self_0, ...)
169+
return _self_0
170+
end
171+
})
172+
_base_0.__class = _class_0
173+
local self = _class_0;
174+
self:prop('x', {
175+
get = function(self)
176+
return self._x + 1000
177+
end,
178+
set = function(self, v)
179+
self._x = v
180+
end
181+
})
182+
if _parent_0.__inherited then
183+
_parent_0.__inherited(_parent_0, _class_0)
184+
end
185+
A = _class_0
186+
end
187+
local B
188+
do
189+
local _class_0
190+
local _parent_0 = A
191+
local _base_0 = { }
192+
for _key_0, _val_0 in pairs(_parent_0.__base) do
193+
if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
194+
_base_0[_key_0] = _val_0
195+
end
196+
end
197+
if _base_0.__index == nil then
198+
_base_0.__index = _base_0
199+
end
200+
setmetatable(_base_0, _parent_0.__base)
201+
_class_0 = setmetatable({
202+
__init = function(self, ...)
203+
return _class_0.__parent.__init(self, ...)
204+
end,
205+
__base = _base_0,
206+
__name = "B",
207+
__parent = _parent_0
208+
}, {
209+
__index = function(cls, name)
210+
local val = rawget(_base_0, name)
211+
if val == nil then
212+
local parent = rawget(cls, "__parent")
213+
if parent then
214+
return parent[name]
215+
end
216+
else
217+
return val
218+
end
219+
end,
220+
__call = function(cls, ...)
221+
local _self_0 = setmetatable({ }, _base_0)
222+
cls.__init(_self_0, ...)
223+
return _self_0
224+
end
225+
})
226+
_base_0.__class = _class_0
227+
local self = _class_0;
228+
self:prop('abc', {
229+
get = function(self)
230+
return "hello"
231+
end
232+
})
233+
if _parent_0.__inherited then
234+
_parent_0.__inherited(_parent_0, _class_0)
235+
end
236+
B = _class_0
237+
end
238+
local b = B()
239+
b.x = 999
240+
return print(b.x, b.abc)

0 commit comments

Comments
 (0)