Skip to content

Commit 11f0b02

Browse files
committed
use relative reference to parent class instead of closure
1 parent 24b3a86 commit 11f0b02

File tree

3 files changed

+102
-11
lines changed

3 files changed

+102
-11
lines changed

moonscript/compile.lua

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@ do
638638
__init = function(self, options)
639639
self.options = options
640640
self.root = self
641-
return _parent_0.__init(self)
641+
return self.__class.__parent.__init(self)
642642
end,
643643
__base = _base_0,
644644
__name = "RootBlock",
@@ -647,7 +647,10 @@ do
647647
__index = function(cls, name)
648648
local val = rawget(_base_0, name)
649649
if val == nil then
650-
return _parent_0[name]
650+
local parent = rawget(cls, "__parent")
651+
if parent then
652+
return parent[name]
653+
end
651654
else
652655
return val
653656
end

moonscript/transform.moon

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,25 @@ Statement = Transformer {
612612
class_lookup = build["if"] {
613613
cond: { "exp", {"ref", "val"}, "==", "nil" }
614614
then: {
615-
parent_cls_name\index"name"
615+
build.assign_one LocalName"parent", build.chain {
616+
base: "rawget"
617+
{
618+
"call", {
619+
{"ref", "cls"}
620+
{"string", '"', "__parent"}
621+
}
622+
}
623+
}
624+
625+
build.if {
626+
cond: LocalName "parent"
627+
then: {
628+
build.chain {
629+
base: LocalName "parent"
630+
{"index", "name"}
631+
}
632+
}
633+
}
616634
}
617635
}
618636
insert class_lookup, {"else", {"val"}}
@@ -660,14 +678,21 @@ Statement = Transformer {
660678
@put_name name if name
661679

662680
@set "super", (block, chain) ->
681+
relative_parent = {
682+
"chain",
683+
"self"
684+
{"dot", "__class"}
685+
{"dot", "__parent"}
686+
}
687+
663688
if chain
664689
chain_tail = { unpack chain, 3 }
665-
new_chain = {"chain", parent_cls_name}
666-
667690
head = chain_tail[1]
668691

669692
if head == nil
670-
return parent_cls_name
693+
return relative_parent
694+
695+
new_chain = relative_parent
671696

672697
switch head[1]
673698
-- calling super, inject calling name and self into chain
@@ -702,7 +727,7 @@ Statement = Transformer {
702727

703728
new_chain
704729
else
705-
parent_cls_name
730+
relative_parent
706731

707732
{"declare_glob", "*"}
708733

spec/class_spec.moon

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ describe "class", ->
1919
instance = Thing!
2020
assert.same instance\get_color!, "blue"
2121

22-
23-
it "should have class property", ->
22+
it "should have base properies from class", ->
2423
class Thing
2524
color: "blue"
2625
get_color: => @color
@@ -54,7 +53,6 @@ describe "class", ->
5453
assert.same instance.property, "name"
5554
assert.same instance.name, "the_thing"
5655

57-
5856
it "should call super method", ->
5957
class Base
6058
_count: 111
@@ -66,6 +64,18 @@ describe "class", ->
6664
instance = Thing!
6765
assert.same instance\counter!, "00000111"
6866

67+
it "should call other method from super", ->
68+
class Base
69+
_count: 111
70+
counter: =>
71+
@_count
72+
73+
class Thing extends Base
74+
other_method: => super\counter!
75+
76+
instance = Thing!
77+
assert.same instance\other_method!, 111
78+
6979
it "should get super class", ->
7080
class Base
7181
class Thing extends Base
@@ -102,7 +112,6 @@ describe "class", ->
102112
Thing = class
103113
assert.same Thing.__name, "Thing"
104114

105-
106115
it "should not expose class properties on instance", ->
107116
class Thing
108117
@height: 10
@@ -135,3 +144,57 @@ describe "class", ->
135144
instance = Thing!
136145
instance\go!
137146

147+
it "should have class properies take precedence over base properties", ->
148+
class Thing
149+
@prop: "hello"
150+
prop: "world"
151+
152+
assert.same "hello", Thing.prop
153+
154+
it "class properties take precedence in super class over base", ->
155+
class Thing
156+
@prop: "hello"
157+
prop: "world"
158+
159+
class OtherThing extends Thing
160+
161+
assert.same "hello", OtherThing.prop
162+
163+
it "gets value from base in super class", ->
164+
class Thing
165+
prop: "world"
166+
167+
class OtherThing extends Thing
168+
assert.same "world", OtherThing.prop
169+
170+
it "should let parent be replaced on class", ->
171+
class A
172+
@prop: "yeah"
173+
cool: => 1234
174+
plain: => "a"
175+
176+
class B
177+
@prop: "okay"
178+
cool: => 9999
179+
plain: => "b"
180+
181+
class Thing extends A
182+
cool: =>
183+
super! + 1
184+
185+
get_super: =>
186+
super
187+
188+
instance = Thing!
189+
190+
assert.same "a", instance\plain!
191+
assert.same 1235, instance\cool!
192+
assert A == instance\get_super!, "expected super to be B"
193+
194+
Thing.__parent = B
195+
setmetatable Thing.__base, B.__base
196+
197+
assert.same "b", instance\plain!
198+
assert.same 10000, instance\cool!
199+
assert B == instance\get_super!, "expected super to be B"
200+

0 commit comments

Comments
 (0)