fix: remove default constructors and require explicit construct new() for all user classes
The compiler no longer auto-generates a default `new()` constructor for classes. All classes must now explicitly define `construct new() {}` to be instantiable. This change removes the `createDefaultConstructor` function from the compiler, eliminates the `return_this` primitive used by Object's default initializer, and adds explicit constructors to all test and example classes. Core metaclasses (Bool, Class, Null, Num, Object, Range, Sequence) now correctly reject `new()` calls with runtime errors.
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
class foo {
|
||||
construct new() {}
|
||||
|
||||
static callFoo {
|
||||
IO.print(foo)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
static sayName {
|
||||
IO.print(Foo)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
var F = null
|
||||
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
method(param) {
|
||||
F = Fn.new {
|
||||
IO.print(param)
|
||||
|
||||
@@ -4,6 +4,8 @@ var foo = null
|
||||
{
|
||||
var local = "local"
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
method {
|
||||
IO.print(local)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
{
|
||||
var local = "local"
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
method {
|
||||
IO.print(local)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
static bar { true }
|
||||
static baz { 1 }
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
class Foo {
|
||||
toString { "Foo" }
|
||||
}
|
||||
|
||||
// Classes get an argument-less "new()" by default.
|
||||
var foo = Foo.new()
|
||||
IO.print(foo is Foo) // expect: true
|
||||
IO.print(foo.toString) // expect: Foo
|
||||
@@ -1,9 +0,0 @@
|
||||
class Foo {
|
||||
construct new() {
|
||||
IO.print("Foo.new()")
|
||||
}
|
||||
}
|
||||
|
||||
class Bar is Foo {}
|
||||
|
||||
Bar.new() // expect: Foo.new()
|
||||
@@ -1,6 +1,4 @@
|
||||
class Foo {
|
||||
construct real() {}
|
||||
}
|
||||
class Foo {}
|
||||
|
||||
// Classes do not get an argument-less "new()" if they define a constructor.
|
||||
// Classes do not get a constructor by default.
|
||||
var foo = Foo.new() // expect runtime error: Foo metaclass does not implement 'new()'.
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
// Tests that Object implements new(). The only way to call that is through a
|
||||
// super() call in a subclass, so this does that.
|
||||
|
||||
class Foo {
|
||||
construct new() {
|
||||
super() // Should not cause a no method error.
|
||||
IO.print("ok")
|
||||
}
|
||||
}
|
||||
|
||||
Foo.new() // expect: ok
|
||||
@@ -1,4 +1,5 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
write { IO.print(_field) }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
set(a, b, c, d, e) {
|
||||
_a = a
|
||||
_b = b
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
class Outer {
|
||||
construct new() {}
|
||||
|
||||
method {
|
||||
_field = "outer"
|
||||
IO.print(_field) // expect: outer
|
||||
|
||||
class Inner {
|
||||
construct new() {}
|
||||
|
||||
method {
|
||||
_field = "inner"
|
||||
IO.print(_field) // expect: inner
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
write { IO.print(_field) } // Compile a use of the field...
|
||||
init { _field = "value" } // ...before an assignment to it.
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
getter {
|
||||
IO.print("getter")
|
||||
}
|
||||
@@ -13,6 +15,8 @@ class Foo {
|
||||
}
|
||||
|
||||
class Bar is Foo {
|
||||
construct new() {}
|
||||
|
||||
test {
|
||||
getter // expect: getter
|
||||
setter = "value" // expect: setter
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
getter {
|
||||
IO.print("getter")
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
bar { "getter" }
|
||||
|
||||
test {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
bar=(value) {
|
||||
IO.print("setter")
|
||||
return value
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Outer {
|
||||
construct new() {}
|
||||
|
||||
getter {
|
||||
IO.print("outer getter")
|
||||
}
|
||||
@@ -17,6 +19,8 @@ class Outer {
|
||||
method("arg") // expect: outer method
|
||||
|
||||
class Inner {
|
||||
construct new() {}
|
||||
|
||||
getter {
|
||||
IO.print("inner getter")
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
foo(a, b) {
|
||||
_field1 = a
|
||||
_field2 = b
|
||||
@@ -11,6 +13,8 @@ class Foo {
|
||||
}
|
||||
|
||||
class Bar is Foo {
|
||||
construct new() {}
|
||||
|
||||
bar(a, b) {
|
||||
_field1 = a
|
||||
_field2 = b
|
||||
|
||||
@@ -6,6 +6,7 @@ class Foo {
|
||||
}
|
||||
|
||||
class Bar is Foo {
|
||||
construct new() {}
|
||||
methodOnBar { IO.print("bar") }
|
||||
method(a, b) { IO.print("bar") }
|
||||
method(a, b, c, d) { IO.print("bar") }
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
class A {}
|
||||
class B is A {}
|
||||
class C is B {}
|
||||
class A {
|
||||
construct new() {}
|
||||
}
|
||||
class B is A {
|
||||
construct new() {}
|
||||
}
|
||||
class C is B {
|
||||
construct new() {}
|
||||
}
|
||||
var a = A.new()
|
||||
var b = B.new()
|
||||
var c = C.new()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
method { "getter" }
|
||||
method() { "no args" }
|
||||
method(a) { a }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
bar {}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
thisHasAMethodNameThatIsExactly64CharactersLongWhichIsTheMaximum {
|
||||
return "result"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
method000 { 1 }
|
||||
method001 { 1 }
|
||||
method002 { 1 }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
method(a, b) { "method " + a + " " + b }
|
||||
[a, b] { "subscript " + a + " " + b }
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
class Foo {}
|
||||
class Foo {
|
||||
construct new() {}
|
||||
}
|
||||
|
||||
Foo.new().someUnknownMethod // expect runtime error: Foo does not implement 'someUnknownMethod'.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
class Foo {}
|
||||
class Foo {
|
||||
construct new() {}
|
||||
}
|
||||
|
||||
Foo.new().someUnknownMethod(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) // expect runtime error: Foo does not implement 'someUnknownMethod(_,_,_,_,_,_,_,_,_,_,_)'.
|
||||
@@ -1,3 +1,5 @@
|
||||
class Foo {}
|
||||
class Foo {
|
||||
construct new() {}
|
||||
}
|
||||
|
||||
Foo.new().someUnknownMethod(1, 2) // expect runtime error: Foo does not implement 'someUnknownMethod(_,_)'.
|
||||
@@ -1,3 +1,5 @@
|
||||
class Foo {}
|
||||
class Foo {
|
||||
construct new() {}
|
||||
}
|
||||
|
||||
Foo.new().someUnknownMethod(1) // expect runtime error: Foo does not implement 'someUnknownMethod(_)'.
|
||||
@@ -1,4 +1,6 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
+(other) { "infix + " + other }
|
||||
-(other) { "infix - " + other }
|
||||
*(other) { "infix * " + other }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
bar { "on instance" }
|
||||
static bar { "on metaclass" }
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
[a] { "1-subscript " + a }
|
||||
[a, b] { "2-subscript " + a + " " + b }
|
||||
[a, b, c] { "3-subscript " + a + " " + b + " " + c }
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
static bar { Bar.new() }
|
||||
}
|
||||
|
||||
class Bar {
|
||||
construct new() {}
|
||||
static foo { Foo.new() }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
var Global = "global"
|
||||
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
method {
|
||||
IO.print(Global)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
method {
|
||||
IO.print(Global)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
method {
|
||||
return "ok"
|
||||
IO.print("bad")
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
bar=(value) {
|
||||
IO.print(value)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
bar=(value) { "result" }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
bar=(value) { IO.print("set") }
|
||||
bar { IO.print("get") }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
set(a, b, c, d, e) {
|
||||
__a = a
|
||||
__b = b
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
class Outer {
|
||||
construct new() {}
|
||||
|
||||
static staticMethod {
|
||||
__field = "outer"
|
||||
IO.print(__field) // expect: outer
|
||||
|
||||
class Inner {
|
||||
construct new() {}
|
||||
|
||||
static staticMethod {
|
||||
__field = "inner"
|
||||
IO.print(__field) // expect: inner
|
||||
@@ -19,6 +23,8 @@ class Outer {
|
||||
IO.print(__field) // expect: outer
|
||||
|
||||
class Inner {
|
||||
construct new() {}
|
||||
|
||||
instanceMethod {
|
||||
__field = "inner"
|
||||
IO.print(__field) // expect: inner
|
||||
|
||||
@@ -5,6 +5,8 @@ class Base {
|
||||
}
|
||||
|
||||
class Derived is Base {
|
||||
construct new() {}
|
||||
|
||||
foo(a) {
|
||||
IO.print("Derived.bar(a)")
|
||||
super
|
||||
|
||||
@@ -5,6 +5,8 @@ class Base {
|
||||
}
|
||||
|
||||
class Derived is Base {
|
||||
construct new() {}
|
||||
|
||||
bar {
|
||||
IO.print("Derived.bar")
|
||||
super.foo
|
||||
|
||||
@@ -5,6 +5,8 @@ class Base {
|
||||
}
|
||||
|
||||
class Derived is Base {
|
||||
construct new() {}
|
||||
|
||||
foo {
|
||||
IO.print("Derived.foo")
|
||||
super.foo
|
||||
|
||||
@@ -3,6 +3,7 @@ class Base {
|
||||
}
|
||||
|
||||
class Derived is Base {
|
||||
construct new() {}
|
||||
getClosure { Fn.new { super.toString } }
|
||||
toString { "Derived" }
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ class Base {
|
||||
}
|
||||
|
||||
class Derived is Base {
|
||||
construct new() {}
|
||||
|
||||
foo {
|
||||
IO.print("Derived.foo")
|
||||
super
|
||||
|
||||
@@ -7,6 +7,8 @@ class A {
|
||||
class B is A {}
|
||||
|
||||
class C is B {
|
||||
construct new() {}
|
||||
|
||||
foo {
|
||||
IO.print("C.foo")
|
||||
super.foo
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
class Base {}
|
||||
|
||||
class Derived is Base {
|
||||
construct new() {}
|
||||
foo { super.doesNotExist(1) } // expect runtime error: Base does not implement 'doesNotExist(_)'.
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ class A {
|
||||
toString { "A.toString" }
|
||||
}
|
||||
|
||||
class B is A {}
|
||||
class B is A {
|
||||
construct new() {}
|
||||
}
|
||||
|
||||
IO.print(B.new().callSuperToString) // expect: instance of B
|
||||
|
||||
@@ -4,6 +4,8 @@ class A {
|
||||
toString { "A.toString" }
|
||||
}
|
||||
|
||||
class B is A {}
|
||||
class B is A {
|
||||
construct new() {}
|
||||
}
|
||||
|
||||
IO.print(B.new().callSuperToString) // expect: instance of B
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
getClosure { Fn.new { toString } }
|
||||
toString { "Foo" }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Outer {
|
||||
construct new() {}
|
||||
|
||||
method {
|
||||
IO.print(this) // expect: Outer
|
||||
|
||||
@@ -6,6 +8,8 @@ class Outer {
|
||||
IO.print(this) // expect: Outer
|
||||
|
||||
class Inner {
|
||||
construct new() {}
|
||||
|
||||
method {
|
||||
IO.print(this) // expect: Inner
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
getClosure { Fn.new { Fn.new { Fn.new { toString } } } }
|
||||
toString { "Foo" }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
bar { this }
|
||||
baz { "baz" }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
bar {
|
||||
var a = "a"
|
||||
IO.print(a) // expect: a
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
var foo = "variable"
|
||||
|
||||
class Foo {
|
||||
construct new() {}
|
||||
|
||||
foo { "method" }
|
||||
|
||||
method {
|
||||
|
||||
Reference in New Issue
Block a user