No more default constructors.

Fixes #296.
This commit is contained in:
Bob Nystrom
2015-09-01 08:16:04 -07:00
parent 36f3059e48
commit 2e83f056c1
86 changed files with 248 additions and 133 deletions
+4 -1
View File
@@ -5,6 +5,7 @@ class Api {
// Class with a default constructor.
foreign class Counter {
construct new() {}
foreign increment(amount)
foreign value
}
@@ -53,7 +54,9 @@ var error = Fiber.new {
IO.print(error) // expect: Class 'Subclass' cannot inherit from foreign class 'Point'.
// Class with a finalizer.
foreign class Resource {}
foreign class Resource {
construct new() {}
}
var resources = [
Resource.new(),
+1
View File
@@ -0,0 +1 @@
Bool.new() // expect runtime error: Bool metaclass does not implement 'new()'.
+1
View File
@@ -0,0 +1 @@
Class.new() // expect runtime error: Class does not implement 'new()'.
+1
View File
@@ -15,6 +15,7 @@ IO.print([1, [2, [3], 4], 5].join(",")) // expect: 1,[2, [3], 4],5
// Calls toString on elements.
class Foo {
construct new() {}
toString { "Foo.toString" }
}
+1
View File
@@ -9,6 +9,7 @@ IO.print([1, [2, [3], 4], 5]) // expect: [1, [2, [3], 4], 5]
// Calls toString on elements.
class Foo {
construct new() {}
toString { "Foo.toString" }
}
+1
View File
@@ -9,6 +9,7 @@ IO.print({1: {2: {}}}) // expect: {1: {2: {}}}
// Calls toString on elements.
class Foo {
construct new() {}
toString { "Foo.toString" }
}
+1
View File
@@ -0,0 +1 @@
Null.new() // expect runtime error: Null metaclass does not implement 'new()'.
+1
View File
@@ -0,0 +1 @@
Num.new() // expect runtime error: Num metaclass does not implement 'new()'.
+1
View File
@@ -0,0 +1 @@
Object.new() // expect runtime error: Object metaclass does not implement 'new()'.
+3 -1
View File
@@ -1,2 +1,4 @@
class Foo {}
class Foo {
construct new() {}
}
IO.print(!Foo.new()) // expect: false
+4 -1
View File
@@ -24,7 +24,9 @@ IO.print(Object.same(Bool, Num)) // expect: false
IO.print(Object.same(Bool, Bool)) // expect: true
// Other types compare by identity.
class Foo {}
class Foo {
construct new() {}
}
var foo = Foo.new()
IO.print(Object.same(foo, foo)) // expect: true
@@ -32,6 +34,7 @@ IO.print(Object.same(foo, Foo.new())) // expect: false
// Ignores == operators.
class Bar {
construct new() {}
==(other) { true }
}
+3 -1
View File
@@ -1,2 +1,4 @@
class Foo {}
class Foo {
construct new() {}
}
IO.print(Foo.new().toString == "instance of Foo") // expect: true
+1
View File
@@ -0,0 +1 @@
Range.new() // expect runtime error: Range metaclass does not implement 'new()'.
+2
View File
@@ -1,4 +1,6 @@
class TestSequence is Sequence {
construct new() {}
iterate(iterator) {
if (iterator == null) return 1
if (iterator == 10) return false
+1
View File
@@ -2,6 +2,7 @@ IO.print([].isEmpty) // expect: true
IO.print([1].isEmpty) // expect: false
class InfiniteSequence is Sequence {
construct new() {}
iterate(iterator) { true }
iteratorValue(iterator) { iterator }
}
+2
View File
@@ -15,6 +15,8 @@ class FibIterator {
}
class Fib is Sequence {
construct new() {}
iterate(iterator) {
if (iterator == null) return FibIterator.new()
iterator.iterate
+1
View File
@@ -0,0 +1 @@
Sequence.new() // expect runtime error: Sequence metaclass does not implement 'new()'.
+2
View File
@@ -1,4 +1,6 @@
class TestSequence is Sequence {
construct new() {}
iterate(iterator) {
if (iterator == null) return 1
if (iterator == 3) return false
+2
View File
@@ -15,6 +15,8 @@ class FibIterator {
}
class Fib is Sequence {
construct new() {}
iterate(iterator) {
if (iterator == null) return FibIterator.new()
iterator.iterate
+1
View File
@@ -0,0 +1 @@
String.new() // expect runtime error: String metaclass does not implement 'new()'.
+2
View File
@@ -1,4 +1,6 @@
class Foo {
construct new() {}
toString { "Foo.toString" }
}
+1
View File
@@ -1,4 +1,5 @@
class BadToString {
construct new() {}
toString { 3 }
}
+1
View File
@@ -1,4 +1,5 @@
class BadToString {
construct new() {}
toString { 3 }
}
@@ -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 }
}
-8
View File
@@ -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()
+2 -4
View File
@@ -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()'.
-11
View File
@@ -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
View File
@@ -1,4 +1,5 @@
class Foo {
construct new() {}
write { IO.print(_field) }
}
+2
View File
@@ -1,4 +1,6 @@
class Foo {
construct new() {}
set(a, b, c, d, e) {
_a = a
_b = b
+4
View File
@@ -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
View File
@@ -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") }
+9 -3
View File
@@ -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
View File
@@ -1,4 +1,5 @@
class Foo {
construct new() {}
method { "getter" }
method() { "no args" }
method(a) { a }
+1
View File
@@ -1,4 +1,5 @@
class Foo {
construct new() {}
bar {}
}
+1
View File
@@ -1,4 +1,5 @@
class Foo {
construct new() {}
thisHasAMethodNameThatIsExactly64CharactersLongWhichIsTheMaximum {
return "result"
}
+1
View File
@@ -1,4 +1,5 @@
class Foo {
construct new() {}
method000 { 1 }
method001 { 1 }
method002 { 1 }
+1
View File
@@ -1,4 +1,5 @@
class Foo {
construct new() {}
method(a, b) { "method " + a + " " + b }
[a, b] { "subscript " + a + " " + b }
}
+3 -1
View File
@@ -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(_)'.
+2
View File
@@ -1,4 +1,6 @@
class Foo {
construct new() {}
+(other) { "infix + " + other }
-(other) { "infix - " + other }
*(other) { "infix * " + other }
+1
View File
@@ -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)
}
+2
View File
@@ -1,4 +1,6 @@
class Foo {
construct new() {}
method {
return "ok"
IO.print("bad")
+2
View File
@@ -1,4 +1,6 @@
class Foo {
construct new() {}
bar=(value) {
IO.print(value)
}
+1
View File
@@ -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
+1
View File
@@ -3,6 +3,7 @@ class Base {
}
class Derived is Base {
construct new() {}
getClosure { Fn.new { super.toString } }
toString { "Derived" }
}
+2
View File
@@ -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
View File
@@ -1,4 +1,5 @@
class Foo {
construct new() {}
getClosure { Fn.new { toString } }
toString { "Foo" }
}
+4
View File
@@ -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
View File
@@ -1,4 +1,5 @@
class Foo {
construct new() {}
getClosure { Fn.new { Fn.new { Fn.new { toString } } } }
toString { "Foo" }
}
+1
View File
@@ -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 {